-
Notifications
You must be signed in to change notification settings - Fork 19
[duplicate-code] Duplicate Code Pattern: Bearer/Agent Header Prefix Parsing in auth/header.go #3109
Description
Part of duplicate code analysis: #3108
Summary
ParseAuthHeader and ExtractSessionID in internal/auth/header.go both contain near-identical logic for detecting and stripping the "Bearer " and "Agent " scheme prefixes from Authorization header values. This 16-line block is duplicated verbatim, differing only in one strings.TrimSpace call.
Duplication Details
Pattern: Repeated Bearer/Agent Scheme Prefix Detection
- Severity: High
- Occurrences: 2 instances in the same file
- Locations:
internal/auth/header.go(lines 75–88, insideParseAuthHeader)internal/auth/header.go(lines 151–163, insideExtractSessionID)
Instance 1 — ParseAuthHeader (lines 75–88):
// Handle "Bearer <token>" format (backward compatibility)
if strings.HasPrefix(authHeader, "Bearer ") {
log.Print("Detected Bearer token format (backward compatibility)")
token := strings.TrimPrefix(authHeader, "Bearer ")
return token, token, nil
}
// Handle "Agent <agent-id>" format
if strings.HasPrefix(authHeader, "Agent ") {
log.Print("Detected Agent ID format")
agentIDValue := strings.TrimPrefix(authHeader, "Agent ")
return agentIDValue, agentIDValue, nil
}Instance 2 — ExtractSessionID (lines 151–163):
// Handle "Bearer <token>" format (backward compatibility)
// Trim spaces for backward compatibility with older clients
if strings.HasPrefix(authHeader, "Bearer ") {
log.Print("Detected Bearer format, trimming spaces for backward compatibility")
sessionID := strings.TrimPrefix(authHeader, "Bearer ")
return strings.TrimSpace(sessionID)
}
// Handle "Agent <agent-id>" format
if strings.HasPrefix(authHeader, "Agent ") {
log.Print("Detected Agent format")
return strings.TrimPrefix(authHeader, "Agent ")
}The only behavioral difference is that ExtractSessionID calls strings.TrimSpace on Bearer tokens.
Impact Analysis
- Maintainability: If a new header scheme is added (e.g.,
"Token "for a future spec version), it must be added in two places; a missed update would cause inconsistent behavior between session extraction and full auth parsing - Bug Risk: High — the two functions are in a security-critical code path. Discrepancies in scheme handling between them could result in auth bypass or session mismatch vulnerabilities
- Code Bloat: Minor (~16 lines), but concentrated in a file already well-structured with clear doc comments
Refactoring Recommendations
-
Extract a private
stripAuthSchemehelper insideinternal/auth/header.go:// stripAuthScheme extracts the value from a scheme-prefixed Authorization header. // Recognizes "Bearer <value>" and "Agent <value>" formats. // Returns (scheme, value, true) on match, or ("", authHeader, false) for plain values. func stripAuthScheme(authHeader string) (scheme, value string, matched bool) { for _, prefix := range []string{"Bearer ", "Agent "} { if strings.HasPrefix(authHeader, prefix) { scheme = strings.TrimSuffix(prefix, " ") value = strings.TrimPrefix(authHeader, prefix) return scheme, value, true } } return "", authHeader, false }
Then both
ParseAuthHeaderandExtractSessionIDcan callstripAuthSchemeand apply their own post-processing (e.g.,TrimSpaceinExtractSessionID). -
Or, have
ExtractSessionIDdelegate toParseAuthHeadersinceExtractAgentIDalready does this pattern — though theTrimSpacedivergence would need to be resolved first.
Implementation Checklist
- Review both functions to confirm the
TrimSpacedifference is intentional - Extract
stripAuthSchemeprivate helper (or equivalent) - Update
ParseAuthHeaderto use the helper - Update
ExtractSessionIDto use the helper - Verify all existing tests pass
- Add a test case for each recognized scheme in the helper
Parent Issue
See parent analysis report: #3108
Related to #3108
Generated by Duplicate Code Detector · ◷
- expires on Apr 10, 2026, 6:01 AM UTC