Skip to content

security: harden solver execution gates and 94-test suite#452

Draft
brightyorcerf wants to merge 1 commit intoEAPD-DRB:mainfrom
brightyorcerf:security/harden-solver-execution-gates
Draft

security: harden solver execution gates and 94-test suite#452
brightyorcerf wants to merge 1 commit intoEAPD-DRB:mainfrom
brightyorcerf:security/harden-solver-execution-gates

Conversation

@brightyorcerf
Copy link
Copy Markdown
Contributor

@brightyorcerf brightyorcerf commented Apr 18, 2026

Linked issue

Existing related work reviewed

Overlap assessment

  • Classification: Security Hardening / Stability
  • Overlapping items: Filesystem path validation logic and Config.validate_path implementation.
  • Why this is not duplicate/superseded: While Fix case-run path traversal #431 and fix: sanitize dzuuid to prevent path traversal in /uploadCase (#254) #434 address path traversal at the "Passive Route" level (Data at rest: Uploads, Downloads, Deletions), this PR targets the "Active Execution" surface. Specifically, Fix case-run path traversal #431 secures file retrieval, but fails to validate caserunname in routes where it flows into subprocess.run() arguments (most notably /run and /batchRun. This PR introduces a comprehensive _validate_case_inputs framework that closes the Remote Code Execution (RCE) and Arbitrary File Write gaps that existing PRs have left exposed. Furthermore, this PR includes a full security regression suite (94 tests) ensuring these execution gates remain hardened against future regressions) a level of validation not present in previous submissions.

Why this PR should proceed

  • Patches a Critical Security Vulnerability: The v5.5 upstream sync introduced/modified several routes in DataFileRoute.py that failed to validate the caserunname input against path traversal. Because this value ultimately flows into subprocess.run() arguments for solver execution (in the /run endpoint), an attacker could escape the designated res/ sandbox (caserunname: "../../../../tmp/evil") and run shell processes from arbitrary directories, posing a severe system security risk.

  • Zero Regressions & Strong Test Coverage: Adds 94 new test cases specifically targeting traversal payloads (including null-byte injection) across all 12 affected route handlers. The entire existing test suite continues to pass. This PR also thoroughly enforces Config.validate_path() across all APIs that handle data files.

Summary

What changed:

  • Introduced the _validate_case_inputs() helper in DataFileRoute.py to consistently validate both casename and caserunname at the route boundary before any filesystem access or instantiation.
  • Applied the new path validation helper to 12 endpoints (including /generateDataFile, /createCaseRun and so on).
  • Implemented a strict whitelist ({'glpk', 'cbc'}) for the solver parameter in the /run endpoint to prevent command/solver injection.
  • Fixed a swallowed exception bug in /deleteCaseRun by placing the PermissionError handler before its parent class (OSError), ensuring path validation failures return a 400 instead of a generic 500.
  • Added a comprehensive test suite (tests/test_path_traversal.py) with 94 tests verifying path traversal protections.

Why:

  • Previously, while casename was somewhat protected by the DataFile() constructor inheriting Osemosys.__init__, caserunname was completely ignored. A request constructed with a safe casename but a malicious caserunname (e.g., ../../../../etc/passwd) would successfully bypass checks and traverse the filesystem. Validating both inputs exactly at the route entry point eliminates this gap.

Validation

  • Tests added/updated (or not applicable)
  • Validation steps documented
  • Evidence attached (logs/screenshots/output as relevant)
test

Documentation

  • Docs updated in this PR (or not applicable)
  • Any setup/workflow changes reflected in repo docs

Scope check

  • No unrelated refactors
  • Implemented from a feature branch
  • Change is deliverable without upstream OSeMOSYS/MUIO dependency
  • Base repo/branch is EAPD-DRB/MUIOGO:main (not upstream)

Exception rationale

blank

@github-actions github-actions Bot added the needs-intake-fix PR intake structure needs maintainer follow-up label Apr 18, 2026
@brightyorcerf brightyorcerf changed the title implement comprehensive execution-gate hardening and 94 regression tests security: harden solver execution gates and implement 94-test security suite Apr 18, 2026
@brightyorcerf brightyorcerf changed the title security: harden solver execution gates and implement 94-test security suite security: harden solver execution gates Apr 18, 2026
@brightyorcerf brightyorcerf changed the title security: harden solver execution gates security: harden solver execution gates with 94-test regression suite Apr 18, 2026
@brightyorcerf brightyorcerf changed the title security: harden solver execution gates with 94-test regression suite security: harden solver execution gates & 94-test suite Apr 18, 2026
@brightyorcerf brightyorcerf changed the title security: harden solver execution gates & 94-test suite security: harden solver execution gates and 94-test suite Apr 18, 2026
@SeaCelo
Copy link
Copy Markdown
Collaborator

SeaCelo commented May 6, 2026

Thanks for this. We're prioritizing other work right now, so converting this to draft for the time being. We'll revisit when we're ready to pick these up.

@SeaCelo SeaCelo marked this pull request as draft May 6, 2026 00:56
@SeaCelo SeaCelo added Deferred Not prioritized for now; revisit later Security Security hardening or vulnerability fix labels May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Deferred Not prioritized for now; revisit later needs-intake-fix PR intake structure needs maintainer follow-up Security Security hardening or vulnerability fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unvalidated subpath injection in solver execution and data-generation routes

2 participants