Skip to content

v0.2.23 — 붙여 쓴 프롬프트도 프롬프트다 (A24·A25)

Latest

Choose a tag to compare

@xzawed xzawed released this 06 Sep 11:13
· 4 commits to main since this release
8ea1cf3

v0.2.23 — 붙여 쓴 프롬프트도 프롬프트다 (전체 코드 감사 A24·A25)

2026-09-06. 릴리스된 산출물과 소스 전체(19모듈 3,930줄)를 Grok과 함께 검증한 결과다.
채점 대상은 사용자가 실제로 실행하는 것이었다 — 태그 v0.2.22distorigin/main
dist가 바이트 동일함을 먼저 확인했으므로, 캐시 번들 채점이 곧 릴리스 채점이다.

두 결함 모두 배포 번들에서 재현한 뒤 고쳤고, 같은 페이로드로 다시 쟀다.


A24 — 인증 게이트를 통과하고 이력에도 남지 않는 유료 턴

-p는 값을 붙여서도 받는다. clap은 -p2+2-p 2+2와 똑같이 읽는다. 그런데 이 래퍼의
짧은 플래그 판정은 /^-[A-Za-z][A-Za-z]+$/토큰 전체가 알파벳이어야 했다. 그건 붙인 값이
우연히 알파벳일 때만 참이므로, 숫자·슬래시·점을 포함한 값은 기록기와 인증 게이트 양쪽에서
동시에 사라졌다.

grok_cli에는 서버 측 checkAuth가 없다 — hook.ts가 스스로 적어둔 대로 PreToolUse hook이
유일한 게이트
다. 그 게이트가 열려 있었다.

실측 (배포 번들 + 배포 dist/hook.js):

확인 수정 전 수정 후
hook, 로그아웃 · ["-p","2+2"] deny deny
hook, 로그아웃 · ["-p2+2"] allow deny
hook, 로그아웃 · ["-p/tmp/x"] · ["-pfoo.txt"] allow deny
hook · ["sessions","list"] · ["--version"] · ["-wq","name"] allow allow (유지)
번들 · ["-p2+2","--output-format","json"] status: ok, grok이 text:"**4**" · stopReason: end_turn · 실제 sessionId — 유료 턴 동일하게 성공
그 턴의 promptRun / 이력 부재 / 행 없음 (2→2) true / 행 기록 (promptPreview: "2+2")

즉 A2가 고친 피해(위임이 /grok:usage·/grok:status에서 사라짐)가 다른 문으로 재발
있었고, 이번에는 인증 게이트까지 함께 열려 있었다.

수정: 판정 대상을 "토큰 전체"에서 **"앞쪽 옵션 문자열"**로 바꿨다. 붙인 값은 옵션이 아니므로
판정에서 제외되고(-s01a0p619p는 데이터다), -p=VALUE도 clap과 같게 읽는다.

Grok의 몫: 게이트 구멍을 독립적으로 먼저 찾았다 — 실제 코드를 주고 반증을 시켰더니
-p0, -p/tmp/x, -pfoo.txtGAP_FOUND를 돌려줬다. 수정 후 다시 검토시켰을 때는 누락을
하나도 찾지 못했고
, 대신 -mp(= --model p)를 과잉 게이트라고 지적했다. 그건 기각했다 —
실측 결과 수정 전후가 동일하고(옛 규칙도 true), 모듈 주석과 기존 테스트가 이미 명시한
의도적 정책이다("과잉 게이트는 로그인한 사용자에게 비용이 없지만, 누락은 검사 없이 쿼터를 태운다").

A25 — cwd를 안 넘긴 grok_cli 이력이 cwd: ""로 기록

runGrokCli는 생략된 cwd를 process.cwd()로 채우는데, 이력을 쓰는 호출부는 그걸 알 수 없어
cwd ?? ''를 적었다. 같은 디렉터리에서 돈 위임 2건 중 1건만 그 디렉터리로 집계됐다.

질의 수정 전 수정 후
전체 2건 (recent[].cwd = ["D:/…", ""]) 2건, 둘 다 실제 경로
그 디렉터리로 필터 1건 2건

A17이 읽는 쪽에서 고친 문제를 쓰는 쪽에서 만들고 있었던 셈이다.

수정: 호출부에서 기본값을 다시 유도하지 않는다 — 실행이 자기가 쓴 디렉터리를 보고한다
(GrokCliResult.cwd, 필수 필드). 호출부에 cwd ?? process.cwd()를 적는 대안은 기각했다:
A7이 정확히 그것(하나의 기본값을 두 곳에서 유도하다 어긋남) 때문에 생겼다.

Grok 판정은 이 수정안에 FIX_SOUND였고, 유일한 공격(cwd:""을 넘기면 여전히 "")은
실측으로 반증했다 — 빈 문자열은 spawn 전에 거부되고 이력 행도 남지 않는다.


결함이 아닌 것 (감사가 확인하고 넘어간 것)

  • 레닥션은 사람이 외우는 비밀번호를 못 가린다 (password = Password1!, 12자 하한).
    Grok이 LEAK_FOUND를 냈으나 4건 중 2건은 검토용 발췌본이 실제 키 목록보다 짧아서 생긴
    오탐이었고(실제 코드는 OPENAI_API_KEY·GH_TOKEN 모두 마스킹), 남은 2건은
    CLAUDE.md 절대 원칙 4와 docs/04가 이미 **"마스킹은 완화이지 보장이 아니다"**로 명시한
    설계상 한계다. 하한을 낮추면 A6 라운드에서 Grok이 잡았던 과교정(45개 중 19개 훼손)이 그대로
    돌아온다.
  • 표면 일치: 도구 9개 전부 등록·전부 additionalProperties: false, 커맨드 27·스킬 2·
    에이전트 1이 참조하는 도구 이름 9개가 모두 실재, hooks/hooks.json 래핑 정상,
    accept-release 10/10.

유닛

572 → 578. 수치는 npm test가 원천이다.