Skip to content

[BREAKING] FIX: Keep uploads from API-created HTTP targets in a server-chosen folder - #3172

Open
varunj-msft wants to merge 1 commit into
microsoft:mainfrom
varunj-msft:varunj-msft/10765-HTTP-Upload-Folder
Open

varunj-msft wants to merge 1 commit into
microsoft:mainfrom
varunj-msft:varunj-msft/10765-HTTP-Upload-Folder

Conversation

@varunj-msft

@varunj-msft varunj-msft commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

HTTPXAPITarget can upload a local file when it sends: its file_path, a path-typed message piece, or a text prompt that names an existing file (deprecated). When it was created through POST /api/targets, the caller chose both the file and allowed_upload_directory, or left the folder unset, which allows any file. So an API caller could make the server upload any file it can read, such as .env, to a URL of their choice.

Expected behavior:

  • The operator chooses the folder with a new target_upload_directory setting in .pyrit_conf. The server passes it to the target as allowed_upload_directory, and callers can't set it (400).
  • Without the setting, HTTPXAPITarget is not listed in GET /api/targets/types, and creating it through the API returns 400.
  • The folder check itself is the target's existing _validate_upload_path, so absolute paths, .., and symlinks that end up outside the folder are refused before anything is sent. A send like that records the target's error in the conversation, like other target errors; nothing is uploaded.
  • Targets registered in Python or by initializers are unchanged.

PromptTarget.upload_directory_parameter (default None) names the constructor parameter the server sets; HTTPXAPITarget sets it to allowed_upload_directory. The loader only checks that the setting is a non-empty string. The target checks that the folder exists when it is created, so a folder mounted after startup works, and a missing one fails that request instead of backend startup.

BREAKING: API callers who create HTTPXAPITarget now need the operator to set target_upload_directory, and can no longer pass allowed_upload_directory.

Not included: network destinations. Callers still choose http_url, like any other target endpoint.

Note for #3030 and #3058: both add other ways to build targets from API input (build_from_source_async, and rebuilding saved targets at startup). They'll need the same folder injection. For #3058 the folder should be applied when the target is built, like the auth-mode parameters, rather than saved with the target.

Tests and Documentation

  • test_target_service.py: the type is hidden without the setting and listed without allowed_upload_directory when it is set; a caller-supplied folder is rejected before construction; the server folder is injected.
  • test_api_routes.py: the routes pass the configured folder to the service.
  • test_runtime_lifecycle.py, test_configuration_loader.py: the setting is loaded and validated, published by the runtime, and left unset when startup fails.
  • .pyrit_conf_example documents target_upload_directory.
    No JupyText changes.

…folder

An HTTPXAPITarget created through the API could upload any file the server can read: the caller chose file_path and allowed_upload_directory, and a text message naming a path was uploaded too. The server now sets allowed_upload_directory from the new target_upload_directory setting, callers cannot supply it, and the type is left out of the target catalog while the setting is unset.

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