Skip to content

Enforce path validation and restrict default allowed origins#14

Merged
sergiobayona merged 1 commit into
mainfrom
security/enforce-path-and-origin-validation
Mar 17, 2026
Merged

Enforce path validation and restrict default allowed origins#14
sergiobayona merged 1 commit into
mainfrom
security/enforce-path-and-origin-validation

Conversation

@sergiobayona
Copy link
Copy Markdown
Owner

Address two partially-remediated findings from the 2026-03-17 security audit (SECURITY-004 and SECURITY-006) by making their protections mandatory rather than opt-in.

SECURITY-004 — ImageUtil path traversal (CWE-22):
Previously, validate_path_safety! only ran when a base_directory was explicitly passed to file_to_mcp_image_content. Callers who forgot to supply it got no protection at all. Now the validation always runs:

  • With base_directory: unchanged behavior (path must resolve within it).
  • Without base_directory: paths containing ".." are canonicalized and rejected if they escape the current working directory. This catches the common "../../etc/passwd" pattern even when callers omit the base_directory parameter. The method now returns the canonicalized path, which is used for all subsequent File.exist? / File.readable? / File.binread calls.

SECURITY-006 — Origin validation (CWE-352):
The default allowed_origins was ["*"], which silently permitted cross-origin requests from any website. The new default restricts to localhost/127.0.0.1/[::1] over both http and https. Additionally:

  • valid_origin? now does prefix matching so "http://localhost" in the allow list correctly matches "http://localhost:3000".
  • Configuring ["*"] explicitly still works but now logs a [SECURITY] warning at startup.

Test changes:

  • ImageUtil: added specs for traversal rejection without base_directory.
  • HttpStream: updated origin validation suite to cover the new default (localhost-only), port-aware matching, and opt-in wildcard behavior.

All 1421 examples pass, 0 failures. RuboCop clean.

Address two partially-remediated findings from the 2026-03-17 security
audit (SECURITY-004 and SECURITY-006) by making their protections
mandatory rather than opt-in.

SECURITY-004 — ImageUtil path traversal (CWE-22):
Previously, validate_path_safety! only ran when a base_directory was
explicitly passed to file_to_mcp_image_content. Callers who forgot to
supply it got no protection at all. Now the validation always runs:
- With base_directory: unchanged behavior (path must resolve within it).
- Without base_directory: paths containing ".." are canonicalized and
  rejected if they escape the current working directory. This catches
  the common "../../etc/passwd" pattern even when callers omit the
  base_directory parameter.
The method now returns the canonicalized path, which is used for all
subsequent File.exist? / File.readable? / File.binread calls.

SECURITY-006 — Origin validation (CWE-352):
The default allowed_origins was ["*"], which silently permitted
cross-origin requests from any website. The new default restricts to
localhost/127.0.0.1/[::1] over both http and https. Additionally:
- valid_origin? now does prefix matching so "http://localhost" in the
  allow list correctly matches "http://localhost:3000".
- Configuring ["*"] explicitly still works but now logs a [SECURITY]
  warning at startup.

Test changes:
- ImageUtil: added specs for traversal rejection without base_directory.
- HttpStream: updated origin validation suite to cover the new default
  (localhost-only), port-aware matching, and opt-in wildcard behavior.

All 1421 examples pass, 0 failures. RuboCop clean.
@sergiobayona
Copy link
Copy Markdown
Owner Author

/gemini-review

3 similar comments
@sergiobayona
Copy link
Copy Markdown
Owner Author

/gemini-review

@sergiobayona
Copy link
Copy Markdown
Owner Author

/gemini-review

@sergiobayona
Copy link
Copy Markdown
Owner Author

/gemini-review

@sergiobayona sergiobayona merged commit 7037e54 into main Mar 17, 2026
8 checks passed
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