Skip to content

Security hardening: Tier 1 fixes from SECURITY.md sweep#41

Open
MarketDataApp wants to merge 3 commits into
mainfrom
security-sweep
Open

Security hardening: Tier 1 fixes from SECURITY.md sweep#41
MarketDataApp wants to merge 3 commits into
mainfrom
security-sweep

Conversation

@MarketDataApp

@MarketDataApp MarketDataApp commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Full security sweep per SECURITY.md. All fixes below are Tier 1 (API- and behavior-compatible for legitimate consumers). Tier 2 findings are held back for maintainer discussion per policy.

Credential handling

  • obfuscate_token used a variable-width mask ("*" * (len-4) + last4), revealing the exact token length in debug logs — and up to 80% of short tokens. Now a fixed-width mask that never reveals length, and never reveals any characters of tokens ≤ 8 chars.

Injection into outbound requests

  • Path traversal via symbols: all 8 symbol-taking endpoints interpolated caller input raw into the URL path (f"stocks/earnings/{symbol}/"). A consumer passing untrusted end-user input as a symbol (e.g. a ticker search box) allowed AAPL/../../user to redirect the authenticated request to a different endpoint, or AAPL?x=y to smuggle query params. Path segments are now percent-encoded (quote(v, safe="")). Valid symbols (alphanumerics, ., -) are byte-identical after encoding.
  • Dot-segment traversal in options.lookup(): the lookup string was quoted with safe='/', so .. segments survived. Slashes are legitimate in lookup strings (dates like 7/28/2023), so they are kept — but all-dot segments are now percent-encoded so they cannot traverse. Valid lookup strings are unaffected.

Deserialization safety

  • Error messages extracted from response bodies were unbounded — a malformed/hostile response could balloon exception messages and logs. Now truncated to 500 chars. Also replaced a bare except: with except Exception:.
  • Missing or non-numeric x-api-ratelimit-* headers on an otherwise-successful response raised a raw KeyError/ValueError to the consumer. Now logs a warning and keeps the previously known limits.

Supply chain (CI/publish pipeline)

  • pypa/gh-action-pypi-publish was pinned to release/v1 — a moving branch ref — on the OIDC trusted-publishing job. Now pinned to the fixed release tag v1.14.0. Other actions stay on readable major-version tags; Dependabot (github-actions ecosystem) keeps them current.
  • test.yml now sets permissions: contents: read (default token was potentially write-scoped).

Tests

  • New test_path_injection.py: end-to-end respx tests asserting encoded wire paths for traversal/smuggling inputs and unchanged behavior for valid symbols and lookup strings.
  • Client tests for bounded error messages and tolerant rate-limit extraction.
  • Updated obfuscate_token expectations.

355 tests pass (uv run pytest -n 4). A few files show formatting-only diffs from ./lint.sh (Black).

Not in this PR (Tier 2 — needs maintainer approval)

Held back per policy; will summarize separately for discussion.

- Percent-encode caller-supplied symbols in request paths (path traversal
  / query smuggling via untrusted input); valid symbols unaffected
- Neutralize dot-segments in options.lookup() path while keeping valid
  slashes (dates) intact
- Token obfuscation no longer reveals token length or any characters of
  short tokens
- Bound API error messages extracted from response bodies (max 500 chars)
- Malformed rate-limit headers no longer crash a successful request
- Pin GitHub Actions to full commit SHAs; test workflow token read-only
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9df2bd0) to head (a96397f).

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #41   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           52        52           
  Lines         2293      2311   +18     
=========================================
+ Hits          2293      2311   +18     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Keep pypa/gh-action-pypi-publish on a fixed release tag (v1.14.0)
rather than the moving release/v1 branch ref.
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