Repository navigation
Guard OTLP endpoints against scheme-only authorization headers #59315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -873,6 +873,27 @@ function parseOTLPHeaders(raw) { | |
| return result; | ||
| } | ||
|
|
||
| const EMPTY_OTLP_AUTHORIZATION_SCHEMES = new Set([ | ||
| "api-key", | ||
| "apikey", | ||
| "basic", | ||
| "bearer", | ||
| "concealed", | ||
| "digest", | ||
| "dpop", | ||
| "dsn", | ||
| "gnap", | ||
| "hoba", | ||
| "mutual", | ||
| "negotiate", | ||
| "oauth", | ||
| "privatetoken", | ||
| "scram-sha-1", | ||
| "scram-sha-256", | ||
| "sentry", | ||
| "vapid", | ||
| ]); | ||
|
|
||
| /** | ||
| * @param {string} raw | ||
| * @returns {boolean} | ||
|
|
@@ -881,7 +902,7 @@ function hasEmptyOTLPAuthorizationHeader(raw) { | |
| const headers = parseOTLPHeaders(raw); | ||
| return Object.entries(headers).some(([key, value]) => { | ||
| const normalizedKey = key.toLowerCase(); | ||
| return (normalizedKey === "authorization" || normalizedKey === "x-sentry-auth") && value === ""; | ||
| return (normalizedKey === "authorization" || normalizedKey === "x-sentry-auth") && (value === "" || EMPTY_OTLP_AUTHORIZATION_SCHEMES.has(value.toLowerCase())); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This drops any 💡 Tighten this to detect structurally empty credentials instead of matching literal secret valuesRight now the runtime is making a semantic decision from the secret payload alone: EMPTY_OTLP_AUTHORIZATION_SCHEMES.has(value.toLowerCase())That is safe only if the format contract guarantees those bare values are invalid for every supported backend, and the surrounding code/docs do not establish that. If the goal is specifically to catch expressions like For example, constrain the check to formats you actually own, or move the normalization earlier so the compiler/runtime can distinguish const authMatch = value.match(/^(\S+)\s+(.+)$/);
if (authMatch && EMPTY_OTLP_AUTHORIZATION_SCHEMES.has(authMatch[1].toLowerCase()) && authMatch[2].trim() === "") {
return true;
}That keeps the guard focused on incomplete credentials without inventing invalidity for otherwise non-empty secrets.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/tdd] The 💡 SuggestionConsider adding a unit test directly on @copilot please address this. |
||
| }); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/codebase-design] This hardcodes 18 specific auth-scheme names as a blocklist, which is a shallow fix for what's really a structural problem: any header value that is "just a scheme token with no credential" is invalid, regardless of which scheme name is used.
💡 Suggestion: detect structurally instead of enumerating schemes
A scheme-only
Authorization/x-sentry-authvalue never contains the credential material itself — the credential comes after a space (Scheme <token>) or is the whole value for schemeless auth. Consider testing structure instead of matching a fixed vocabulary, e.g.:This avoids needing to keep
EMPTY_OTLP_AUTHORIZATION_SCHEMESin sync with every current and future auth scheme (custom/vendor schemes likeAWS4-HMAC-SHA256,Signature,hawk, etc. are not in the list and would silently slip past the guard this PR adds). It also removes ~20 lines of enumeration that need justifying/maintaining.If the fixed list is intentionally conservative (to avoid false positives on legitimate single-word tokens), it'd help to note that tradeoff in a comment near the
Setso future readers understand why a structural check wasn't used.@copilot please address this.