AntFleet

Anatomy · 44bd7a66-0

Security policy can be bypassed by placing sensitive files in subdirectories (anchored patterns only match repo root)

highsecurityclosed in 97d3766
repo 56f59a0d·PR #1·reviewed 2 months ago·closed 3 weeks ago

The vulnerable code

src/security-policy.ts:16-27

16const BLOCKED_PATTERNS: RegExp[] = [
17 /^\.env(?:\.|$)/i,
18 /^\.npmrc$/i,
19 /^\.git(?:\/|$)/i,
20 /^\.ssh(?:\/|$)/i,
21 /(?:^|\/)id_rsa$/i,
22 /(?:^|\/)id_ed25519$/i,
23 /\.(?:pem|key|p12|pfx)$/i,
24 /(?:^|\/)wallet\.dat$/i,
25 /(?:^|\/)seed(?:s|_phrase)?\.txt$/i,
26 /(?:^|\/)secrets?(?:\.|\/|$)/i,
27];

The reasoning

Opus

BLOCKED_PATTERNS misses common secret-bearing files (e.g., .env without suffix variants, credentials.json, .aws/, .kube/, gcloud)

mediumsecurityhigh
  • src/security-policy.ts:17-27
Block patterns are anchored to root (e.g., /^\.env/) so a nested `packages/foo/.env` is NOT blocked — it is classified as 'safe'. The CONFIRM patterns have the same root-anchoring bias. This is inconsistent with the secret scanner (src/ci/secrets.ts) which scans by content but the policy gate is the one that prevents the agent from writing to those paths in the first place. Net effect: agent can freely create/modify `apps/web/.env` or `packages/x/.npmrc` without confirmation. Also missing: ~/.aws/credentials, .kube/config, gcp service-account.json, .pypirc, .netrc, id_ecdsa.

Recommendation

Change root-anchored patterns to allow path prefix (e.g., /(?:^|\/)\.env(?:\.|$)/i), and add patterns for .aws/, .kube/, .netrc, .pypirc, id_ecdsa, gcloud credentials JSON.

GPT-5

Security policy can be bypassed by placing sensitive files in subdirectories (anchored patterns only match repo root)

highsecurityhigh
  • src/security-policy.ts:16-27
  • src/security-policy.ts:29-42
  • src/security-policy.ts:44-50
  • src/security-policy.ts:56-64
The regexes for .env, .npmrc, .git, .ssh, Dockerfile, scripts/, etc. are anchored to the start of the path. This only flags files at the repository root. Sensitive files under subdirectories (e.g., apps/api/.env or packages/foo/.npmrc or services/web/Dockerfile) will not match and will be misclassified as safe, allowing high-impact or sensitive writes to proceed without block/confirmation.

Recommendation

Update patterns to match anywhere in the path using a non-capturing prefix boundary. For example: - .env: use /(?:^|\/)\.env(?:\.|$)/i - .npmrc: use /(?:^|\/)\.npmrc$/i - .git: use /(?:^|\/)\.git(?:\/|$)/i - .ssh: use /(?:^|\/)\.ssh(?:\/|$)/i - Dockerfile: use /(?:^|\/)Dockerfile$/i - scripts/: use /(?:^|\/)scripts\//i - Similarly adjust Makefile, justfile, .husky/, .vscode/tasks.json to use (?:^|\/). Add unit tests for classifyActionRisk and touchesCommandSurface to cover subdirectory paths (e.g., packages/app/.env, packages/service/Dockerfile).

The agreement

Both frontier models flagged this within the same line range. AntFleet's unanimous gate fired — the finding posted on the PR. Closed in 97d3766.

The fix

16export interface PolicyReview {
17 approved: FileAction[];
18 blocked: Array<{ action: FileAction; verdict: ActionRiskVerdict }>;
19 needsConfirmation: Array<{ action: FileAction; verdict: ActionRiskVerdict }>;
20}
21
22const BLOCKED_PATTERNS: RegExp[] = [
23 /(?:^|\/)\.env(?:\.|$)/i,
24 /(?:^|\/)\.npmrc$/i,
25 /(?:^|\/)\.git(?:\/|$)/i,
26 /(?:^|\/)\.ssh(?:\/|$)/i,
27 /(?:^|\/)id_rsa$/i,

Closure

Closed 3 weeks ago

SHA: 97d37662a07d471f599610fd8762cb0ce175d385

View closure receipt on GitHub →

Tweet thread template

tweet 1 of 8202 / 280

Two frontier models reviewed PR #1 on 56f59a0d. Both found this bug: high security: Security policy can be bypassed by placing sensitive files in subdirectories (anchored patterns only match repo root)

tweet 2 of 8114 / 280

The vulnerable code (src/security-policy.ts:16-27): (full snippet at https://www.antfleet.dev/anatomy/44bd7a66-0)

tweet 3 of 8280 / 280

What Opus saw: "Block patterns are anchored to root (e.g., /^\.env/) so a nested `packages/foo/.env` is NOT blocked — it is classified as 'safe'. The CONFIRM patterns have the same root-anchoring bias. This is inconsistent with the secret scanner (src/ci/secrets.ts) which scans…

tweet 4 of 8280 / 280

What GPT-5 saw: "The regexes for .env, .npmrc, .git, .ssh, Dockerfile, scripts/, etc. are anchored to the start of the path. This only flags files at the repository root. Sensitive files under subdirectories (e.g., apps/api/.env or packages/foo/.npmrc or services/web/Dockerfile…

tweet 5 of 897 / 280

Both flagged the same line range. AntFleet's unanimous gate fired — the finding posted on the PR.

tweet 6 of 893 / 280

The fix landed in commit 97d3766: (view diff at https://www.antfleet.dev/anatomy/44bd7a66-0)

tweet 7 of 881 / 280

AntFleet reviews every PR with two frontier models. Only unanimous findings post.

tweet 8 of 877 / 280

Full anatomy + reasoning + diffs: https://www.antfleet.dev/anatomy/44bd7a66-0

Paste into X composer one tweet at a time. X has no multi-tweet intent API.