Security essentials for Flask APIs — CORS, Talisman security headers, rate
99
94%
Does it follow best practices?
Impact
100%
1.17xAverage score across 10 eval scenarios
Passed
No known issues
An e-commerce platform's Flask API has been running on a single development server for months. The ops team is now migrating it to production: three Gunicorn worker processes behind an nginx reverse proxy on the same host.
Since the migration, the support team has reported two alarming problems:
Rate limiting has stopped working properly. Users who were previously being throttled for making too many requests can now make far more requests than the configured limits should allow. During load tests the limiter never seems to kick in at the expected thresholds.
After a Gunicorn worker restart, users who had been throttled become unthrottled immediately. Rolling restarts during deployment appear to clear all rate-limit state.
The current application code is shown below. Your job is to diagnose the root causes, fix the deployment configuration, and document what you changed and why.
Produce the following files:
app_fixed.py — the corrected Flask applicationrequirements.txt — dependencies needed to run the appdiagnosis.md — a brief explanation of each root cause and the fix appliedThe following file is provided as input. Extract it before beginning.
=============== FILE: app.py =============== import os from flask import Flask, jsonify, request from flask_limiter import Limiter from flask_limiter.util import get_remote_address
def create_app(): app = Flask(name) app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'dev-only-key')
limiter = Limiter(
key_func=get_remote_address,
default_limits=["200 per hour"],
)
limiter.init_app(app)
@app.route('/api/products', methods=['GET'])
def list_products():
return jsonify({'products': ['widget', 'gadget', 'doohickey']})
@app.route('/api/orders', methods=['POST'])
@limiter.limit("10 per minute")
def create_order():
data = request.get_json(silent=True)
if data is None:
return jsonify({'error': 'Request body must be JSON'}), 400
return jsonify({'order_id': 101}), 201
@app.route('/api/orders/<int:order_id>', methods=['DELETE'])
@limiter.limit("5 per minute")
def cancel_order(order_id):
return jsonify({'cancelled': order_id})
return appif name == 'main': app = create_app() app.run()
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
skills
flask-security-basics
verifiers