XPath 인젝션

XPath Injection

설명

XPath 인젝션은 사용자 입력이 문자열 결합, f-string, 포맷팅 등으로 XPath 표현식에 직접 포함될 때 발생합니다. 공격자는 따옴표, 논리 연산자(or/and), 비교식 등을 주입해 의도와 다른 노드를 조회하거나 조건을 무력화할 수 있습니다. 예를 들어 로그인 검증에 사용하는 XPath에 입력을 주입하면 '항상 True' 조건을 만들어 인증을 우회하거나, 임의 경로를 선택해 민감 데이터를 열람할 수 있습니다. lxml과 ElementTree의 xpath/find/findall 계열 함수가 첫 번째 인자로 받는 표현식이 조작 대상이 됩니다.

잠재적 영향

  • 인증 우회: 로그인/권한 체크에 쓰이는 XPath 조건을 '항상 True'으로 만들어 계정 없이 접근할 수 있습니다.

  • 데이터 노출: 임의 노드를 선택하여 이메일, 토큰 등 민감한 정보를 조회할 수 있습니다.

  • 데이터 변조: XPath로 선택된 노드를 기반으로 업데이트/삭제가 이루어지는 경우, 원치 않는 데이터 수정이 발생할 수 있습니다.

  • 서비스 장애(DoS): 매우 복잡한 XPath를 주입하여 CPU를 과도하게 사용하게 만들 수 있습니다.

해결 방법

  • 표현식에 사용자 입력을 직접 연결하지 않습니다. (문자열 결합, f-string, % 포맷 등 금지)

  • lxml 사용 시 변수 바인딩을 활용합니다. 예: tree.xpath("//user[@id=$uid]", uid=value)

  • 숫자형 파라미터는 int로 타입 캐스팅하고, 문자열은 엄격한 허용 목록(정규식)으로 검증합니다. 예: re.fullmatch(r"[a-z0-9_]{1,20}", name)

  • ElementTree 사용 시 XPath 표현식을 상수로 고정하고, 값 비교는 Python 코드 로직으로 수행합니다(표현식 동적 조립 금지).

  • 필요 시 입력을 이스케이프하는 유틸을 사용하지만, 최우선은 변수 바인딩/허용 목록 검증입니다.

  • 애플리케이션 설계 단계에서 사용자에게 임의 XPath를 입력받는 기능을 두지 않습니다.

취약한 코드 및 안전한 코드 예시

취약한 코드

안전한 코드

설명:

  • 취약한 코드: 사용자 입력(u, p)이 따옴표와 논리 연산자를 포함해 그대로 XPath로 들어갑니다. 예를 들어 u에 "alice' or '1'='1"를 넣으면 조건이 항상 참이 되어 인증을 우회할 수 있습니다.

  • 안전한 코드: - 변수 바인딩을 사용해 표현식은 상수로 고정하고, 사용자 입력은 별도 인자로 전달하여 XPath 구문이 변경되지 않습니다.

  • 추가로 사용자명을 정규식으로 검증해 허용된 형식만 통과시키므로, 주입 가능성을 더욱 줄입니다.

참조

Last updated