AngularJS SCE 비활성화

Disabling AngularJS SCE

설명

AngularJS의 SCE(Strict Contextual Escaping)는 신뢰되지 않은 값을 컨텍스트(HTML, URL, CSS, JS 등)에 맞춰 자동으로 이스케이프/정화하여 XSS를 완화합니다. $sceProvider.enabled(false)로 SCE를 전역 비활성화하면 이 보호가 사라져 사용자 입력이나 외부 데이터가 그대로 렌더링되고 스크립트가 실행될 수 있습니다. 공격자는 댓글, 쿼리 스트링, 해시 프래그먼트, API 응답 등에 악성 HTML/JS(예: <img onerror=...>, <script>...)를 주입해 브라우저에서 실행시키는 방식으로 악용합니다. 또한 라이브러리나 공용 모듈에서 SCE를 끄면 애플리케이션 전체가 노출됩니다.

잠재적 영향

  • XSS에 의한 임의 스크립트 실행(Arbitrary JavaScript Execution): 사용자가 본 문서 컨텍스트에서 악성 스크립트를 실행하여 UI 조작, 추가 공격을 수행할 수 있음

  • 세션 탈취(Session Hijacking): 쿠키/토큰을 탈취해 사용자 계정을 가로챌 수 있음

  • 민감정보 유출(Data Exfiltration): 페이지 내 표시되거나 접근 가능한 데이터(개인정보, CSRF 토큰 등)를 외부로 전송 가능

  • 페이지 변조 및 피싱(Defacement/Phishing): DOM을 조작해 가짜 입력폼, 결제창을 띄워 사용자 기만

  • 추가 공격으로의 발판(Defense Bypass/CSRF Chain): SCE 비활성화로 출력 정화가 무력화되어 다른 방어(입력 검증, CSP 등)와 결합해 더 큰 피해 유발

해결 방법

  • $sceProvider.enabled(false)를 사용하지 않습니다. 기본값(SCE 활성화)을 유지합니다.

  • 동적 HTML이 꼭 필요하면 다음 중 하나를 적용합니다:

    • ng-bind(텍스트 바인딩) 사용으로 HTML 해석을 차단합니다.

    • ngSanitize 모듈의 $sanitize로 정화한 뒤, 꼭 필요한 경우에만 $sce.trustAsHtml(cleanHtml)로 한정 신뢰합니다.

  • 사용자 생성 컨텐츠(댓글, 소개글 등)는 서버/클라이언트 모두에서 허용 목록 기반의 정화(whitelist sanitization) 수행 후 저장/표시합니다.

  • 템플릿에서 ng-bind-html 사용 시 입력 출처를 제한하고, 신뢰 경로만 바인딩합니다.

  • 서드파티 스크립트/모듈이 SCE를 끄지 않는지 코드 리뷰와 정적 분석(SAST)으로 점검합니다.

  • CSP(Content-Security-Policy)를 적용해 인라인 스크립트와 임의 스크립트 로딩을 제한하여 피해 범위를 축소합니다.

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

취약한 코드

안전한 코드

설명:

  • 취약한 코드: $sceProvider.enabled(false)로 SCE를 전역 비활성화하면 AngularJS가 컨텍스트별 이스케이프/정화를 수행하지 않습니다. 그 결과, 사용자 입력이 ng-bind-html 등으로 렌더링될 때 같은 페이로드가 스크립트로 실행되어 XSS가 발생합니다. 라이브러리 수준에서 비활성화하면 애플리케이션 전역이 동시에 노출됩니다.

  • 안전한 코드: SCE 기본값을 유지해 신뢰되지 않은 값을 자동으로 정화/차단합니다. 기본은 텍스트 바인딩(ng-bind)으로 HTML 해석을 막고, 동적 HTML이 필요한 경우에만 $sanitize로 정화한 뒤 $sce.trustAsHtml로 한정 신뢰하여 공격 표면을 최소화합니다. 이렇게 하면 악성 스크립트가 실행되지 않습니다.

참조

Last updated