← 04 TRACE무엇을 남겼는가
복구하려다 토큰을 파괴했다
키체인이 hex를 내놓아 디코딩해 다시 저장했다. security의 대화형 프롬프트가 128자에서 자르고 원본은 덮어써졌다.
401이 났다. 응답 본문이 비어 있어서 원인을 알 수 없었다.
키체인 값을 형태만 떠보니 접두사가 41544였다.
41 54 41 54 54 = A T A T T
hex로 저장돼 있었다. security find-generic-password -w는 저장된 값에
개행이 섞이면 평문 대신 hex를 출력한다.
복구가 파괴였다
디코딩해서 다시 저장했다. security의 대화형 프롬프트를 썼다.
그 프롬프트는 128자에서 자른다. 192자 토큰이 128자가 되고 원본은 덮어써졌다. 재발급하게 만들었다.
나중에 재봤다.
| 저장 방식 | 200자 입력 → 조회 결과 |
|---|---|
-w 뒤에 값 없이 (대화형 프롬프트) | 128자 |
-w '<VALUE>' 인자로 전달 | 200자 |
앞서 다른 문서에 "대화형 프롬프트가 값을 argv에 남기지 않으니 안전하다,
권장한다"고 적어 뒀었다. 그 조언은 이 한도를 확인하지 않은 것이었다.
안전한 쪽을 골랐는데 그 방법이 데이터를 조용히 잘랐다.
진짜 원인은 진단 도구가 없었던 것
설정 오류가 평범한 401로만 보였다. 응답 본문이 비어 있으니 hex 접두사를 직접 뜯어보는 데까지 갔고, 거기서 잘못된 복구를 시도했다.
그래서 bb_doctor를 만들었다. 겪은 함정 네 개 — 스코프 없는 토큰, 128자
절단, 개행으로 인한 hex, 빈 allowlist — 를 전부 감지하고 실행할 명령을
준다.
### hex 토큰 → ok=false, 문제 4건
✖ 토큰 형태: hex로 인코딩돼 보입니다 (386자)
fix: security add-generic-password -U -s bb-api-token -a "$USER" -w '<TOKEN>'
✖ 인증: 401 — 자격증명이 거부됐습니다
스코프 목록은 /user가 403일 때 응답 본문의 granted 배열에서 뽑는다.
비어 있는 본문으로 추측하는 대신 서버가 이미 말해 준 것을 읽는다.
토큰 값은 어떤 형태로도 출력하지 않는다. 접두사조차 담지 않고 boolean으로만
판정한다 — 테스트가 응답에 ATATT 문자열조차 없는지 검사한다.
남는 것
토큰을 키체인에 넣을 때 값이 잠시 argv에 노출되는 것은 피할 수 없다.
대화형 프롬프트가 그 노출을 없애 주지만 128자에서 자르고, 이 토큰은
190자가 넘는다. 대안이 없어서 노출되는 쪽을 택하고 그 사실을 적어 뒀다.
복구 절차를 처음 쓰는 순간이 가장 위험하다. 원본을 덮어쓰는 명령이라면 특히 그렇다.