Skip to content

Validate Awkward ZIP upload keys to prevent path traversal#1376

Open
stuartcampbell wants to merge 5 commits into
mainfrom
codex/fix-path-traversal-vulnerability-in-zip-upload
Open

Validate Awkward ZIP upload keys to prevent path traversal#1376
stuartcampbell wants to merge 5 commits into
mainfrom
codex/fix-path-traversal-vulnerability-in-zip-upload

Conversation

@stuartcampbell
Copy link
Copy Markdown
Member

@stuartcampbell stuartcampbell commented May 7, 2026

This was initially generated by Codex Security.

Motivation

  • A new /awkward/full upload flow accepted ZIP entry names verbatim and forwarded them into storage, enabling path traversal (zip-slip) and arbitrary file writes outside the dataset directory.
  • The deserializer returned a dict keyed by ZIP entry names with no validation, which ultimately allowed untrusted names like ../outside.txt to be written to disk.
  • The intent of the change is to block unexpected or malicious ZIP entry names while preserving legitimate Awkward buffer uploads.

Description

  • Validate ZIP entries during deserialization by computing expected_form_keys = set(awkward.forms.from_dict(form).expected_from_buffers()) and rejecting any ZIP entry not in that set with a ValueError in tiled/serialization/awkward.py.
  • Iterate zip.namelist() and raise a clear error for unexpected keys before reading buffer contents, preventing unsafe names from being returned to entry.write.
  • Add a regression test test_reject_unexpected_zip_form_key to tests/test_awkward.py that crafts a ZIP containing valid buffers plus ../outside.txt and asserts that deserialization is rejected.
  • Add required io and zipfile imports to the test file to support the new regression test.

Testing

  • Compiled affected modules with python -m compileall tiled/serialization/awkward.py tests/test_awkward.py, which succeeded.
  • Attempted to run pytest -q tests/test_awkward.py -k 'reject_unexpected_zip_form_key or slicing', but the test run could not complete in this environment due to missing test dependencies (asyncpg) from tests/conftest.py and optional packages; the test harness is therefore not fully executed here.
  • A focused runtime attempt to exercise the deserializer in this environment also could not run because the awkward package was not available, so the behavior was validated by static checks and the added unit test which will run in CI where dependencies are present.

Codex Task

@checkmarx-gh-ast-us-povs
Copy link
Copy Markdown

checkmarx-gh-ast-us-povs Bot commented May 7, 2026

Logo
Checkmarx One – Scan Summary & Detailsec6f869d-c7d1-48f3-a39e-d93826bdd594

Great job! No new security vulnerabilities introduced in this pull request


Communicate with Checkmarx by submitting a PR comment with @Checkmarx followed by one of the supported commands. Learn about the supported commands here.

@danielballan
Copy link
Copy Markdown
Member

Thanks! Seems good once CI passes.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants