CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/input-sanitization

Sanitize and validate user input at system boundaries — prevent XSS, SQL

94

1.20x
Quality

89%

Does it follow best practices?

Impact

100%

1.20x

Average score across 6 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-2/

{
  "context": "Tests whether the agent follows the full input validation pattern on a mutation endpoint: checking Content-Type first, trimming strings, validating required fields, enforcing length limits, parsing and range-checking numbers, and validating enums — all in the correct order before passing data to the service layer.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "Content-Type checked first",
      "description": "The POST/PUT/PATCH handler checks Content-Type (req.is('application/json') or equivalent) as the FIRST check before reading or validating any body fields",
      "max_score": 10
    },
    {
      "name": "415 status on wrong Content-Type",
      "description": "Returns HTTP 415 (Unsupported Media Type) when Content-Type is not application/json",
      "max_score": 10
    },
    {
      "name": "Strings trimmed",
      "description": "String fields from the request body are trimmed with .trim() (or equivalent) before being validated or stored",
      "max_score": 8
    },
    {
      "name": "Required fields validated",
      "description": "Missing or empty required string fields (after trimming) are rejected with HTTP 400",
      "max_score": 8
    },
    {
      "name": "Length limits enforced",
      "description": "At least one string field has an explicit maximum length check that returns 400 if exceeded",
      "max_score": 8
    },
    {
      "name": "Numeric field parsed",
      "description": "Numeric fields (e.g. quantity, price) are explicitly parsed with parseInt or Number() — not used directly as received from the body",
      "max_score": 10
    },
    {
      "name": "NaN and range rejected",
      "description": "After parsing, numeric fields are checked for NaN and out-of-range values (e.g. negative quantity), returning 400 on failure",
      "max_score": 10
    },
    {
      "name": "Enum validated against allowed list",
      "description": "A field that accepts a fixed set of values is checked against an explicit array or set of allowed values, returning 400 for unrecognised values",
      "max_score": 10
    },
    {
      "name": "Validated data passed to service",
      "description": "Validated and transformed values (trimmed strings, parsed numbers) — not raw req.body — are passed to the service or persistence layer",
      "max_score": 8
    },
    {
      "name": "Service layer business rule",
      "description": "The service or handler includes at least one business rule check beyond format validation (e.g. existence check, stock check, status transition guard, or permission check)",
      "max_score": 9
    },
    {
      "name": "Mass assignment prevented",
      "description": "The entire req.body object is NOT spread or passed directly into a database create/update call; only explicitly named fields are used",
      "max_score": 9
    }
  ]
}

evals

tile.json