Skip to content

fix(security): sanitize all override diagnostic controls on current main - #414

Open
seonghobae wants to merge 4 commits into
mainfrom
fix/policy-override-log-control-main-20260812-r2
Open

fix(security): sanitize all override diagnostic controls on current main#414
seonghobae wants to merge 4 commits into
mainfrom
fix/policy-override-log-control-main-20260812-r2

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Objective

Prevent log and terminal control injection through client-provided policy-override diagnostics while retaining redaction of approval secrets and identities.

Exact current-head evidence

  • protected base: 961f44a19c4ced87f8062b3ab9842a9a08d05235;
  • test-only RED head: dcc36bacc974cde95eefa4d45ee70f3951b7c11c;
  • exact GREEN head: 293a48ca395d457ae08632b2c94571f9ee958cc2;
  • CI, Security Scan, SAST Semgrep, and fuzz: terminal-success;
  • mergeable: true;
  • unresolved review threads: zero.

Contract

Every ISO control character, including ESC, NUL, newline, and tab, is replaced with _ in the printable override flag. Raw accessor behavior is unchanged, while approval-token and approver identity remain redacted from diagnostic output.

Scope boundary

Diagnostic rendering only. Authorization, token verification, audit pseudonymization, tenant identity, and unrelated logging remain unchanged.

Merge gate

Keep this exact head unchanged. Auto-merge may act only after live checks remain successful, zero valid unresolved findings remain, and a qualifying independent non-author approval is attached to this exact head. Automated evidence and predecessor reviews do not transfer.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 18222ef6-3eaf-4bd2-a849-01628a787485

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4451d47a-f055-440d-8247-c292ee9d53b9

📥 Commits

Reviewing files that changed from the base of the PR and between b66b692 and 11bce87.

📒 Files selected for processing (2)
  • src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java
  • src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java

📝 Walkthrough

Walkthrough

normalizeHeader가 CR, LF, 탭뿐 아니라 모든 ISO 제어 문자를 _로 치환합니다. 테스트는 ESCNUL 문자가 toString() 출력에 노출되지 않는지 검증합니다.

Changes

PolicyOverrideRequest 정규화

Layer / File(s) Summary
헤더 정규화와 검증
src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java, src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java
normalizeHeader가 모든 ISO 제어 문자를 _로 치환합니다. 테스트는 ESCNUL 문자의 치환과 원본 문자 비노출을 검증합니다.

Estimated code review effort: 1 (매우 간단) | ~5분

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 현재 main에서 override 진단 출력의 모든 제어 문자를 정제하는 주요 변경 사항을 명확하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/policy-override-log-control-main-20260812-r2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 12, 2026 06:14
@seonghobae
seonghobae enabled auto-merge (squash) August 12, 2026 07:07

Copy link
Copy Markdown
Collaborator Author

@opencode-agent review

Please review the unchanged exact current head 11bce87a46fa61709ad2226b7d6f033c6275a651 against live protected main and repository gates. Treat checks/model output as evidence only and submit a formal review only for this exact head.

Copy link
Copy Markdown
Collaborator Author

Exact-current-head read-only review request for 293a48ca395d457ae08632b2c94571f9ee958cc2 on protected main 961f44a19c4ced87f8062b3ab9842a9a08d05235. CI, Security Scan, SAST Semgrep, and fuzz are terminal-success; the two-file diagnostic-safety delta is mergeable with zero unresolved threads. Verify replacement of every ISO control while preserving raw accessor semantics and redaction of approval-token and approver identity. Do not mutate the branch or bypass independent approval.

@opencode-agent review
@cwl-noema-review review
@strix review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head_sha="293a48ca395d457ae08632b2c94571f9ee958cc2"
base_sha="961f44a19c4ced87f8062b3ab9842a9a08d05235"
repo="ContextualWisdomLab/clearfolio"
pr_number="414"

echo "== Repository checkout =="
git rev-parse HEAD
git status --short
git cat-file -e "${head_sha}^{commit}"
git cat-file -e "${base_sha}^{commit}"
echo
echo "== Exact commit relationship =="
git merge-base --is-ancestor "$base_sha" "$head_sha" && echo "base_is_ancestor=yes" || echo "base_is_ancestor=no"
git diff --name-status "$base_sha" "$head_sha"
echo
echo "== Exact diff =="
git diff --no-ext-diff --unified=80 "$base_sha" "$head_sha" -- \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java
echo
echo "== Production type outline =="
ast-grep outline src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java --items all --view expanded
echo
echo "== Test type outline =="
ast-grep outline src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java --items all --view expanded
echo
echo "== Relevant symbols and diagnostics paths =="
rg -n -C 8 --type java \
  '(normalizeHeader|toString\s*\(|getApproval|approvalToken|approver|PolicyOverrideRequest)' \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java
echo
echo "== GitHub PR evidence =="
gh pr view "$pr_number" --repo "$repo" --json number,headRefOid,baseRefOid,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,reviewThreads

Length of output: 37873


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="ContextualWisdomLab/clearfolio"
owner="${repo%%/*}"
name="${repo#*/}"
pr_number="414"

echo "== Live main reference and protection =="
gh api "repos/${repo}/git/ref/heads/main" --jq '{ref: .ref, sha: .object.sha}'
gh api "repos/${repo}/branches/main/protection" \
  --jq '{required_status_checks, required_pull_request_reviews, enforce_admins, required_linear_history}' \
  || echo "branch_protection_query_unavailable"
echo
echo "== Pull request metadata =="
gh pr view "$pr_number" --repo "$repo" \
  --json number,state,isDraft,headRefOid,baseRefOid,mergeable,mergeStateStatus,reviewDecision,latestReviews,url
echo
echo "== Exact-head check runs =="
gh api "repos/${repo}/commits/293a48ca395d457ae08632b2c94571f9ee958cc2/check-runs?per_page=100" \
  --jq '[.check_runs[] | {name, status, conclusion, details_url}]'
echo
echo "== Review threads =="
gh api graphql \
  -F owner="$owner" \
  -F name="$name" \
  -F number="$pr_number" \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      headRefOid
      baseRefOid
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          path
          line
          originalLine
          comments(first: 20) {
            nodes {
              author { login }
              body
              createdAt
            }
          }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest | {
    headRefOid,
    baseRefOid,
    threads: [
      .reviewThreads.nodes[] | {
        isResolved, isOutdated, path, line, originalLine,
        comments: [.comments.nodes[] | {author: .author.login, body, createdAt}]
      }
    ]
  }'

Length of output: 8840


@seonghobae Review complete for exact head 293a48ca395d457ae08632b2c94571f9ee958cc2 against live main 961f44a19c4ced87f8062b3ab9842a9a08d05235.

I found no issues in the requested scope.

  • The diff changes only the two diagnostic-safety files.
  • normalizeHeader() replaces every Java ISO control character with _, including ESC, NUL, C0, DEL, and C1 controls.
  • The raw accessors retain the original header values.
  • toString() keeps approvalToken and approverId redacted with fixed markers.
  • The exact-head Maven, coverage, security, SAST, and fuzz checks completed successfully.
  • The PR has no review threads.
  • GitHub reports the PR as mergeable and REVIEW_REQUIRED. I did not approve it.

The branch-protection configuration could not be read because the GitHub integration received HTTP 403. No branch or PR content was changed.

⚠️ Action not completed

No files to review.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent review
@coderabbitai review
@cwl-noema-review review
@strix review

Review exact head 293a48ca395d457ae08632b2c94571f9ee958cc2 only. Exact-head CI, Security Scan, SAST Semgrep, and fuzz are terminal-success; unresolved inline findings are zero. Validate replacement of every ISO control character in printable policy-override diagnostics while retaining raw accessor semantics and redaction of approval-token and approver identity.

Review read-only; preserve independent reviewer identity. Do not mutate the branch, synthesize author approval, weaken protection, or merge.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="ContextualWisdomLab/clearfolio"
owner="${repo%%/*}"
name="${repo#*/}"
pr_number="414"
head_sha="293a48ca395d457ae08632b2c94571f9ee958cc2"

echo "== Checked-out commit and requested head =="
git rev-parse HEAD
git status --short
git cat-file -e "${head_sha}^{commit}"

echo "== Live main and ancestry =="
live_main="$(gh api "repos/${repo}/git/ref/heads/main" --jq '.object.sha')"
printf 'live_main=%s\n' "$live_main"
git cat-file -e "${live_main}^{commit}"
git merge-base --is-ancestor "$live_main" "$head_sha" \
  && echo "live_main_is_ancestor=yes" \
  || echo "live_main_is_ancestor=no"

echo "== Exact changed files =="
git diff --name-status "$live_main" "$head_sha"
git diff --no-ext-diff --unified=80 "$live_main" "$head_sha" -- \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java

echo "== Source outlines =="
ast-grep outline src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java --items all --view expanded
ast-grep outline src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java --items all --view expanded

echo "== Relevant source and test contexts =="
rg -n -C 12 --type java \
  '(normalizeHeader|toString\s*\(|getApproval|approvalToken|approverId|PolicyOverrideRequest)' \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java

echo "== Exact-head check runs =="
gh api "repos/${repo}/commits/${head_sha}/check-runs?per_page=100" \
  --jq '[.check_runs[] | {name, status, conclusion}]'

echo "== PR exact refs and review threads =="
gh api graphql \
  -F owner="$owner" -F name="$name" -F number="$pr_number" \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      headRefOid
      baseRefOid
      mergeable
      reviewDecision
      reviewThreads(first: 100) {
        nodes { isResolved isOutdated path line originalLine }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest'

Length of output: 41558


@seonghobae Review complete for exact head 293a48ca395d457ae08632b2c94571f9ee958cc2.

I found no issue in the requested PolicyOverrideRequest diagnostic scope.

  • normalizeHeader() replaces every Java ISO control character with _. This includes ESC, NUL, C0 controls, DEL, and C1 controls.
  • policyOverride(), approvalToken(), and approverId() retain the original raw values.
  • toString() redacts approvalToken and approverId with fixed markers.
  • The added regression verifies ESC and NUL normalization.
  • Exact-head Maven, coverage, security, SAST, and listed fuzz checks succeeded.
  • The PR has zero review threads.

The requested head is not based on current live main. Live main is eb0a32e87e7470469c8fa0f8c67d9583654bef57, and it is not an ancestor of the requested head. The resulting live-main-to-head diff also contains six files, not the stated two-file diagnostic slice. Therefore, I cannot confirm a two-file-only review against current live main.

I did not modify the branch, approve, weaken protection, or merge.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

Exact-current-head independent review request for 293a48ca395d457ae08632b2c94571f9ee958cc2.

The two-file diagnostic-rendering slice is mergeable; CI, Security Scan, SAST Semgrep, and fuzz are terminal-success; unresolved inline findings are zero. Every ISO control character is replaced in the printable policy-override flag while raw accessors remain unchanged and approval credentials/identity stay redacted. Protected main has advanced since construction, so any base update must regenerate all exact-head evidence.

@opencode-agent review
@coderabbitai review
@cwl-noema-review review
@strix review

Review this exact head read-only. Do not mutate the branch, synthesize author approval, weaken protection, or merge.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="ContextualWisdomLab/clearfolio"
owner="${repo%%/*}"
name="${repo#*/}"
pr_number="414"
head_sha="293a48ca395d457ae08632b2c94571f9ee958cc2"

echo "== Local requested commit =="
git rev-parse HEAD
git status --short
git cat-file -e "${head_sha}^{commit}"

echo "== Live main and protection =="
live_main="$(gh api "repos/${repo}/git/ref/heads/main" --jq '.object.sha')"
printf 'live_main=%s\n' "$live_main"
gh api "repos/${repo}/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,enforce_admins,required_linear_history}' \
  || echo "branch_protection_query_unavailable"

echo "== Requested-head relationship to live main =="
git cat-file -e "${live_main}^{commit}"
if git merge-base --is-ancestor "$live_main" "$head_sha"; then
  echo "live_main_is_ancestor=yes"
else
  echo "live_main_is_ancestor=no"
fi
git merge-base "$live_main" "$head_sha"
git diff --name-status "$live_main" "$head_sha"

echo "== Requested-head changes relative to its first parent =="
git diff --name-status "${head_sha}^" "$head_sha"
git diff --no-ext-diff --unified=100 "${head_sha}^" "$head_sha" -- \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java

echo "== Relevant source outlines =="
ast-grep outline src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java --items all --view expanded
ast-grep outline src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java --items all --view expanded

echo "== Relevant source and test context =="
rg -n -C 15 --type java \
  '(normalizeHeader|toString\s*\(|policyOverride\s*\(|approvalToken\s*\(|approverId\s*\(|PolicyOverrideRequest)' \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/test/java/com/clearfolio/viewer/service/PolicyOverrideRequestTest.java

echo "== Exact-head checks =="
gh api "repos/${repo}/commits/${head_sha}/check-runs?per_page=100" \
  --jq '[.check_runs[] | {name,status,conclusion,details_url}]'

echo "== PR references and review threads =="
gh api graphql \
  -F owner="$owner" -F name="$name" -F number="$pr_number" \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      headRefOid
      baseRefOid
      mergeable
      mergeStateStatus
      reviewDecision
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          path
          line
          originalLine
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest'

Length of output: 37352


@seonghobae Review complete for exact head 293a48ca395d457ae08632b2c94571f9ee958cc2.

I found no issue in the requested PolicyOverrideRequest diagnostic-rendering scope.

  • normalizeHeader() replaces every Java ISO control character with _.
  • This includes CR, LF, TAB, ESC, NUL, DEL, and C1 control characters.
  • policyOverride(), approvalToken(), and approverId() retain raw values.
  • toString() uses fixed redaction markers for approvalToken and approverId.
  • The regression coverage includes ESC and NUL.
  • The queried Maven, coverage, security, SAST, and listed fuzz checks completed successfully.
  • The PR has zero review threads.

I cannot confirm this as a two-file-only review against current protected main.

  • Current main is eb0a32e87e7470469c8fa0f8c67d9583654bef57.
  • Current main is not an ancestor of the requested head.
  • The current-main-to-head diff contains six files, including OpenAPI and contract-test changes.
  • GitHub reports mergeable: MERGEABLE, but mergeStateStatus: BLOCKED and reviewDecision: REVIEW_REQUIRED.
  • The GitHub integration returned HTTP 403 when it queried branch protection.

Update the branch onto current main and regenerate the exact-head evidence before a current-base mergeability review. I did not modify the branch, approve the PR, weaken protection, or merge.

⚠️ Action not completed

No files to review.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant