A CKAN extension to hold various security improvements for CKAN, including:
- Stronger password reset tokens
- Brute force protection
- Double-submit CSRF protection for requests (Courtesy of the Queensland Government)
- Removed ability to change usernames after signup
- Server-side session storage
- Session invalidation on logout
- Stronger password validators (NZISM compatible)
- When users try to reset a password for an email address, CKAN will no longer disclose whether or not that email address exists in the DB.
Reset tokens are generated using os.urandom(16)
instead of CKAN's default
uuid.uuid4().hex[:10]
.
Users attempting to log in more than ckanext.security.login_max_count
times
within ckanext.security.lock_timeout
seconds from a single IP address will be
temporarily locked out.
By default, this means that after 10 unsuccessful login attempts within 15 minutes the login will be disabled for another 15 minutes.
A notification email will be sent to locked out users.
- The CSRFMiddleware needs to be placed at the bottom of the middleware
stack. This requires to patch
ckan.config.middleware.pylons_app
. The patch is currently available in the data.govt.nz CKAN repository on thedia
branch, or commit74f78865
for cherry-pick. - A running Redis instance to store brute force protection tokens configured with a maxmemory and maxmemory-policy=lru so it overwrites the least recently used item rather than running out of space. This instance should be a different instance from the one used for Harvest items to avoid data loss. Redis LRU-Cache documentation.
You will need at least the following setting ins your who.ini
[plugin:use_beaker]
use = repoze.who.plugins.use_beaker:make_plugin
key_name = ckan_session
delete_on_logout = True
[plugin:friendlyform]
# <your other settings here>
rememberer_name = use_beaker
[identifiers]
plugins =
friendlyform;browser
use_beaker
[authenticators]
plugins =
ckanext.security.authenticator:CKANLoginThrottle
ckanext.security.authenticator:BeakerRedisAuth
For better security, make sure you harden your session configuration (in your ckan config file). See for example the settings below.
[app:main]
# <your other settings here>
beaker.session.key = ckan_session
# Your session secret should be a long, random and secret string!
beaker.session.secret = beaker-secret
beaker.session.data_serializer = json
beaker.session.httponly = true
beaker.session.secure = true
beaker.session.timeout = 3600
beaker.session.save_accessed_time = true
beaker.session.type = redis
beaker.session.url = 127.0.0.1:6739
beaker.session.cookie_expires = true
# Your domain should show here.
beaker.session.cookie_domain = 192.168.232.65
## Security
ckanext.security.domain = 192.168.232.65 # Cookie domain
ckanext.security.redis.host = 127.0.0.1
ckanext.security.redis.port = 6379
ckanext.security.redis.db = 1 # ckan uses db 0
# 15 minute timeout with 10 attempts
ckanext.security.lock_timeout = 900 # Login throttling lock period
ckanext.security.login_max_count = 10 # Login throttling attempt limit
You can use pip
to install this plugin into your virtual environment:
pip install --process-dependency-links -e 'https://github.com/data-govt-nz/ckanext-security.git#egg=ckanext-security==0.1.0'
NOTE: The ``--process-dependency-links` flag has officially been deprecated, but has not been removed from pip, because it is the currently the only setuptools-supported way for specifying private repo dependencies
Finally, add security
to ckan.plugins
in your config file.
- If your service is responding with
Internal Server Error
, try usingpaster request <config> /
. If you see aValueError: No Beaker session (beaker.session) in environment
then you have not installed the patch to CKAN correctly.