Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

62 lines
3.3 KiB
Markdown

# Credential scrubbing in error/log text
`local_deep_research.security.log_sanitizer` scrubs credentials out of
exception/error strings **before** they reach a client (HTTP/SSE/JSON
responses) or the logs. It is a runtime, defense-in-depth *sanitizer* — not a
git/CI secret *scanner* (use [gitleaks](https://github.com/gitleaks/gitleaks)
for that, which this repo already runs in pre-commit/CI).
## The two layers
1. **`sanitize_error_message(text)`** — a regex first-pass over `_CREDENTIAL_PATTERNS`
for *common credential shapes* (API-key query params, `Authorization:`/
`x-api-key:` headers, `user:pass@host`, and well-known token prefixes:
`sk-`/`pk-`, Google `AIza`/`ya29.`, GitHub `ghp_`/`github_pat_`, AWS
`AKIA`/`ASIA`, Slack `xox*-`, JWTs). `sanitize_error_for_client()` composes
it with control-char stripping + length capping.
2. **`redact_secrets(text, *known_literals)`** — the **backstop**. When you
hold the actual secret value (e.g. the configured API key), pass it here so
it is scrubbed regardless of shape. This is the real guarantee for
*known* secrets; the regex layer is best-effort for *unknown* ones.
Always pair them ("dual-scrub") on any path that surfaces secret-adjacent
text — via **`scrub_error(error, *known_literals)`** (`security.log_sanitizer`),
which composes both passes plus the defensive guards (a raising `__str__`
or a non-string secret cannot crash the `except` handler). Engine
subclasses use `self._scrub_error(error)`, which resolves the engine's
`_secret_attrs` and delegates to the same helper. Don't hand-inline the
two calls: per-site copies are how scrub passes drift apart.
## Design constraints (why it is curated, not exhaustive)
This runs on **arbitrary, possibly attacker-influenced** strings at runtime, so:
- **No ReDoS.** Every pattern must scale linearly — prefer prefix-anchored,
single-quantifier regexes; avoid nested quantifiers / ambiguous alternations.
Spot-check new patterns on a 200k-char adversarial input.
- **Over-redaction is the safe failure; under-redaction (a leak) is not** —
but gratuitous over-redaction harms log readability, so patterns are
anchored/length-floored to avoid eating prose.
- Keep the set **small and high-signal**. Matching gitleaks' full 100+ rules
at runtime is overkill and raises false positives; the `redact_secrets`
backstop covers the long tail for known secrets.
## Keeping the patterns current
The prefix regexes mirror the **canonical, actively-maintained gitleaks
ruleset** — gitleaks' own upstream `config/gitleaks.toml`
(<https://github.com/gitleaks/gitleaks>), **not** this repo's root
`.gitleaks.toml` (which only configures the gitleaks *scan* run in
pre-commit/CI). To refresh when a provider introduces a new token format:
1. Find the rule in gitleaks' upstream `config/gitleaks.toml` (or detect-secrets).
2. Adapt the regex to a prefix-anchored, ReDoS-safe form here; redact to
`[REDACTED_KEY]`.
3. Add a positive (redacts) **and** a negative (prose not over-redacted) case
to `tests/security/test_log_sanitizer.py`.
4. Run `pytest tests/security/` and a 200k-char ReDoS spot-check.
A periodic (e.g. quarterly) glance at gitleaks' changelog for new
widely-used token prefixes is enough — this layer only needs the formats that
plausibly appear in *this app's* error/log text.