Skip to content

fix(#6165): tighten auth_header redactor pattern to prevent JSON corruption - #6166

Open
fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/6165-fix-auth-header-pattern
Open

fix(#6165): tighten auth_header redactor pattern to prevent JSON corruption#6166
fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/6165-fix-auth-header-pattern

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Summary

Tightens the auth_header structural pattern in internal/security/redactor.go to fix two compounding bugs: (1) the \S{8,} capture group consumed JSON structural characters (", }, ]), corrupting JSON output after mask() replaced the match, and (2) the 8-character minimum triggered false positives on short technical references in triage agent output discussing auth headers.

Changes

  • Replace (\S{8,}) with ([^\s"'}\]),;]{16,}) in the auth_header regex — excludes JSON/YAML structural delimiters from the capture group and raises the minimum match length from 8 to 16 characters
  • Add four test cases covering: false positive rejection, JSON structure preservation, real secret detection, and the specific \S eating past JSON closing quotes regression

Testing

  • All existing tests in internal/security/ pass
  • Four new test cases pass covering the documented failure modes
  • go vet passes
  • Patch coverage at 100% for defaultStructuralPatterns

Closes #6165

Post-script verification

  • Branch is not main/master (agent/6165-fix-auth-header-pattern)
  • Secret scan passed (gitleaks — 3c7f5d034d3f9ace8efd3608a6322903da907809..HEAD)
  • PR body secret scan passed (gitleaks — no-git)

@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner August 13, 2026 06:56
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Agent PR ready for human review label Aug 13, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:57 AM UTC · Completed 7:13 AM UTC

Commit: 009cbf5 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review

Findings

Low

  • [scope-divergence] internal/security/redactor.go:172 — The PR body states the minimum match length was raised to 16, but the code implements {12,}. The linked issue (auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output #6165) also suggested auditing env_assignment for the same \S boundary bug — this audit is deferred. Consider updating the PR description and filing a follow-up for the audit.
  • [defense-in-depth-gap] internal/security/redactor.go:172 — Raising the minimum from 8 to 12 means secrets of 8–11 characters in auth headers will no longer be caught by this structural pattern. Practical impact is minimal since real auth tokens are typically 20+ characters and known token formats (ghp_, sk-ant-, etc.) are independently caught by prefix patterns.
Previous run

Review

Findings

Low

  • [redaction-gap] internal/security/redactor.go:172 — Raising the auth_header minimum match length from 8 to 16 creates a coverage gap for credentials in the 8–15 character range. Defense-in-depth layers mitigate this: prefix patterns catch known token formats (GitHub PATs, JWTs, etc.), the Python posttool hook uses a 20-char minimum, and the json_field pattern independently catches credentials in JSON contexts at 8+ chars. A minimum of 12 would still eliminate the documented false positive (token_value = 11 chars) while narrowing the gap slightly.

  • [scope-gap] internal/security/redactor.go:170 — Issue auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output #6165 notes the env_assignment pattern ([^\s'"]{8,}) has the same class of structural-delimiter consumption bug that this PR fixes for auth_header. A follow-up issue should audit all structural patterns for the same problem.

Previous run (2)

Review

Findings

Low

  • [edge-case] internal/security/redactor.go:172 — Raising the auth_header minimum match length from 8 to 16 creates a coverage gap for short auth tokens (8–15 chars), such as Base64-encoded Basic auth credentials (e.g., Authorization: Basic dXNlcjpwdw== at 12 chars). This is an intentional tradeoff documented in issue auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output #6165 — short tokens are lower-risk and the previous 8-char threshold caused false positives on short technical references like token_value. Prefix-based patterns still catch tokens with known prefixes (ghp_, sk-, etc.).
Previous run (3)

Review

Findings

Low

  • [edge-case] internal/security/redactor.go:172 — Raising the auth_header minimum match length from 8 to 16 creates a coverage gap for short auth tokens (8–15 chars), such as Base64-encoded Basic auth credentials (e.g., Authorization: Basic dXNlcjpwdw== at 12 chars). This is an intentional tradeoff documented in issue auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output #6165 — short tokens are lower-risk and the previous 8-char threshold caused false positives on short technical references like token_value. Prefix-based patterns still catch tokens with known prefixes (ghp_, sk-, etc.).

Labels: PR modifies internal security scanner/redactor code and fixes a documented bug

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge security Security threat model and related concerns type/bug Confirmed defect in existing behavior labels Aug 13, 2026
@ifireball

Copy link
Copy Markdown
Member

/fs-fix fix CI issue and review comments

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:41 AM UTC · Completed 8:53 AM UTC

Commit: 009cbf5 · View workflow run →

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Fixed CI failure caused by a test expectation that encoded the old buggy auth_header behavior (double-masking and quote-eating). The test now expects the correct output where the prefix pattern redacts the token and structural delimiters are preserved. Acknowledged the reviewer's low-severity finding about the 8-to-16 minimum as an intentional tradeoff per #6165.

Fixed (1):

  1. CI test failure in TestExtractSafeContext/bash_with_github_token_redacted (internal/runtime/claude_progress_test.go): Updated test expectation to match the new auth_header regex behavior. The old test expected '***' because the previous \S{8,} pattern would double-mask the already-redacted prefix output and consume the closing single quote. The new regex correctly stops at structural delimiters, so the prefix pattern's 'ghp_...' mask is preserved and the closing quote is not eaten.

Disagreed (1):

  1. auth_header 8-to-16 char minimum creates coverage gap for short auth tokens: The reviewer's own analysis acknowledges this is an intentional tradeoff documented in issue auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output #6165. Short tokens (8-15 chars) are lower-risk, the previous 8-char threshold caused false positives on technical references, and prefix-based patterns still catch tokens with known prefixes. No code change warranted.

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 13, 2026
The auth_header pattern change in the previous commit (8→16 char
minimum, excluding structural delimiters) correctly stops the
regex from double-masking already-redacted prefix output and eating
the closing quote. Update TestExtractSafeContext to match the new
(correct) behavior: the ghp_ prefix pattern redacts the token to
"ghp_..." and the closing quote is preserved.

Addresses review feedback on #6166
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 8:54 AM UTC · Ended 9:06 AM UTC

Commit: a1d49d9 · View workflow run →

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:54 AM UTC · Completed 9:06 AM UTC

Commit: a1d49d9 · View workflow run →

…uption

The auth_header structural pattern used \S{8,} as its capture group,
which matches any non-whitespace character including JSON structural
delimiters (", }, ], etc.). When the matched text reached the end of
a JSON string value, the capture group consumed the closing quote,
and mask() replaced it, destroying JSON validity.

Two changes to the regex:
1. Replace \S{8,} with [^\s"'}\]),;]{16,} — excludes JSON/YAML
   structural delimiters from the capture group, preventing the
   capture from eating past string boundaries.
2. Raise minimum match length from 8 to 16 — short technical
   references like "token_value" in conceptual discussion of
   auth headers are not real secrets. Real auth tokens are
   almost always 20+ characters.

Added four test cases covering: false positive rejection on short
technical references, JSON structure preservation after redaction,
real secret detection, and the specific regression where \S ate
past JSON closing quotes.

Closes #6165
The auth_header pattern change in the previous commit (8→16 char
minimum, excluding structural delimiters) correctly stops the
regex from double-masking already-redacted prefix output and eating
the closing quote. Update TestExtractSafeContext to match the new
(correct) behavior: the ghp_ prefix pattern redacts the token to
"ghp_..." and the closing quote is preserved.

Addresses review feedback on #6166
@ifireball
ifireball force-pushed the agent/6165-fix-auth-header-pattern branch from a1d49d9 to eadbe1f Compare August 20, 2026 08:16
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:18 AM UTC · Completed 8:34 AM UTC

Commit: eadbe1f · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@ifireball

Copy link
Copy Markdown
Member

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 10:03 AM UTC · Completed 10:09 AM UTC

Commit: eadbe1f · View workflow run →

Narrows the redaction coverage gap for 12-15 character credentials per
reviewer feedback, while still preventing the documented false positive
on short technical references like 'token_value' (11 chars).

Addresses review feedback on #6166
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (human-triggered)

Addressed 1 of 2 review findings. Lowered auth_header minimum match length from 16 to 12 to narrow the redaction gap while still preventing false positives. Disagreed with 1 finding (follow-up issue for env_assignment is out of scope for this PR).

Fixed (1):

  1. redaction-gap: auth_header minimum match length 16 creates coverage gap (internal/security/redactor.go): Lowered minimum match length from 16 to 12 per reviewer suggestion. A minimum of 12 still prevents the documented false positive on 'token_value' (11 chars) while narrowing the redaction gap for credentials in the 12-15 character range.

Disagreed (1):

  1. scope-gap: env_assignment pattern has same delimiter-consumption bug: The reviewer asks for a follow-up issue to audit env_assignment and other structural patterns. This is a valid concern but out of scope for this PR — it requires a separate issue and PR. No code change warranted here.

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:11 AM UTC · Completed 10:25 AM UTC

Commit: 9074df1 · View workflow run →

{"env_assignment", `(?i)(?:^|\s)(?:export\s+)?((?:[A-Za-z0-9]+_)*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|PASSWD|AUTH|API_KEY)(?:_[A-Za-z0-9]+)*)\s*=\s*['"]?([^\s'"]{8,})['"]?`},
{"json_field", `(?:"[^"]*(?i:key|token|secret|password|credential|auth)[^"]*"|'[^']*(?i:key|token|secret|password|credential|auth)[^']*')\s*:\s*(?:"([^"]{8,})"|'([^']{8,})')`},
{"auth_header", `(?i)(?:Authorization|X-Api-Key|X-Auth-Token)\s*:\s*(?:Bearer\s+)?(\S{8,})`},
{"auth_header", `(?i)(?:Authorization|X-Api-Key|X-Auth-Token)\s*:\s*(?:Bearer\s+)?([^\s"'}\]),;]{12,})`},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] scope-divergence

The PR body states the minimum match length was raised to 16, but the code implements {12,}. The linked issue (#6165) also suggested auditing env_assignment for the same \S boundary bug, which is deferred. Consider updating the PR description and filing a follow-up for the env_assignment audit.

Suggested fix: Update PR description to reflect the actual minimum (12). Consider filing a follow-up issue for auditing other structural patterns for the same \S boundary bug.

{"env_assignment", `(?i)(?:^|\s)(?:export\s+)?((?:[A-Za-z0-9]+_)*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|PASSWD|AUTH|API_KEY)(?:_[A-Za-z0-9]+)*)\s*=\s*['"]?([^\s'"]{8,})['"]?`},
{"json_field", `(?:"[^"]*(?i:key|token|secret|password|credential|auth)[^"]*"|'[^']*(?i:key|token|secret|password|credential|auth)[^']*')\s*:\s*(?:"([^"]{8,})"|'([^']{8,})')`},
{"auth_header", `(?i)(?:Authorization|X-Api-Key|X-Auth-Token)\s*:\s*(?:Bearer\s+)?(\S{8,})`},
{"auth_header", `(?i)(?:Authorization|X-Api-Key|X-Auth-Token)\s*:\s*(?:Bearer\s+)?([^\s"'}\]),;]{12,})`},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] defense-in-depth-gap

Raising the minimum from 8 to 12 means secrets of 8-11 characters in auth headers will no longer be caught by this structural pattern. Practical impact is minimal since real auth tokens are typically 20+ characters and known token formats are independently caught by prefix patterns.

@ifireball

Copy link
Copy Markdown
Member

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 11:56 AM UTC · Completed 12:03 PM UTC

Commit: 9074df1 · View workflow run →

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 3 (human-triggered)

No code changes needed. Both outstanding review findings are informational/low severity and the review approved the PR. The scope-divergence finding asks to update the PR body to reflect the actual minimum (12 instead of 16) — attempted but blocked by sandbox API restrictions. The defense-in-depth-gap finding is informational with no action suggested. All tests and CI checks pass.

Disagreed (2):

  1. scope-divergence: PR body states minimum match length was raised to 16, but code implements {12,}: This is a PR description issue, not a code issue. The fix agent attempted to update the PR body via gh pr edit but the sandbox network policy blocks GraphQL API calls. The PR body should be manually updated to change '16' to '12' in the Changes section. No code change is warranted — the code correctly uses {12,} as approved in iteration 2.
  2. defense-in-depth-gap: Raising minimum from 8 to 12 means secrets of 8-11 characters in auth headers will not be caught: This is an informational observation with no suggested fix. The reviewer notes that practical impact is minimal since real auth tokens are typically 20+ characters and known token formats are independently caught by prefix patterns. The review approved the change. No code change warranted.

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge All reviewers approved — ready to merge ready-for-review Agent PR ready for human review security Security threat model and related concerns type/bug Confirmed defect in existing behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

auth_header sanitizer pattern produces false positives on auth-related issues and corrupts JSON output

1 participant