بنقرة واحدة
credential-leak-audit
Find and fix credential leaks in log/display output — the URL sanitization pattern from PRs
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Find and fix credential leaks in log/display output — the URL sanitization pattern from PRs
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Systematic approach to rebasing a stale PR branch onto a diverged upstream main — from PRs
Receive, verify, and respond to PR review feedback — especially hermes-sweeper automated reviews.
Hermes Ops Kit workflows for provider routing, secret and key lifecycle, preflight plugin scanning, MCP auditing, cost governance, and operator diagnostics.
Use Hermes Ops Kit with Vaultwarden/Bitwarden secret storage, preferring the Bitwarden CLI (`bw`) for item-level CRUD and verification.
| name | credential-leak-audit |
| description | Find and fix credential leaks in log/display output — the URL sanitization pattern from PRs |
Pattern for finding and fixing credential leaks in Python code that logs or displays configuration values to terminals, log files, or structured output.
When code reads a base_url from config and displays it without sanitization, the URL
may carry embedded credentials:
https://user:pass@api.example.com/v1 # userinfo in netloc
https://api.example.com/v1?api_key=sk-abc # query-string API token
https://api.example.com/v1#fragment # rarely sensitive, but strip anyway
These leak through:
logger.info("... %s ...", base_url) — log files, aggregatorsprint(f"base_url: {base_url}") — terminal output, CI logscheck_info(f"base_url: {base_url}") — diagnostic commandsSearch for config values that are interpolated into output without a sanitizer:
# Find base_url references in log/print calls
rg -n 'base_url.*f"|f".*base_url|logger\.\w+\(.*base_url|print\(.*base_url' --glob '!tests/**'
# Find API key references (should NEVER be in output)
rg -n 'api_key.*f"|f".*api_key|logger\.\w+\(.*api_key|print\(.*api_key' --glob '!tests/**'
If API keys are found in output: HIGH severity — fix immediately.
Add a sanitization function that strips sensitive URL components:
def _sanitize_url_for_display(url: str) -> str:
"""Strip userinfo, query, and fragment from a URL for terminal display."""
if not url:
return url
try:
from urllib.parse import urlparse, urlunparse
parsed = urlparse(url)
# Python's ParseResult has no `userinfo` field — split netloc manually
netloc = parsed.netloc
if "@" in netloc:
netloc = netloc.split("@")[-1]
sanitized = parsed._replace(netloc=netloc, query="", fragment="")
return urlunparse(sanitized)
except Exception:
return "<url-redacted>" # never return raw on failure
Apply it at every display site:
# Before (LEAKS credentials)
check_info(f"base_url: {base_url}")
label += f" at {fb_url}"
# After (SAFE)
check_info(f"base_url: {_sanitize_url_for_display(base_url)}")
label += f" at {_sanitize_url_for_display(fb_url)}"
| Location | Approach |
|---|---|
| Same module, single use | Inline the function |
| Same module, multiple uses | Module-level helper |
| Multiple modules | Extract to a shared utility (e.g., utils.py) |
For hermes-agent, utils.py already exists and is imported widely — it's the natural home
for a shared _sanitize_url_for_logging.
Test with known-bad URLs:
tests = [
("https://user:pass@host/v1?key=sk-secret#f", "https://host/v1"),
("https://api.openai.com/v1", "https://api.openai.com/v1"),
("", ""),
]
for url, expected in tests:
assert sanitize(url) == expected
set_runtime_main() logged _RUNTIME_MAIN_BASE_URL directly via logger.info().
The base URL can come from OPENAI_BASE_URL env var, which users commonly set with
embedded credentials. Added _sanitize_url_for_logging() and applied it before
interpolation.
_show_verbose_route_details() and _show_verbose_fallback_chain() displayed
base_url from config.yaml via check_info(). Added _sanitize_url_for_display()
and applied at both call sites.