템플릿 인젝션(Template Injection)

Improper Control of Generation of Code ('Code Injection')

설명

템플릿 인젝션(Template Injection)은 애플리케이션이 템플릿 문자열을 동적으로 생성할 때 발생할 수 있는 보안 취약점입니다. 공격자는 악의적인 데이터를 템플릿에 주입하여 임의의 Java 코드 실행, OS 명령어 실행, 데이터 유출 등의 공격을 수행할 수 있습니다.

Velocity, FreeMarker, Pebble과 같은 Java 기반 템플릿 엔진에서 사용자 입력을 직접 템플릿 코드로 사용하지 않도록 주의해야 합니다.

잠재적 영향

  • 임의 코드 실행(RCE, Remote Code Execution): 공격자가 템플릿을 조작하여 서버에서 Java 코드 또는 OS 명령을 실행할 수 있음.

  • 데이터 유출: 공격자가 내부 시스템 정보를 조회하거나 민감한 데이터를 노출시킬 수 있음.

  • XSS 공격: 클라이언트 측 코드(JavaScript)가 삽입되어 브라우저에서 악성 코드가 실행될 가능성이 있음.

해결 방법

  1. 템플릿 엔진의 evaluate 또는 process 메서드에 사용자 입력을 직접 전달하지 않기

    • 템플릿 문자열을 동적으로 생성하는 대신, VelocityContext 또는 Configuration.getTemplate("safeTemplate.ftl")을 사용합니다.

  2. 사용자 입력을 템플릿 코드가 아닌 데이터로 전달

    • Apache Velocity에서는 VelocityContext.put()을 사용하여 데이터 바인딩합니다.

    • FreeMarker에서는 Configuration.getTemplate("safeTemplate.ftl")을 사용하여 정적 템플릿을 로드합니다.

  3. 템플릿 내 사용자 입력을 적절히 이스케이프 처리

    • HTML 컨텍스트에서는 $esc.html($userInput)을 사용하여 HTML 태그를 이스케이프합니다.

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

취약한 코드 (Apache Velocity)

안전한 코드 (Apache Velocity)


취약한 코드 (FreeMarker)

안전한 코드 (FreeMarker)

설명:

  • 취약한 코드:

    • 사용자 입력을 Velocity.evaluate() 또는 Configuration.getTemplate(userInput)에 직접 전달하여 코드 실행 가능.

  • 안전한 코드:

    • VelocityContext.put()을 사용하여 데이터를 바인딩하고, EscapeTool을 활용하여 HTML 이스케이프 적용.

    • FreeMarker에서는 getTemplate("safeTemplate.ftl")을 사용하여 정적 템플릿을 로드하고, 사용자 입력은 데이터 모델로 전달.

참조

Last updated