CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/flask-security-basics

Security essentials for Flask APIs — CORS, Talisman security headers, rate

99

1.17x
Quality

94%

Does it follow best practices?

Impact

100%

1.17x

Average score across 10 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-7/

Production Deployment: Rate Limiter Acting Strangely

Problem Description

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:

  1. 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.

  2. 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.

Output Specification

Produce the following files:

  • app_fixed.py — the corrected Flask application
  • requirements.txt — dependencies needed to run the app
  • diagnosis.md — a brief explanation of each root cause and the fix applied

Input Files

The 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 app

if name == 'main': app = create_app() app.run()

evals

tile.json