AntFleet

Anatomy · 44bd7a66-0

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

highsecurity
repo 56f59a0d·PR #1·reviewed 4 days ago

The vulnerable code

src/security-policy.ts:16-27

Code snippet unavailable.

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.

Closure

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 pending: (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.