Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
pasteguard-PoC — PoC — PasteGuard에서 구성된 공급자 API 키의 교차 출처 프록시 악용 (GHSA-q94x-p9rc-q89f, CVE-2026-86998, CVSS 7.6). | Kitploit
도구/GitHubGitHub/squeeze440/pasteguard-poc
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingPapers & ResearchAPI Security
GitHubsqueeze440/pasteguard-poc

pasteguard-PoC

PoC — PasteGuard에서 구성된 공급자 API 키의 교차 출처 프록시 악용 (GHSA-q94x-p9rc-q89f, CVE-2026-86998, CVSS 7.6).

저장소 보기
7일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

PasteGuard: 보안 권고

CVE 상태: 요청됨, 할당 대기 중. 이 발견 사항은 GHSA-q94x-p9rc-q89f로 게시되었습니다. CVE가 할당되면 이 저장소는 CVE-YYYY-NNNNN-pasteguard-PoC로 이름이 변경되고 이 배너는 CVE 링크로 대체됩니다.

연구자Dostxodjayev Abdullox (@squeeze440)
권고GHSA-q94x-p9rc-q89f
CVSS 3.17.6 (높음)
취약점CWE-352, CWE-942

요약: PasteGuard 0.9.1의 LLM 프록시 라우트에 CORS/CSRF 보호가 누락되어 있어, 원격 공격자(운영자의 브라우저가 방문하는 모든 웹사이트 또는 로컬 네트워크의 모든 호스트)가 PasteGuard의 서버 측 폴백 API 키를 사용하여 운영자가 구성한 OpenAI/Anthropic API에 인증된 요청을 트리거하고, /openai/v1/chat/completions(및 이와 유사한 /anthropic/v1/messages)에 대한 교차 출처 fetch()를 통해 응답을 읽을 수 있습니다.

제품: PasteGuard (github.com/sgasser/pasteguard)

테스트된 버전: 커밋 100718191499c52934f3b2ccca72ca16373fb765 (2026-07-30), package.json 버전 0.9.1

추정 CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:H — 7.6 (높음)

  • UI:R — 운영자가 PasteGuard가 실행 중인 동안 브라우저로 페이지(모든 사이트의 모든 페이지)를 열어야 합니다. 다른 상호작용은 필요하지 않습니다.
  • C:L / I:L — 공격자의 자체 JS는 공격자가 선택한 프롬프트에 대한 응답만 읽습니다(운영자의 과거 대화/대시보드 데이터는 CORS에서 올바르게 제외됨). 그러나 이는 여전히 활성 자금이 있는 계정을 확인/사용하고 운영자의 신원으로 계정의 사용량/감사 기록을 오염시킵니다.
  • A:H — 현실적이고 무제한적인 영향: 공격자 페이지가 이 요청을 무한히 반복하여 운영자의 제공자 계정/할당량에 대해 실제 청구되는 사용량을 유발할 수 있습니다(재정적 소진, 속도 제한 소진 또는 제공자 측 남용 플래그 가능성). 이를 막는 속도 제한이나 출처 검사가 없습니다.
  • S:U — 영향은 동일한 신뢰 경계 내에 머뭅니다(프록시 자체의 구성된 자격 증명이 사용됨). 별도의 보안 권한이 침범되지 않습니다.

세부 정보:

PasteGuard의 HTTP 계층은 대시보드를 제외한 모든 라우트에 관대한 와일드카드 CORS 정책을 적용합니다:

  • src/index.ts:40-45 — const corsMiddleware = cors(); (옵션 없는 Hono의 cors()는 기본적으로 Access-Control-Allow-Origin: *로 설정됨)가 app.use("*", ...)를 통해 모든 것에 적용되며, /dashboard와 /dashboard/*에만 명시적으로 예외가 있습니다. 바로 위의 주석(src/index.ts:34-39)은 작성자가 대시보드 CORS 노출에 대해 신중하게 추론했지만 그 아래의 프록시 라우트에는 동일한 추론을 확장하지 않았음을 보여줍니다.
  • src/config.ts:153 — host: z.string().default("0.0.0.0"), config.example.yaml:13에서 실제로 확인됨. 프록시는 기본적으로 루프백뿐만 아니라 모든 인터페이스에서 수신 대기하므로 운영자의 브라우저뿐만 아니라 LAN에서도 접근할 수 있습니다.
  • src/providers/openai/client.ts:48-53:
    root@kitploit:~
    // Use client's auth header if provided, otherwise fall back to config
    if (authHeader) {
      headers.Authorization = authHeader;
    } else if (config.api_key) {
      headers.Authorization = `Bearer ${config.api_key}`;
    }
    
    들어오는 요청에 Authorization 헤더가 없으면 PasteGuard는 자체 서버 보유 providers.openai.api_key를 나가는 요청에 조용히 첨부합니다. config.example.yaml:22-24는 이를 "Apps & APIs" 사용 사례를 위한 의도적인 편의 기능("클라이언트가 인증 헤더를 보내지 않을 경우 선택적 폴백")으로 문서화합니다.
  • src/providers/anthropic/client.ts:37-61은 /anthropic/v1/messages에 대해 동일한 폴백 패턴을 구현합니다(x-api-key/Authorization이 config.api_key로 폴백) — 동일한 근본 원인의 형제 사례로 확인되었으나, 독립적으로 종단 간 재검증되지는 않았습니다(아래 PoC 범위 참조).

와일드카드 CORS 정책이 이 폴백 자격 증명을 보유한 라우트 앞에 위치하기 때문에, 모든 출처가 (1) 브라우저가 Authorization 헤더 없이 요청을 보내도록 하여 서버가 자체 실제 API 키를 첨부하게 하고, (2) Access-Control-Allow-Origin: *가 있으므로 JSON 응답을 읽을 수 있습니다. 이 라우트를 보호하는 Origin/Referer 검사나 CSRF 토큰이 없습니다.

개념 증명 (정적으로 추적한 것뿐만 아니라 동적으로 확인됨):

  1. config.yaml을 providers.openai.base_url: http://127.0.0.1:9091(모의 업스트림) 및 providers.openai.api_key: "sk-VICTIM-SECRET-DO-NOT-LEAK-12345", pii_detection.enabled: false(모의 탐지기 /health만, 전체 GLiNER 모델 서비스를 필요로 하지 않기 위해), secrets_detection.enabled: false로 구성했습니다. bun run src/index.ts로 PasteGuard를 시작하고 /health → 200을 확인했습니다.
  2. 127.0.0.1:9091에서 수신하는 Authorization 헤더를 기록하는 모의 업스트림(mock_upstream.py)을 시작했습니다.
  3. 실제로 다른 출처인 http://127.0.0.2:8001/attack.html(Chrome의 사이트 격리 규칙에 따라 다른 리터럴 루프백 IP — 동일 출처 localhost 테스트가 아님)에서 python3 -m http.server 8001 --bind 127.0.0.2를 통해 실제 공격자 페이지를 제공했습니다. 페이지가 로드 시 수행하는 유일한 동작:
    root@kitploit:~
    fetch("http://127.0.0.1:3000/openai/v1/chat/completions", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ model: "gpt-4o-mini", messages: [{ role: "user", content: "cross-origin drive-by call, attacker supplied NO api key" }] })
    }).then(r => r.json()).then(data => { /* render on page */ });
    
  4. 실제 Chrome 인스턴스(Chrome DevTools Protocol)를 http://127.0.0.2:8001/attack.html로 구동했습니다. DevTools 네트워크 검사를 통해 확인:
    • 요청: origin: http://127.0.0.2:8001, sec-fetch-site: cross-site, 공격자 페이지가 보낸 Authorization 헤더 없음.
    • 응답: access-control-allow-origin: *, HTTP 200, JSON 본문이 공격자 페이지의 JS에 의해 완전히 읽힘.
    • 페이지 렌더링: "CROSS-ORIGIN READ SUCCEEDED. Response body visible to attacker JS: ..." — 스크린샷: ../evidence/cross_origin_csrf_success.png.
    • 해당 정확한 요청에 대한 모의 업스트림 로그: RECEIVED AUTH HEADER: Bearer sk-VICTIM-SECRET-DO-NOT-LEAK-12345 — PasteGuard가 공격자 페이지가 알지도 못하고 제공하지도 않은 운영자의 실제 구성된 키를 서버 측에서 첨부했음을 증명합니다.

원시 증거: ~/engagements/pasteguard/evidence/cross_origin_csrf_success.png, ~/engagements/pasteguard/evidence/mock_upstream_log.txt.

/anthropic/v1/messages 라우트는 동일한 폴백 + 와일드카드 CORS 패턴을 공유하는 것으로 정적으로 확인되었지만(위의 파일:줄), /openai에서 근본 원인이 이미 확인된 후 세션의 깊이 우선/5분 규칙 지침에 따라 라이브 브라우저 PoC를 통해 별도로 재실행되지는 않았습니다.

영향: PasteGuard 운영자의 브라우저가 방문하는 모든 웹사이트(악성 광고, 침해된 사이트 또는 기본 0.0.0.0 바인딩으로 인해 동일 LAN의 공격자)는 운영자의 로컬 PasteGuard 인스턴스를 통해 운영자 자신의 OpenAI/Anthropic 계정으로 무제한 청구 요청을 조용히 유도할 수 있으며, 탭을 열어두는 것 외에 사용자 상호작용이 필요하지 않고 운영자가 제공자 청구 대시보드를 보지 않고는 알아차릴 방법이 없습니다. 이는 직접적인 재정적 남용/할당량 소진 벡터이며, 부차적으로 운영자의 제공자 계정 사용량/감사 기록을 공격자가 선택한 콘텐츠로 오염시킵니다.

취약점:

  • CWE-352: 사이트 간 요청 위조
  • CWE-942: 신뢰할 수 없는 도메인에 대한 관대한 교차 도메인 정책
  • CWE-798: 하드코딩된 자격 증명 사용(서버 측 폴백 키는 자체 인증을 생략하는 모든 호출자가 투명하게 재사용할 수 있음) — 기여 요인으로 나열되며, 주요 취약점은 아님

완화 (제안):

  • 폴백 api_key가 구성된 경우 /openai, /anthropic, /codex(그리고 /api/mask가 서버 보유 자격 증명을 사용하도록 확장되는 경우)에 와일드카드 cors() 미들웨어를 적용하지 마십시오. 최소한 이 라우트에 허용되는 출처를 명시적/구성 가능하게 만들고(예: 브라우저 확장 프로그램의 알려진 출처만), *가 아닌 교차 출처 접근 없음을 기본값으로 설정하십시오.
  • 폴백 키 코드 경로에 특별히 Origin/Referer 검사(또는 합법적인 브라우저 확장 프로그램이 첨부하는 경량 공유 로컬 토큰)를 추가하여 src/index.ts의 /dashboard에 이미 적용된 추론을 반영하십시오.
  • src/config.ts:153 및 config.example.yaml:13에서 server.host 기본값을 0.0.0.0에서 127.0.0.1로 변경하여 모든 인터페이스에 바인딩하려면 명시적 옵트인이 필요하도록 하십시오.

크레딧: Dostxodjayev Abdullox

보고 채널: 저장소에 SECURITY.md가 존재하지 않습니다(gh api repos/sgasser/pasteguard/contents/SECURITY.md → 404로 확인, 감사 시 재확인). 이전에 게시된 보안 권고도 없습니다(gh api repos/sgasser/pasteguard/security-advisories → []). 따라서 이전에 공개된 이슈의 중복으로 보이지 않습니다. 권장 채널: https://github.com/sgasser/pasteguard/security/advisories/new의 GitHub 기본 비공개 취약점 보고 흐름.

도구 다운로드