Skip to content

FIX: Apply the request limits to request fields added since the last limits PR - #3595

Open
varunj-msft wants to merge 7 commits into
microsoft:mainfrom
varunj-msft:varunj-msft/10765-Newer-Field-Limits
Open

varunj-msft wants to merge 7 commits into
microsoft:mainfrom
varunj-msft:varunj-msft/10765-Newer-Field-Limits

Conversation

@varunj-msft

Copy link
Copy Markdown
Contributor

Description

Problem. Request fields added after #3174 skip the shared limits. Main accepts 100,001-character operation, finding, preset, suite, and technique-edit text, echoes 300-character source, preset, and suite names back in error responses, and lets a 257-character paired-outcome group id reach the handler, because FastAPI drops an annotated limit on a required query parameter.

Change. These fields now use the shared identifier, text, and item limits:

  • Operations and findings: descriptions, titles, and the custom "Other" severity and harm type (100,000), on the backend request models: OperationUpdateRequest, and the new OperationCreateRequest and FindingUpdateRequest (which FindingCreateRequest now extends).
  • Findings title search: 1,000 characters, the dataset search's limit. The search becomes a SQL LIKE pattern, which SQL Server limits to 8,000 bytes, and escaping can double its length.
  • Target bindings sent with attacks, saved conversations, and messages: names and hashes (256), checked by a request-only TargetBindingInput that still returns a plain TargetBinding, so request and saved bindings still compare equal.
  • SourceInstanceSpec: names, hashes, and parameter keys (256), and at most 100 parameters.
  • Presets and suites: description (100,000); author, names in the body and the URL, and the preset names a suite lists (256); the versions sent to update or resolve a preset and to update a suite (256).
  • Suite launch: the suite version and each entry's preset name and version (256).
  • Technique edits: description (100,000) and dependency identities (128, like source_identity).
  • Paired-outcome group ids: Query(..., max_length=...), the fix FIX: Apply the request limits to the remaining request fields #3174 used for conversation_id.

Limits go on the backend request models where one saved over-limit row would break a whole listing (operations, findings, and target bindings, which every attack summary re-reads), and on the shared models elsewhere, most of which already limit other fields. MAX_TEXT_LENGTH moves to pyrit/models/request_limits.py, following Rich's comment on #2960; pyrit/backend/models/common.py imports it from there.

What stays the same. Values within the limits; saved operations, findings, and target bindings, which still load; building operations, findings, and target bindings in Python; and prompt content and free-form parameter values (still limited only by the body size). The shared preset, suite, suite-launch, technique-edit, and source-spec models apply their new limits to Python callers too, as #2960 did for scenario runs. So a saved preset or suite over a limit is skipped as invalid, a saved run whose technique edit is over a limit can't be resumed, and a saved target binding with an over-limit name can't be rebuilt. None of these models are in v1.1.0. Preset resolve and suite launch take their other fields from ScenarioLaunchConfiguration, which already limits them. The author the routes fill in for the signed-in user is the Microsoft Graph display name or email, which fit the 256 limit.

Tests and Documentation

  • New boundary tests through the real routes and request models, plus: over-limit preset and suite names are rejected without being echoed when sent in a request body, and before the route runs when sent in the URL; saved over-limit operations, findings, and bindings still load; a request binding still equals the saved one; the findings title search at 1,000 and 1,001 characters.
  • pytest -n 8 --dist=loadfile tests/unit/backend tests/unit/models tests/unit/registry: 6,514 passed, 4 skipped.
  • uv run --frozen --extra all --link-mode=copy ty check pyrit: all checks passed.
  • Live, against local backends built from this branch and from main with the same config: 28/28 checks pass on both. Main lets the over-limit values through (201/200, or the route's own 400/404), echoes 300-character source, preset, and suite names back in errors, and lets a 257-character group id reach the handler; this branch returns 422 for each, without echoing names sent in a request body. Values at the limits are accepted on both.
  • pyrit/backend/README.md: the Request Limits list now names titles and descriptions.

No JupyText changes.

…limits PR

Operation and finding text, component source specs and target bindings, the
paired-outcome group ids, preset and suite descriptions and authors, version
preconditions, and technique edit descriptions and dependency identities now use
the shared identifier, text, and item limits. Operations, findings, and target
bindings are checked only on requests, so rows already saved keep loading. The
paired-outcome group ids get an explicit Query max_length, because FastAPI drops
the annotated limit on a required query parameter.
Assert the exact status for a dependency identity at the limit, and cover the
binding limit on message sends, which inherit it from the add-message request.
The title search becomes a LIKE pattern, which SQL Server limits to 8,000 bytes,
and escaping can double its length. It now has the same 1,000-character limit as
the dataset search.
The preset and suite names, and the preset names a suite lists, came in
after the last limits PR without a length limit. The registry-name check
puts the name in its error message, so an invalid name was echoed in
full in the 422 response. Cap them at the shared identifier limit, which
rejects an over-limit name before that check runs.
Keep the limit on the preset resolve version, which main moved to
pyrit.models.catalog.scenario_preset.
The suite launch request came in after the last limits PR. Give its
suite version and each entry's preset name and version the shared
identifier limit, like the other versions sent with a request. Also
give this PR's suite route tests the one-line docstrings the rest of
that file has.
The preset and suite routes came in after the last limits PR and read
the name in the URL as a plain string, unlike the other routes' path
identifiers. Use IdentifierStr, so an over-limit name gets a 422 before
the route runs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant