Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
flask-simple-captcha
Advanced tools
Extremely simple, "Good Enough" captcha implemention for flask forms. No server side session library required.
v5.0.0+ added an encryption mechanism to the stored text in the jwts. Previous versions are insecure!
v5.5.4 removed the upper limit on werkzeug/pillow dependency versions
flask-simple-captcha
is a CAPTCHA generator class for generating and validating CAPTCHAs. It allows for easy integration into Flask applications.
See the encryption / decryption breakdown below for more information on the verification mechanism.
Import this package directly into your Flask project and make sure to install all dependencies.
DEFAULT_CONFIG = {
'SECRET_CAPTCHA_KEY': 'LONGKEY', # use for JWT encoding/decoding
# CAPTCHA GENERATION SETTINGS
'EXPIRE_SECONDS': 60 * 10, # takes precedence over EXPIRE_MINUTES
'CAPTCHA_IMG_FORMAT': 'JPEG', # 'PNG' or 'JPEG' (JPEG is 3X faster)
# CAPTCHA TEXT SETTINGS
'CAPTCHA_LENGTH': 6, # Length of the generated CAPTCHA text
'CAPTCHA_DIGITS': False, # Should digits be added to the character pool?
'EXCLUDE_VISUALLY_SIMILAR': True, # Exclude visually similar characters
'BACKGROUND_COLOR': (0, 0, 0), # RGB(A?) background color (default black)
'TEXT_COLOR': (255, 255, 255), # RGB(A?) text color (default white)
# Optional settings
#'ONLY_UPPERCASE': True, # Only use uppercase characters
#'CHARACTER_POOL': 'AaBb', # Use a custom character pool
}
Add this code snippet at the top of your application:
from flask_simple_captcha import CAPTCHA
YOUR_CONFIG = {
'SECRET_CAPTCHA_KEY': 'LONG_KEY',
'CAPTCHA_LENGTH': 6,
'CAPTCHA_DIGITS': False,
'EXPIRE_SECONDS': 600,
}
SIMPLE_CAPTCHA = CAPTCHA(config=YOUR_CONFIG)
app = SIMPLE_CAPTCHA.init_app(app)
To add CAPTCHA protection to a route, you can use the following code:
@app.route('/example', methods=['GET','POST'])
def example():
if request.method == 'GET':
new_captcha_dict = SIMPLE_CAPTCHA.create()
return render_template('your_template.html', captcha=new_captcha_dict)
if request.method == 'POST':
c_hash = request.form.get('captcha-hash')
c_text = request.form.get('captcha-text')
if SIMPLE_CAPTCHA.verify(c_text, c_hash):
return 'success'
else:
return 'failed captcha'
In your HTML template, you need to wrap the CAPTCHA inputs within a form element. The package will only generate the CAPTCHA inputs but not the surrounding form or the submit button.
<!-- your_template.html -->
<form action="/example" method="post">
{{ captcha_html(captcha)|safe }}
<input type="submit" value="Submit" />
</form>
Here is an example of what the generated CAPTCHA images look like, this is a screen shot from the /images
route of the debug server.
link to image url if the above does not load
Uses a combination of JWTs and Werkzeug's password hashing to encrypt and decrypt CAPTCHA text.
salted_text = secret_key + text
generate_password_hash
function is then used to hash the salted CAPTCHA text.
hashed_text = generate_password_hash(salted_text)
payload = {
'hashed_text': hashed_text,
'exp': datetime.utcnow() + timedelta(seconds=expire_seconds),
}
return jwt.encode(payload, secret_key, algorithm='HS256')
decoded = jwt.decode(token, secret_key, algorithms=['HS256'])
hashed_text = decoded['hashed_text']
check_password_hash
function is used to verify that the hashed CAPTCHA text matches the original salted CAPTCHA text.
salted_original_text = secret_key + original_text
if check_password_hash(hashed_text, salted_original_text):
return original_text
Create a Virtual Environment:
Navigate to the project directory where you've cloned the repository and create a virtual environment named venv
within the project directory:
python -m venv venv/
Activate the Virtual Environment:
source venv/bin/activate
.\venv\Scripts\activate
.\venv\Scripts\Activate.ps1
Install Dependencies:
Install the required dependencies for development:
pip install -r requirements_dev.txt
Install the local flask-simple-captcha package:
pip install .
venv
IN THE PROJECT DIRECTORY AND THAT IT IS ACTIVATED AND BOTH THE DEPENDENCIES AND THE LOCAL FLASK-SIMPLE-CAPTCHA PACKAGE ARE INSTALLED IN THE VENVAs of the time of me writing this README (2023-11-15), pytest reports 97% test coverage of the logic in the flask_simple_captcha
package. Should be kept as close to 100% as possible.
python -m pytest tests.py -s -vv --cov=flask_simple_captcha/ --cov-report term-missing
Simply hit command + shift + p and type "Select And Start Debugging" and select Python: Run tests
. You will want to make sure your venv is installed and activated.
... previous output omitted for brevity ...
tests.py::TestCaptchaUtils::test_jwtencrypt PASSED
tests.py::TestCaptchaUtils::test_no_hashed_text PASSED
---------- coverage: platform darwin, python 3.8.18-final-0 ----------
Name Stmts Miss Cover Missing
--------------------------------------------------------------------------
flask_simple_captcha/__init__.py 3 0 100%
flask_simple_captcha/captcha_generation.py 78 0 100%
flask_simple_captcha/config.py 10 0 100%
flask_simple_captcha/img.py 56 0 100%
flask_simple_captcha/text.py 25 0 100%
flask_simple_captcha/utils.py 51 0 100%
--------------------------------------------------------------------------
TOTAL 223 0 100%
==================================== 41 passed in 5.53s
export FLASK_APP=debug_flask_server
export FLASK_DEBUG=1
set FLASK_APP=debug_flask_server
set FLASK_DEBUG=1
$env:FLASK_APP="debug_flask_server"
$env:FLASK_DEBUG="1"
flask run --no-debugger
Python: Flask
Navigate to localhost:5000
in your browser to view the debug server. You can also navigate to localhost:5000/images
to view 50 CAPTCHA images at once.
For usage and integration examples, including how to use flask-simple-captcha
with WTForms and Flask-Security, check out the Code Examples document.
Feel free to open a PR. The project has undergone a recent overhaul to improve the code quality.
If you make changes in the logic, please follow the steps laid out in this document for testing and debugging. Make sure the coverage % stays >= 100% and that you verify manually at least once that things look okay by submitting a real CAPTCHA in the debug server.
The pyproject.toml
has the required configuration for black
and isort
. There is also a vscode settings file equivalent to the pyproject.toml
file in .vscode/settings.json
.
MIT
Contact: ccarterdev@gmail.com
FAQs
Extremely simple, "Good Enough" captcha implemention for flask forms. No server side session library required.
We found that flask-simple-captcha demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.