Skip to content

security: restrict local image_url paths in AWSRekognitionProvider._prepare_image_input #1209

Description

@groupthinking

Problem

AWSRekognitionProvider._prepare_image_input selects its branch purely by string prefix:

  • s3://...S3Object
  • http(s)://... → fetched over HTTP
  • anything else → treated as a local filesystem path and read verbatim

That final branch reads whatever string it is given, so an absolute path or a ../
traversal supplied as image_url can read files outside any intended media directory.

Reachability

analyze_image is live from the primary production entrypoint:
youtube_extension.main:appcloud_ai_routes.py:89,141integrator.py:297-298.

Why this is a separate issue, not part of #1205

This behaviour is pre-existing and unchanged by #1205. On origin/main the same
branch already did:

with open(image_url, 'rb') as image_file:   # origin/main, line 373

#1205 is a performance change: it moved that read onto a worker thread via
asyncio.to_thread(_read_file_bytes, image_url). The set of readable paths is
identical before and after — no widening, no narrowing.

CodeRabbit raised it on #1205 (Security & Privacy, Major). It is a legitimate finding,
but fixing it properly means choosing and enforcing a policy, which is a behavioural
change deserving its own PR and its own tests rather than being smuggled into a
performance PR. This mirrors the scope objection CodeRabbit itself raised on #1152,
where an out-of-scope guard was reverted and tracked separately as #1162.

Acceptance criteria

  • A configured media root exists (env-driven, with a documented default).
  • Local paths are resolved (Path.resolve()) and rejected when outside that root.
  • Symlink escape is covered, not just lexical ../.
  • Rejection raises a typed error rather than returning empty bytes.
  • Tests cover: absolute path outside root, ../ traversal, symlink escape, and a
    valid in-root path still succeeding.
  • Decide whether callers should be restricted to s3:///https:// only, making the
    local branch dev-mode.

Reopened by the PR-remediation routine. This issue was closed as completed on
2026-08-02 while its implementing PR (#1216) was still an unmerged draft. The fix
(cloud_ai/media_paths.py) is not on origin/main — verified absent — so the
issue is not actually resolved yet. Reopening also unblocks #1216's own required
Canonical issue and evidence gate, which fails when the closing-referenced issue is
closed. It will auto-close again when #1216 merges.

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions