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

criteria.jsonevals/scenario-1/

{
  "context": "The agent was asked to add input validation to a Flask POST endpoint that creates book records. The scorer checks bookstore.py to verify correct use of get_json(silent=True), presence/type checks for all four fields, length constraints, and proper 400 error responses.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "get_json(silent=True) used",
      "description": "The handler calls request.get_json(silent=True) (not request.get_json() without silent=True) to safely parse the body.",
      "max_score": 10
    },
    {
      "name": "None body returns 400",
      "description": "If get_json returns None (missing or non-JSON body), the handler returns a 400 response with a JSON error message before attempting to access any fields.",
      "max_score": 10
    },
    {
      "name": "title presence check",
      "description": "title is validated to be a non-empty string after stripping whitespace. Missing or empty title returns 400.",
      "max_score": 8
    },
    {
      "name": "title max length check",
      "description": "title longer than 200 characters is rejected with a 400 error.",
      "max_score": 6
    },
    {
      "name": "title stripped",
      "description": "title is stripped of leading/trailing whitespace before the non-empty check (e.g., using .strip()).",
      "max_score": 6
    },
    {
      "name": "author presence check",
      "description": "author is validated to be a non-empty string after stripping whitespace. Missing or empty author returns 400.",
      "max_score": 8
    },
    {
      "name": "author max length check",
      "description": "author longer than 100 characters is rejected with a 400 error.",
      "max_score": 6
    },
    {
      "name": "year type and range check",
      "description": "year is validated to be an integer (not a string or float) and within the range 1000–2100 inclusive. Invalid values return 400.",
      "max_score": 10
    },
    {
      "name": "tags list type check",
      "description": "tags is validated to be a list. Non-list values return 400.",
      "max_score": 8
    },
    {
      "name": "tags element check",
      "description": "Each element in tags is validated to be a non-empty string. Invalid elements cause a 400 error.",
      "max_score": 8
    },
    {
      "name": "400 JSON error response",
      "description": "All validation errors return HTTP 400 with a JSON body containing at least an 'error' key and a descriptive message.",
      "max_score": 10
    },
    {
      "name": "Valid request succeeds",
      "description": "A request with all valid fields returns HTTP 201 with the book data (the happy path is preserved).",
      "max_score": 10
    }
  ]
}

evals

scenario-1

criteria.json

task.md

tile.json