flawopen.com/AI Security/semantic-kernel-inmemory-vector-filter-cve-2026-26030
Semantic Kernel CVE-2026-26030: 필터 코드 인젝션
프롬프트 영향을 받은 벡터 필터가 AST 검사를 우회해 Python eval에 도달했습니다. SDK 1.39.4 이상으로 업데이트하세요.[1], [4]
💡 알기 쉬운 설명 (ELI5)
검색 규칙 카드에서 익숙한 단어를 확인한 사서가 컴퓨터에 카드 전체를 작은 프로그램처럼 실행하라고 하는 장면을 떠올려 보세요. 카드에 영향을 줄 수 있는 사람은 검사의 빈틈을 이용할 수 있습니다. CVE-2026-26030은 모델 영향을 받은 필터가 데이터 검색에서 애플리케이션 프로세스 내부 코드 실행으로 넘어가게 했습니다.[4]
핵심 개념 및 용어
InMemoryVectorStore- Semantic Kernel 프로세스 내 벡터 저장소이며 검색 전에 레코드를 필터링할 수 있습니다.[4]
Filter expression- 레코드가 벡터 검색 결과에 포함될지 정하는 조건식입니다. 취약한 Python 경로는 문자열 필터를 Python 표현식으로 파싱하고 평가했습니다.[4]
Prompt injection- 신뢰할 수 없는 텍스트가 AI 모델에 영향을 주어 의도하지 않은 작업을 유도합니다. 애플리케이션이 모델 입력을 취약한 필터에 전달할 때 위험합니다.[4]
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-94
단계별 공격 실행 흐름
소스 코드 비교: 취약한 구현 vs 보안 패치
취약 코드 패널은 제품의 원본 코드가 아닌 대표 패턴입니다. 모델 제어 값이 eval 전에 Python 구문에 삽입됩니다. 수정 패널은 업스트림 1.39.4 검사를 발췌합니다. 구성된 AST 허용 목록은 레코드 필드 접근을 위해 ast.Subscript를 의도적으로 포함하며, 위험 속성 차단, 단독 이름을 lambda 매개변수로 제한하는 검사, 허용된 함수 호출 확인을 함께 적용합니다. builtins를 제거해도 eval은 샌드박스가 아닙니다. 패키지를 업데이트하고 이 발췌를 독립 검증기로 복사하지 마세요.[2], [6], [4]
취약한 구현
# 수정 전 대표 패턴: 모델 제어 텍스트가 표현식을 바꿉니다.
filter_text = f"lambda x: x.city == '{model_selected_city}'"
tree = ast.parse(filter_text, mode="eval")
code = compile(tree, filename="<filter>", mode="eval")
filter_fn = eval(code, {"__builtins__": {}}, {}) # nosec
보안 강화 패치
def validate_filter(self, tree):
# 업스트림 1.39.4 핵심 검사이며 예외 메시지는 줄였습니다.
# 최상위 필터는 lambda 식이어야 합니다.
if not (isinstance(tree, ast.Expression) and isinstance(tree.body, ast.Lambda)):
raise VectorStoreOperationException("Filter must be a lambda expression")
lambda_param_names = {arg.arg for arg in tree.body.args.args}
for node in ast.walk(tree):
if type(node) not in self.allowed_filter_ast_nodes:
raise VectorStoreOperationException("AST node type is not allowed")
if isinstance(node, ast.Attribute) and node.attr in self.blocked_filter_attributes:
raise VectorStoreOperationException("Dangerous attribute is not allowed")
if isinstance(node, ast.Name) and node.id not in lambda_param_names:
raise VectorStoreOperationException("Only lambda parameter names are allowed")
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name):
func_name = node.func.id
elif isinstance(node.func, ast.Attribute):
func_name = node.func.attr
else:
func_name = None
if func_name and func_name not in self.allowed_filter_functions:
raise VectorStoreOperationException("Function is not allowed")
code = compile(tree, filename="<filter>", mode="eval")
func = eval(code, {"__builtins__": {}}, {}) # nosec
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓semantic-kernel이 포함된 Python 환경을 모두 찾아 컨테이너, 노트북, worker, CI 이미지 버전을 기록합니다.[4]
- ✓1.39.4 이상으로 올리고 lockfile과 이미지를 다시 만듭니다.[1], [3]
- ✓업데이트 전까지 프로덕션에서 InMemoryVectorStore 필터를 끕니다.[1]
- ✓벡터 검색 필터를 추가하거나 변경하는 모든 PR에 사용자 텍스트, 검색 문서, 모델 제공 인수가 파싱된 필터 구조를 바꾸지 못함을 입증하는 테스트를 추가하고 지원하지 않는 형식은 거부합니다.[4]
- ✓실행 페이로드 없이 위험 AST 속성과 lambda 외 이름을 거부하는 회귀 테스트를 추가합니다.[2]
- ✓모델이 선택한 필터를 허용 필드와 연산자를 명시한 타입 지정 데이터로 표현하고, 표현식 문자열 및 알 수 없는 필드나 연산자를 거부하는 테스트를 추가합니다.
- ✓에이전트의 파일, 네트워크, 자격 증명 권한을 최소화합니다.[4]
- ✓에이전트 호스트 탐지 회귀 테스트를 추가해 대표적인 자식 프로세스 및 아웃바운드 연결 이벤트를 발생시키고, 배포된 텔레메트리 규칙이 두 이벤트 모두에 경고하는지 확인합니다.[4]