Skip to content

fix: adr-required 换行文件名绕过截断检测——jq 结构化计数(ADR-0016) - #54

Merged
randypanding merged 1 commit into
mainfrom
newline-filename-hardening
Aug 19, 2026
Merged

fix: adr-required 换行文件名绕过截断检测——jq 结构化计数(ADR-0016)#54
randypanding merged 1 commit into
mainfrom
newline-filename-hardening

Conversation

@randypanding

Copy link
Copy Markdown
Contributor

背景

qodo 在 agent-registry #22 的 review 中发现:Git 允许文件名含换行符,grep -c . 行流计数会把单个含换行的文件名算成多行——GOT 被虚增到 == changed_files 后,3000 文件截断的 fail-closed 检测失效,藏在截断边界后的 C1 文件不再触发报错。本仓 gate.yml(#53 引入)与 CI-Workflows ci.yml(#8 引入)为同款实现,存在同款绕过。

修复

计数与 C1 匹配全部改为逐页 jq 按 JSON 对象处理:

  • 计数:jq 'length'(数组对象数,不受文件名内容影响)
  • C1 匹配:jq any(test(...))(按 JSON 值匹配正则,含 previous_filename
  • 逐页拉取(per_page=100 循环到短页),任一页非数组即 fail-closed

三仓同步:agent-registry #22(qodo 首发发现)/ 本 PR / CI-Workflows follow-up。

ADR: ADR-0016

Git 允许文件名含换行——行流计数(grep -c)可被单文件多行虚增 GOT,
使 3000 截断 fail-closed 失效。改为逐页 jq 按 JSON 对象计数(length)
与 C1 匹配(test 正则),文件名中的换行不影响任何一层判定。
与 agent-registry #22(首发发现)三仓同步。
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@randypanding, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

Limit details: You’ve used all 3 included reviews currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4c8fc6bf-972a-4b38-accf-ae576d21a9f1

📥 Commits

Reviewing files that changed from the base of the PR and between f6fb8d8 and 1ea9baa.

📒 Files selected for processing (1)
  • .github/workflows/gate.yml

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

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Harden ADR gate against newline filenames

🐞 Bug fix ⚙️ Configuration changes 🕐 Less than 10 minutes

Grey Divider

AI Description

• Counts files as JSON objects, preventing newline filenames from inflating totals.
• Scans current and previous paths per page for governed-file changes.
• Fails closed on malformed pages or GitHub’s 3,000-file truncation.
Diagram

graph TD
  A["Files API Page"] --> B{"JSON Array?"}
  B -- "Yes" --> C["jq Object Scan"]
  C -- "Full Page" --> A
  C -- "Short Page" --> D{"List Complete?"}
  B -- "No" --> H["Fail Closed"]
  D -- "No" --> H
  D -- "Yes" --> E{"C1 Path?"}
  E -- "No" --> G["Skip Gate"]
  E -- "Yes" --> F["ADR Check"]
Loading
High-Level Assessment

The per-page structured JSON approach is appropriate because filenames never enter line-oriented shell processing, page response types are validated, and large responses are not accumulated in memory. NUL-delimited shell streams or aggregated gh api --paginate output were considered, but they add serialization complexity without improving the fail-closed guarantees.

Files changed (1) +25 / -12

Bug fix (1) +25 / -12
gate.ymlProcess ADR gate file lists as paginated JSON objects +25/-12

Process ADR gate file lists as paginated JSON objects

• Replaces line-based filename counting and matching with per-page jq object processing, including renamed files through 'previous_filename'. The gate now validates each response as an array and fails closed when the accumulated count reveals GitHub’s file-list truncation.

.github/workflows/gate.yml

@randypanding
randypanding merged commit 670df89 into main Aug 19, 2026
6 checks passed
@randypanding
randypanding deleted the newline-filename-hardening branch August 19, 2026 04:27
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. gh api uses workflow token 📘 Rule violation ⛨ Security
Description
The added paginated GitHub API call inherits GH_TOKEN from ${{ github.token }} rather than
obtaining a single-repository cloudbrid-agent token through scripts/gh-app-token.sh. This violates
the mandated identity and token-scoping mechanism for CI GitHub operations.
Code

.github/workflows/gate.yml[84]

+            PAGEJSON=$(gh api "$PR_API/files?per_page=100&page=$PAGE")
Relevance

●●● Strong

Repository history accepts strict token identity and scoping fixes for CI workflows and GitHub API
operations.

PR-#19

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2778539 requires CI GitHub API operations to authenticate exclusively through
scripts/gh-app-token.sh using a single-repository token. The workflow sets GH_TOKEN to `${{
github.token }} at line 68, and the newly added gh api` call at line 84 therefore uses that
generic workflow token without invoking the required script.

Rule 2778539: Agent operations must use the cloudbrid-agent GitHub App identity via scripts/gh-app-token.sh with single-repo tokens
.github/workflows/gate.yml[67-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added `gh api` pagination call authenticates with the workflow-provided GitHub token instead of the required cloudbrid-agent GitHub App identity.

## Issue Context
Obtain the token by invoking `scripts/gh-app-token.sh`, set `REPO` to the specific repository, and expose its output to `gh` as `GH_TOKEN`. Preserve fail-closed behavior if token acquisition fails.

## Fix Focus Areas
- .github/workflows/gate.yml[67-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 7 rules
✅ Web pages:
  +2 more
Review mode: ⚖️ Balanced: This changes CI gate behavior for truncation detection and C1 path authorization, with pagination, jq semantics, and fail-closed handling that warrant a careful full review; it is substantial but localized rather than dense enough for extended.

Grey Divider

Tip of the day
💡 Did you know, you can show, collapse, or hide each part of a finding: code, evidence, and all

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

C1_HIT=0
PAGE=1
while :; do
PAGEJSON=$(gh api "$PR_API/files?per_page=100&page=$PAGE")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. gh api uses workflow token 📘 Rule violation ⛨ Security

The added paginated GitHub API call inherits GH_TOKEN from ${{ github.token }} rather than
obtaining a single-repository cloudbrid-agent token through scripts/gh-app-token.sh. This violates
the mandated identity and token-scoping mechanism for CI GitHub operations.
Agent Prompt
## Issue description
The added `gh api` pagination call authenticates with the workflow-provided GitHub token instead of the required cloudbrid-agent GitHub App identity.

## Issue Context
Obtain the token by invoking `scripts/gh-app-token.sh`, set `REPO` to the specific repository, and expose its output to `gh` as `GH_TOKEN`. Preserve fail-closed behavior if token acquisition fails.

## Fix Focus Areas
- .github/workflows/gate.yml[67-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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