Skip to content

WS-ART-001-03B3B3A: bounded OOXML container security - #233

Merged
abiorh-claw merged 2 commits into
mainfrom
codex/ws-art-001-03b3b3a-ooxml-security
Jul 31, 2026
Merged

WS-ART-001-03B3B3A: bounded OOXML container security#233
abiorh-claw merged 2 commits into
mainfrom
codex/ws-art-001-03b3b3a-ooxml-security

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

WS-ART-001-03B3B3A PR Trust Bundle

Chunk

WS-ART-001-03B3B3A — OOXML Container Security (L1).

Goal and human-approved intent

Install only the previously approved defusedxml dependency and add a shared,
bounded OPC/OOXML security boundary for verified guide-source bytes. Project
Manager guide uploads remain distinct from contributor submission ZIPs. This
chunk must not extract DOCX/PPTX/XLSX content or activate AUTH or sufficiency.

What changed and why

  • Added the exact hash-bound defusedxml==0.7.1 wheel and lock evidence.
  • Added central-directory-first OOXML validation with exact format markers,
    passive package-part/content-type/relationship policies, and bounded XML.
  • Reused the classifier's canonical limits, markers, and EOCD facts so
    classification and child validation cannot drift.
  • Added a typed isolated-worker loader that maps every security failure to the
    existing bounded extraction protocol without registering an adapter.
  • Assigned focused tests to shared_foundations and documented the boundary.

Design chosen and alternatives rejected

The existing format classifier owns server classification and shared ZIP facts;
the isolated child owns defusedxml parsing and strict OOXML validation. Future
DOCX, PPTX, and XLSX adapters must pass this boundary before semantic parsing.
Rejected alternatives were upload-time parsing, root-only allowlists, filename-
only active-content checks, direct provider access, generic ZIP support, and
activating incomplete document adapters.

Scope control and product behavior

The corrected contract lists every changed implementation, test, lane, and
documentation file. There is no route, provider, binding, AUTH, Celery,
submission, review, payment, reputation, or agent-input behavior. Malformed,
ambiguous, active, external, or over-limit packages become bounded internal
extraction outcomes, never guide-insufficiency decisions.

Acceptance criteria proof

  • All metadata is inspected before any body read; a spy proves zero reads for
    encrypted, duplicate, unsafe-path, unknown/cross-format, marker-conflict,
    special-entry, and executable metadata failures.
  • Exact 2,000/2,001 entry, central-directory, decompressed-byte, compression,
    and relationship-size boundaries are covered.
  • Symlinks, traversal, encryption, ZIP64/multidisk, nested/prefixed archives,
    macros, embeddings, executables, DTD/entities including UTF-16, active MIME
    or relationship metadata, and external/escaping targets reject fail closed.
  • Only the exact classified format root and passive OPC parts are accepted;
    directory entries cannot satisfy required file markers.
  • Corrupt local headers and body reads map to stable bounded failures.

Tests and checks

  • Ruff, dependency gate, and lock check — pass.
  • Focused OOXML/extraction/classification/architecture suite — 136 passed.
  • OOXML module coverage — 93.92 percent.
  • CI lane inventory — 31 passed.
  • Stale-contract scan, Markdown links, and git diff --check — pass.
  • Hosted Backend/Agent Gates retain repository-wide coverage and semantic-lane
    proof; no local full-suite run was used.

Test delta and CI integrity

No test, assertion, lane, workflow, or coverage threshold was removed, skipped,
or weakened. The new focused module is in the existing shared_foundations
lane. The dependency is an exact approved PyPI wheel URL/hash and the lockfile
resolves the same bytes.

Reviewer results

Architecture, security, QA, senior engineering, CI integrity, docs, and test
delta pass. Product/ops and reuse/dedup pass with non-blocking future advice.
Initial strictness, metadata, DTD, nested-archive, reuse, and assertion findings
were repaired and re-reviewed.

External review

Pending CodeRabbit and hosted GitHub Backend/Agent Gates on the published PR
head.

Remaining risks and follow-up

OOXML is a complex untrusted container, so isolated execution and the strict
positive policy remain essential. The later 03B3B3B/C/D chunks add document-
specific extraction separately; 03B3B4 handles image metadata. AUTH remains
planned/unavailable until the complete hidden 03B series merges.

Human review focus and merge ownership

Review the exact dependency hash, central-directory-first ordering, passive
part/content-type/relationship policies, shared classifier facts, stable
failure mapping, and absence of adapter activation. A human owns merge approval;
the agent will not merge this PR.

Summary by CodeRabbit

  • New Features

    • Added security validation for supported Office document packages before processing.
    • Detects malformed or unsafe archives, including suspicious paths, embedded content, active content, external links, and nested archives.
    • Enforces package size, entry-count, and compression limits to help prevent resource-exhaustion attacks.
  • Bug Fixes

    • Invalid Office packages now produce consistent, bounded validation failures without activating document extraction.
  • Documentation

    • Clarified the validation-only security boundary and supported package restrictions.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Abiorh001, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fb2f76c3-8b24-430c-abb0-a5823fa05ae4

📥 Commits

Reviewing files that changed from the base of the PR and between b31e565 and 45132ff.

📒 Files selected for processing (5)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-03B3B3A-external-review-response.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-03B3B3A-pr-trust-bundle.md
  • backend/app/modules/artifacts/guide_ooxml.py
  • backend/tests/test_guide_ooxml.py
📝 Walkthrough

Walkthrough

This PR adds bounded, validation-only OOXML/OPC security for DOCX, PPTX, and XLSX packages. It validates archive metadata, XML, relationships, content, and resource limits, then maps failures in the isolated extraction worker.

Changes

OOXML container security

Layer / File(s) Summary
Shared format contracts and policy
.agent-loop/.../chunks/*, backend/app/modules/artifacts/guide_formats.py, backend/pyproject.toml, docs/spec_artifact_storage_service.md
Shared OOXML markers and bounded ZIP metadata handling support validation-only package checks. The approved defusedxml wheel and service rules are recorded.
OOXML package validator
backend/app/modules/artifacts/guide_ooxml.py
The validator enforces format allowlists, safe paths, archive limits, passive-part rules, XML and relationship policies, nested-archive rejection, and coded failures.
Isolated worker integration
backend/app/modules/artifacts/guide_extraction_worker.py, backend/tests/test_artifact_architecture.py, backend/tests/test_guide_extraction.py
The worker maps OOXML security failures to ExtractionFailure. Architecture and regression tests verify import confinement and adapter non-activation.
Security regression coverage and review evidence
backend/tests/test_guide_ooxml.py, backend/scripts/run_test_lanes.py, .agent-loop/.../reviews/*, .agent-loop/.../REVIEW_LOG.md, .agent-loop/.../STATUS.md
Focused tests cover valid, malformed, unsafe, oversized, encrypted, and metadata-only rejection cases. Review evidence records verification results and scope status.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExtractionWorker
  participant OOXMLValidator
  participant DefusedXML
  ExtractionWorker->>OOXMLValidator: Validate package payload
  OOXMLValidator->>DefusedXML: Parse XML safely
  DefusedXML-->>OOXMLValidator: Parsed XML or parser failure
  OOXMLValidator-->>ExtractionWorker: Package facts or security failure
  ExtractionWorker-->>ExtractionWorker: Map failure to ExtractionFailure
Loading

Possibly related PRs

Suggested reviewers: abiorh-claw

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the workstream and summarizes the main change: bounded OOXML container security.
Description check ✅ Passed The description covers the required goals, scope, design, evidence, acceptance criteria, risks, review status, and merge ownership.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ws-art-001-03b3b3a-ooxml-security

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Abiorh001

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/modules/artifacts/guide_ooxml.py`:
- Around line 140-149: Restrict _part_is_allowed so root-level relationships are
accepted only when the name is exactly "_rels/.rels", while preserving valid
directory-level relationship parts. Update _relationship_target_is_external to
fail closed or raise for any .rels name that matches neither "_rels/.rels" nor
the "<dir>/_rels/<partname>.rels" pattern, preventing incorrect source-directory
derivation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b27fe8ee-b1fd-4e43-a257-f80ea36f70c8

📥 Commits

Reviewing files that changed from the base of the PR and between 081dfe7 and b31e565.

⛔ Files ignored due to path filters (1)
  • backend/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-03B3B3A-ooxml-container-security.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-03B3B3A-internal-review-evidence.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-03B3B3A-pr-trust-bundle.md
  • backend/app/modules/artifacts/guide_extraction_worker.py
  • backend/app/modules/artifacts/guide_formats.py
  • backend/app/modules/artifacts/guide_ooxml.py
  • backend/pyproject.toml
  • backend/scripts/run_test_lanes.py
  • backend/tests/test_artifact_architecture.py
  • backend/tests/test_guide_extraction.py
  • backend/tests/test_guide_ooxml.py
  • docs/spec_artifact_storage_service.md

Comment thread backend/app/modules/artifacts/guide_ooxml.py
@abiorh-claw
abiorh-claw self-requested a review July 31, 2026 13:47
@abiorh-claw
abiorh-claw self-requested a review July 31, 2026 13:48
@abiorh-claw
abiorh-claw merged commit 2f441e9 into main Jul 31, 2026
6 checks passed
@abiorh-claw
abiorh-claw deleted the codex/ws-art-001-03b3b3a-ooxml-security branch July 31, 2026 14:34
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.

2 participants