주요 내용
- Angular는 기본적으로 보간된 콘텐츠를 이스케이프 처리하고, 템플릿 바인딩 내의 신뢰할 수 없는 HTML 및 URL 값을 정제하며, CSRF 보호의 클라이언트 측 처리를 담당하지만, 완전한 보호를 위해서는 서버 측에서 토큰을 발급하고 유효성을 검증해야 합니다.
- XSS, CSRF, 인증 취약점, 패치되지 않은 종속성은 Angular 애플리케이션에 가장 빈번하게 영향을 미치는 위험 요소이며, 이들 중 대부분은 프레임워크의 기본 보호 기능을 벗어나서 발생합니다.
- 타사 스크립트에 적용되는 콘텐츠 보안 정책(CSP), 신뢰할 수 있는 유형(Trusted Types), 서브리소스 무결성(SRI)은 Angular가 파악할 수 없는 공격 표면을 차단합니다.
- Angular 19 이하 버전은 지원 종료 기간이 지났으며 더 이상 공식 보안 패치를 제공받지 못합니다. 아직 마이그레이션을 진행하지 못한 팀은 보안 보호를 지속하기 위한 계획을 수립해야 합니다.
Angular 애플리케이션은 은 프레임워크 자체의 취약점 때문에 해킹당하는 경우가 거의 없습니다. 해킹당하는 이유는 개발자가 bypassSecurityTrustHtml 메서드를 사용하여 타사 위젯이 올바르게 렌더링되도록 하고, 해당 값에 대해 Angular의 XSS 보호 기능을 비활성화했기 때문입니다. 또는 백엔드에서 XSRF 토큰을 전혀 검증하지 않았기 때문일 수도 있습니다. 혹은 3단계 아래에 있는 의존성 라이브러리가 2년 동안 패치를 받지 못했기 때문일 수도 있습니다. 이것이 바로 대부분의 Angular 보안 문제 뒤에 숨겨진 패턴입니다. 프레임워크 자체는 견고하지만, 임시 해결책과 관련 구성은 그렇지 않은 것입니다.
이 가이드에서는 프레임워크가 자동으로 보호하는 부분과 팀이 수동으로 적용해야 하는 부분 간의 격차를 해소하는 Angular 보안 모범 사례를 다룹니다.
Angular의 보안 처리 방식
Angular 애플리케이션을 보안 조치하기 전에, Angular가 이미 어떤 기능을 제공해 주는지 알아두면 도움이 됩니다. 알고 보니 꽤 많은 기능을 제공하더군요.
기본적으로 Angular는 모든 값을 신뢰할 수 없는 것으로 간주합니다. 보간이나 템플릿 바인딩을 통해 DOM에 값이 삽입되면, Angular는 해당 값을 이스케이프 처리하거나 정제합니다. 보간된 콘텐츠는 항상 이스케이프 처리되므로 {{ }} 는 마크업을 파싱하지 않고 가시적인 텍스트로 렌더링합니다. 속성 바인딩은 컨텍스트에 따른 정화 처리를 거치며, 그 규칙은 컨텍스트에 따라 달라집니다. Angular는 네 가지 보안 컨텍스트 – HTML, 스타일, URL, 리소스 URL –을 정의하고, 신뢰할 수 없는 HTML 및 URL 값을 정화합니다. 리소스 URL은 정의상 코드를 로드하고 실행하므로 정화할 수 없으며, 따라서 Angular는 이를 명시적으로 신뢰할 수 있는 것으로 표시하지 않는 한 바인딩을 거부합니다. 이러한 동작은 대부분의 단순한 XSS 시도를 차단합니다.
또한 Angular는 CLI 애플리케이션에서 기본적으로 템플릿을 미리 컴파일하므로, 템플릿 주입과 관련된 버그 유형을 제거해 주며, 그 HttpClient 는 클라이언트 측 XSRF 토큰 처리 기능과 XSSI 응답 접두사 자동 제거 기능을 기본으로 제공합니다.
이러한 보호 기능은 해당 범위 내에 머무르는 동안에만 적용됩니다. 다음을 통해 DOM에 직접 쓰기를 수행하십시오. ElementRef를 통해 DOM에 직접 쓰기를 하거나, 바인딩에 우회된 값을 전달하거나, 서버가 XSRF 유효성 검사를 건너뛰도록 허용하면 이러한 보장은 더 이상 적용되지 않습니다. 아래 섹션에서는 Angular가 자동으로 메워주지 않는 보안 취약점에 대해 다룹니다.
| 현실 점검: “Angular는 기본적으로 안전하다”는 말은 반만 맞는 말입니다. Angular는 템플릿 출력을 이스케이프 처리하고 정제하며, CSRF 및 XSSI에 대한 클라이언트 측 헬퍼를 제공하지만, 유출된 토큰, 취약한 npm 패키지, 취약한 인증 방식, 또는 공개된 CVE에 노출된 지원 종료(EOL) 버전 등에 대해서는 아무런 조치를 취하지 않습니다. 이 프레임워크는 클라이언트 측 렌더링 및 HTTP 계층의 특정 부분만을 보호할 뿐, 애플리케이션 전체를 보호하지는 않습니다. |
Angular에서 흔히 발생하는 보안 취약점
다음은 다소 불편한 사실입니다. Angular 애플리케이션의 취약점 대부분은 Angular 자체의 결함이 아닙니다. 이는 개발자가 프레임워크의 보호 범위를 벗어난 부분으로, 대개 기능을 더 빨리 출시하기 위해 그렇게 했으나 그에 상응하는 안전 장치를 다시 마련하지 않은 경우입니다.
| 취약성 | Angular에서 어떻게 발생하는가 | Angular가 다루는 영역과 다루지 않는 영역 |
| XSS | 다음으로 ‘안전’으로 표시된 신뢰할 수 없는 데이터 bypassSecurityTrust*로 '안전'으로 표시되었거나, ElementRef 또는 element.innerHTML | 문맥 기반 정화는 템플릿 바인딩에 적용되며, DOM에 직접 쓰기 작업에는 적용되지 않습니다. |
| CSRF | 서버는 XSRF 토큰을 설정하거나 유효성 검사를 수행하지 않습니다. | HttpClient 토큰을 전송하며, 서버는 이를 발급하고 검증해야 합니다 |
| 취약한 종속성 | 구버전 npm 패키지 또는 지원 종료된 Angular 버전 | 업스트림 패치는 지원 종료 시점에 중단됩니다 |
| 접근 제어 오류 | 서버 측 인증이 누락되었거나 일관성이 없음; 경로 가드가 없거나 잘못 구성됨 | 클라이언트 측 가드는 서버 측 접근 제어를 강제할 수 없습니다. |
| 제3자 스크립트 삽입 | SRI 또는 CSP 제어 없이 로드된 외부 스크립트 | Angular는 타사 코드를 샌드박스 처리하지 않습니다 |
크로스 사이트 스크립팅(XSS)
XSS는 Angular의 보안 모델이 가장 명확하게 방지하도록 설계된 취약점입니다. 신뢰할 수 없는 콘텐츠를 DOM에 주입하는 방식이 매우 확실하게 악용되기 때문에 전체 sanitization 시스템이 존재하는 것이며, 바로 이 때문에 개발자들이 우회 방법을 모색할 때 실수로 가장 자주 비활성화해 버리는 보호 기능이기도 합니다.
다음 ‘2024 시노프시스 오픈소스 보안 및 위험 분석 보고서’는 1,000개 이상의 상용 코드베이스를 분석한 결과, 상위 10개 오픈소스 취약점 중 8개가 CWE-707에 해당한다는 사실을 밝혀냈습니다. CWE-707은 크로스사이트 스크립팅(XSS)을 포함하여 신뢰할 수 없는 입력을 안전하지 않게 처리함으로써 발생하는 취약점을 포괄하는 광범위한 ‘부적절한 중화(improper neutralization)’ 범주에 속합니다. 부적절한 입력 처리는 극히 드문 사례가 아니라, 오픈소스 생태계 전반에 걸쳐 심각한 취약점을 유발하는 가장 확실한 원인 중 하나입니다.
Angular 애플리케이션에서 XSS는 대개 다음 세 가지 중 하나에서 기인합니다: DomSanitizer.bypassSecurityTrustHtml() 호출, 상류 단계에서 잘못 신뢰 대상으로 표시된 콘텐츠, 또는 ElementRef, 네이티브 브라우저 API, 또는 Angular의 통제 범위를 벗어난 타사 라이브러리를 통해 DOM에 직접 쓰기를 수행하는 코드입니다. 단순한 [innerHTML] 바인딩은 반대로 안전성 검증을 거칩니다.
해결 방법은 복잡하지 않습니다. 신뢰할 수 없는 데이터를 바이패스를 통해 전달하지 말고, 외부에서 제공된 HTML을 반드시 렌더링해야 하는 경우에는 템플릿에 도달하기 전에 잘 관리된 살균기를 통해 정제하십시오. 모든 bypassSecurityTrust* 호출을 다시 한 번 꼼꼼히 살펴볼 가치가 있는 문제로 간주하십시오.
| 주의하세요: 모든 bypassSecurityTrust* 메서드는 이름 그대로, 해당 값에 대해 Angular의 sanitization을 비활성화합니다. DomSanitizer.sanitize() 는 이미 신뢰할 수 있는 것으로 표시된 값을 정제하지 않으므로, bypass 메서드를 sanitize 호출로 감싸는 것은 아무런 이득이 없습니다. 공격자가 접근할 수 있는 필드에 이 중 하나만 있어도 저장형 XSS 취약점이 발생하기에 충분합니다. 매 릴리스 전에 이를 찾아내십시오. |
크로스사이트 요청 위조(CSRF)
Angular에서 CSRF는 대개 코드 버그가 아니라 설정상의 문제입니다. 기본적으로, HttpClient 는 XSRF-TOKEN 쿠키를 읽어와 이를 X-XSRF-TOKEN 헤더로 다시 전송합니다. 단, GET 또는 HEAD 요청이나 크로스 오리진 요청에는 이 헤더를 추가하지 않습니다. 클라이언트 측 처리는 이미 완료되었습니다.
문제는 나머지 절반에 있습니다. Angular는 해당 쿠키를 설정하거나 반환된 토큰의 유효성을 확인해 줄 수 없습니다. 백엔드가 쿠키를 발행하지 않거나 헤더가 누락된 요청을 허용한다면, 이 보안 조치는 형식적인 것에 불과합니다. Angular의 공식 문서에서도 이 점을 분명히 밝히고 있습니다. 서버를 제대로 구성하지 않으면 기본 보안 기능이 무력화된다는 것입니다. 이는 단일 페이지 애플리케이션에서 가장 흔히 발생하는 문제 중 하나입니다. 즉, 서버 측에서 확인을 하지 않는데도 프론트엔드만 보안을 적용한 것처럼 보이는 경우입니다.
취약점이 있거나 구버전인 종속성
이것이 가장 큰 숨겨진 문제점이며, 팀들이 가장 오랫동안 간과하는 부분입니다. 앱 코드는 깔끔할지 몰라도, node_modules 트리 구조는 여러분이 직접 관리하는 것이 아니며, 그 안에 포함되는 요소 중 상당 부분은 간접적이거나 전달 의존성 로 유입되며, 팀원 중 누구도 이를 선택하지 않았습니다.
The '2026 블랙덕 오픈소스 보안 및 위험 분석 보고서'는 17개 산업 분야의 상용 코드베이스 947개를 감사한 결과, 대부분의 팀이 이미 감지하고 있지만 거의 조치를 취하지 않는 문제들을 수치로 제시합니다. 해당 코드베이스 중 93%는 최소 2년 동안 개발 활동이 없는 구성 요소를 포함하고 있었으며, 92%는 최신 릴리스보다 10개 이상의 버전이 뒤처진 구성 요소를 사용하고 있었고, 최신 버전을 사용하는 구성 요소는 7%에 불과했습니다. 코드베이스당 평균 취약점 수는 전년 대비 두 배 이상 증가하여 581건에 달했습니다. jQuery에 대한 조사 결과는 특히 시사하는 바가 큽니다. 감사 대상 코드베이스에서 가장 흔한 CVE 10개 중 4개는 수년 전에 패치된 jQuery 취약점이었으며, 코드베이스의 25%에서 28%는 여전히 그중 적어도 하나를 포함하고 있었습니다.
두 가지 시계가 돌아가고 있습니다. 첫 번째는 npm 의존성 트리인데, 이 트리는 사용자가 건드리지 않더라도 CVE가 누적됩니다. 두 번째는 Angular 자체입니다.
Angular는 버전 22부터 릴리스 주기를 변경했습니다. 이제 메이저 버전은 매년 출시되며 일반적으로 24개월 동안 지원됩니다: 12개월의 활성 지원 기간에 이어 12개월의 LTS(장기 지원) 기간이 이어지며, 이 기간에는 중대한 수정 사항과 보안 패치만 제공됩니다. 버전 21까지의 모든 릴리스는 기존의 6개월 주기와 18개월 지원 기간(6개월 활성 지원, 이후 12개월 LTS)을 따랐습니다. 어느 쪽이든 지원은 종료됩니다.
| Angular 버전 | 현황 (2026년 8월) | 적극적인 지원 종료 | 보안 지원(LTS) 종료 |
| 22 | 활성 | 6월 2027 | 6월 2028 |
| 21 | LTS | 2026년 6월 3일 종료 | 6월 2027 |
| 20 | LTS | 2025년 11월 19일에 종료됨 | 11월 28, 2026 |
| 19세 이하 | Lifecycle 종료 | - | 공식 패치 없음 |
일정은 Angular가 공개한 지원 일정을 따르며, 이는 팀이 대략적인 지침으로 제공하는 것으로 향후 변경될 수 있습니다.
EOL 버전을 사용하게 되면 더 이상 업스트림의 정기적인 보안 수정 사항의 적용 대상이 아니므로, 프레임워크나 해당 소스 트리에 영향을 미치는 새로운 CVE는 업그레이드하거나 공급업체의 지원을 받지 않는 한 패치되지 않은 상태로 남게 됩니다. 이에 대한 대처 방안은 나중에 다시 다루겠습니다.
개발 팀을 위한 Angular 보안 모범 사례
1. 손 소독제를 믿고, 더 이상 건너뛰지 마세요
가장 가치 있는 습관은 Angular의 sanitization 기능을 켜두는 것입니다. 기본값으로 보간(interpolation)과 속성 바인딩(property binding)을 사용하면, 이 기능들이 자동으로 이스케이프 처리와 sanitization을 수행합니다. 일반적인 [innerHTML] 바인딩은 살균 처리가 이루어지므로 그 자체로는 안전하지 않은 것은 아닙니다. 하지만 실제로 마크업을 렌더링해야 할 때에만 사용하고, 공격자가 제어하는 콘텐츠나 우회 기법과 절대 결합하지 마십시오.
외부에서 제공된 HTML을 반드시 렌더링해야 하는 경우, 위협 모델에 적합한 관리가 잘 된 HTML 세정 도구를 사용하여 이를 정제해야 하며, 다음 사항을 명심하십시오. DomSanitizer.sanitize() 는 이미 bypassSecurityTrust* 호출로 이미 감싸진 값은 정화하지 못한다는 점을 명심하십시오. 우회 호출을 검토 가능하게 만드십시오: 모든 우회 호출을 표시하는 린트 규칙이나 CI grep을 사용하면 사람이 그 정당성을 입증하도록 강제할 수 있습니다. 보안 감사에서 공격자가 접근 가능한 데이터에 대한 우회 사례가 발견되면, 이를 백로그 항목이 아닌 릴리스 차단 사유로 취급하십시오.
| 전문가 팁: 코드베이스에서 bypassSecurityTrust 를 검색해 보세요. 만약 해당 표현을 발견했는데, 왜 그 특정 값이 안전한지 한 문장으로 설명할 수 없다면, 아마도 안전하지 않은 것입니다. |
2. 콘텐츠 보안 정책(CSP) 추가하기
콘텐츠 보안 정책(CSP)은 sanitization을 뚫고 들어오는 XSS에 대한 두 번째 방어선입니다. CSP는 브라우저가 허용할 출처와 실행 패턴을 제한하므로, 정책을 충족하지 않는 삽입된 스크립트는 실행되지 않습니다. 실제로 얼마나 많이 차단되는지는 작성한 정책에 따라 달라집니다: 광범위한 출처, ‘unsafe-inline’, 또는 허용적인 스크립트 로딩 패턴을 설정하면 많은 부분이 통과하게 됩니다.
Angular은 새로운 애플리케이션에 대한 최소 정책에 대해 다음과 같이 설명하고 있습니다:
| Content-Security-Policy: default-src ‘self’; style-src ‘self’ ‘nonce-randomNonceGoesHere’;
script-src ‘self’ ‘nonce-randomNonceGoesHere’; |
The nonce matters. Angular inserts <style> elements at runtime, and a strict policy without a nonce will block them and break your styling. Generate a fresh, unpredictable nonce for every response and hand it to Angular in one of three supported ways: set autoCsp to true in your workspace configuration, set the ngCspNonce attribute on the root application element, or provide it through the CSP_NONCE injection token. Serve the policy as a response header from your web server or CDN, not as a meta tag. If your HTML is cached at a CDN, generate the nonce at the edge – a nonce baked into a cached response is the same value for every visitor, which defeats the point.
CSP를 Trusted Types와 함께 사용하십시오. Angular는 이 두 가지를 모두 실행할 것을 강력히 권장합니다. 이는 둘 다 DOM 수준에서 작동하기 때문에, 하위 수준의 브라우저 API를 통해 우회될 수 없기 때문입니다. 다음 중 어느 것을 호출하는 애플리케이션은 bypassSecurityTrust* 메서드를 호출하는 애플리케이션은 angular#unsafe-bypass 정책이 필요하며, 지연 로드되는 청크를 사용하는 애플리케이션에는 angular#bundler가 필요합니다.
| 전문가 팁: 먼저 다음 설정을 사용하여 CSP를 '보고 전용' 모드로 적용해 보세요. Content-Security-Policy-Report-Only를 사용하여 CSP를 '보고 전용' 모드로 먼저 적용해 보세요. 앱의 정상 작동을 방해하지 않으면서 위반 보고서를 받을 수 있으므로, 정책을 적용하기 전에 모든 인라인 스크립트, 삽입된 스타일, 타사 출처를 파악할 수 있습니다. 이 단계를 건너뛰는 팀은 거의 예외 없이 프로덕션 환경에서 문제를 일으킵니다. |
3. XSRF/CSRF 보호 기능을 종단 간으로 구성하기
Angular의 클라이언트 측 XSRF 처리가 전부는 아니라고 생각해서는 안 됩니다. Angular는 토큰을 전송할 뿐이며, 서버 측에서 토큰을 발급하고 검증해야 합니다.
동일 출처 API: 백엔드에서 XSRF-TOKEN 쿠키를 세션별로 설정하고, 헤더가 누락되었거나 일치하지 않는 모든 유효한 요청을 거부하도록 설정되어 있는지 확인하십시오. 백엔드에서 다른 이름을 사용하는 경우, withXsrfConfiguration() 를 사용하여 구성하십시오.
크로스 오리진 API: Angular는 크로스 오리진 요청에 헤더를 추가하지 않으므로, 기본 쿠키 기반 방식은 적용되지 않습니다. 쿠키 속성, 자격 증명 처리, CORS 구성에 명시된 신뢰할 수 있는 오리진 목록, 서버 측 토큰 또는 오리진 유효성 검사 등 양쪽 끝점에서 신중하게 보호 체계를 설계해야 합니다. CORS만으로는 CSRF 방어 수단이 될 수 없습니다.
이 경로에 대해 실제로 침투 테스트를 해볼 가치가 있습니다. 웹 스캐너는 명백한 CSRF 취약점을 포착하겠지만, 일부 경로에서는 쿠키가 올바르게 설정되어 있음에도 불구하고 유효성 검사가 은밀하게 생략되는 경우가 쉽게 발생할 수 있습니다.
4. 경로 보호 및 승인 잠금
Angular의 라우터는 매우 강력하지만, 바로 그 때문에 이곳에서 발생하는 권한 관련 오류가 막대한 대가를 치르게 됩니다. 물론 팀들이 예상하는 방식대로만 대가를 치르는 것은 아닙니다. Angular는 접근 제어를 강제하지 않으며, 이는 전적으로 개발자와 백엔드 측의 책임입니다.
가드(guard)가 누락되면 URL을 아는 사람이라면 누구나 클라이언트 측 뷰와 탐색 경로를 볼 수 있게 됩니다. 이러한 뷰 뒤에 있는 API에서도 권한 확인이 제대로 이루어지지 않을 경우, 이는 데이터 유출로 이어집니다. 이 두 가지 요소 모두 중요하며, 그중 하나만이 Angular의 문제입니다.
다음과 같은 몇 가지 사항을 제대로 파악해야 합니다:
- 보호된 경로에는 반드시 가드가 필요하며, 권한이 없는 섹션으로 연결되는 링크가 UI에 표시되지 않는다고만 믿어서는 안 됩니다. 최신 Angular는 함수형 가드를 사용합니다 – CanActivateFn 를 내비게이션에, canMatch 를 사용합니다.
- 가드는 서버에서 파생된 인증 또는 권한 상태를 참조할 수는 있지만, API에 대한 권한 확인을 대체해서는 절대 안 됩니다. localStorage 에 있는 플래그는 어떤 사용자라도 수정할 수 있으므로, 이는 접근 제어 수단이 아닙니다.
- 사용 canMatch 를 사용하면 라우터가 권한이 없는 사용자에 대해서는 해당 경로 구성을 매칭하거나 로드하지 않습니다.
- 가드 조건을 명시적으로 테스트하세요. 다음과 같이 반환 값이 true를 반환하는 를 반환하는 경우가 흔합니다.
| 주의: 지연 로딩이 개인정보 보호를 보장하는 것은 아닙니다. 라우트 가드는 브라우저에서 실행되며 탐색을 제어할 뿐, 공개적으로 제공되는 자바스크립트 번들을 누군가가 직접 가져오거나 개발자 도구(DevTools)에서 읽어보는 것을 막을 수는 없습니다. 지연 로딩 여부와 관계없이 클라이언트 측 코드에는 비밀 정보, 비공개 엔드포인트 또는 민감한 인증 로직을 절대 포함하지 말고, 보호 대상인 모든 백엔드 요청에 대해 인증을 엄격히 적용하십시오. |
5. 제3자 스크립트를 위협 표면으로 간주하기
분석 도구, 채팅 위젯, A/B 테스트 도구, 광고 네트워크 등 로드하는 모든 타사 스크립트는 사용자 자신의 코드와 동일한 권한으로 실행됩니다. Angular의 세정 기능은 템플릿을 보호하지만, 템플릿 외부에서 로드되는 스크립트에 대해서는 샌드박스 처리를 하지 않습니다.
이는 이론적인 문제가 아니라 실질적인 문제입니다. 2025년 9월, 한 npm 유지보수자의 계정을 대상으로 한 피싱 공격으로 인해 다음과 같은 널리 사용되는 18개의 패키지에 악성 코드가 유입되었습니다. chalk 와 debug를 포함한 18개의 널리 사용되는 패키지에 악성 코드가 유입되었습니다. 이 패키지들은 합쳐서 주간 다운로드 수가를 포함해 널리 사용되는 18개 패키지에 악성 코드가 유입되었으며, 이 패키지들의 주간 다운로드 수는 총 수십억 건에 달합니다. 며칠 후, 자가 복제형 웜인 ‘Shai-Hulud’가 개발자 인증 정보를 탈취하고 레지스트리 전반으로 확산되었습니다. GitHub은 해킹당한 패키지 500개 이상을 제거했으며, CISA는 경보를 발령했습니다. 2026년 OSSRA는 이러한 패턴을 구체화합니다. 블랙 덕(Black Duck)이 오픈소스 생태계 전반에서 식별한 악성 패키지 중 66%는 타이포스쿼팅(typosquatting)이나 의존성 혼동과 같은 전술을 통해 피해를 입히기 위해 특별히 제작된 것이었으며, 34%는 커뮤니티의 신뢰를 얻은 후 탈취당한 합법적인 패키지였습니다.
구현해 볼 만한 몇 가지 제어 기능:
- SRI(Subresource Integrity)는 내용이 안정적이고 버전이 지정된 외부 호스팅 스크립트의 해시 값을 확인합니다. 가져온 파일이 선언된 해시 값과 일치하지 않으면 브라우저는 해당 파일의 실행을 거부합니다. 또한 SRI가 정상적으로 작동하려면 호스트 측에서 적절한 CORS 구성이 필요합니다.
- CSP 규칙에서 허용하는 대신 제3자 출처를 명시적으로 허용 목록에 포함시키는 경우 * 또는 ‘unsafe-inline’를 허용하는 대신, 제3자 오리진을 명시적으로 허용하는 CSP 규칙입니다.
- 프로덕션 환경에 어떤 제3자 스크립트가 로드되는지 정기적으로 감사해야 합니다. 마케팅 및 분석 도구는 시간이 지남에 따라 점점 늘어나며, 종종 자체적인 하위 종속성을 불러오기도 합니다.
- 가능한 경우, 타사 라이브러리의 자체 호스팅 및 고정된 사본을 사용하십시오. 이렇게 하면 신뢰 체인에서 CDN이 제외되지만, 패치 적용 책임이 귀사 팀으로 넘어가게 되므로, 업스트림 수정 사항을 추적하는 프로세스와 함께 운영해야 합니다.
6. Angular 및 관련 종속 라이브러리에 대한 패치를 꾸준히 적용하세요
패치 작업은 팀들이 마이그레이션이 될 때까지 미루는 관행입니다. 다음 명령을 실행하세요. CI에서 를 CI에서 실행하고, 당장 해결 방법이 없다는 이유로 경고를 무시하지 말고 발견된 항목을 실제로 분류해 보십시오. 이를 완전한 평가가 아닌 하나의 참고 자료로 취급하십시오. 이 도구는 매니페스트와 락파일에 선언된 패키지에 대한 알려진 권고 사항을 보고할 뿐이며, 2026년 OSSRA 보고서에 따르면 오픈소스 구성 요소의 17%가 표준 패키지 관리자를 전혀 거치지 않고 코드베이스에 유입되는 것으로 나타났습니다(복사-붙여넣기된 스니펫, 벤더링된 코드, AI 생성 코드 등). 이러한 경우 매니페스트 기반 스캐너는 이를 전혀 감지하지 못합니다.
같은 보고서는 2025년 블랙덕(Black Duck)이 실시한 별도의 설문조사 결과를 인용했는데, 이에 따르면 응답 기관의 65%가 소프트웨어 공급망 공격 를 경험했다고 답했습니다. 이 수치는 깊이 생각해 볼 가치가 있습니다. 공급망 공격은 더 이상 극히 드문 위험이 아니라, 기업 전반에 걸친 주요 문제가 되었습니다. 감사 대상 코드베이스 중 87%는 적어도 하나의 알려진 오픈소스 취약점을 포함하고 있었으며, 78%는 적어도 하나의 고위험 취약점을 포함하고 있었습니다.
| npm audit
ng update @angular/core @angular/cli |
Angular를 지원되는 릴리스 기간 내에 유지하고, Dependabot이나 Renovate를 통해 종속성 관련 pull request를 자동화하며, 직접적인 수정 사항이 없더라도 전이적 CVE를 심각하게 받아들여야 합니다. 취약점은 종속성 트리에서 여러 계층 아래에서도 악용될 수 있으므로, 간접적이라는 이유로 무시하기보다는 애플리케이션이 실제로 해당 취약한 코드에 도달하는지 여부를 평가해야 합니다.
이 문제의 더 어려운 측면은 업그레이드가 불가능할 때 어떤 상황이 벌어지는지입니다. 메이저 버전으로의 마이그레이션에는 막대한 비용이 들 수 있고, 앱은 안정적이며, 재작성에 대한 사업적 타당성을 입증하기 어렵습니다. 바로 그 지점에서 EOL(지원 종료)의 격차가 발생합니다.
Angular 보안을 위한 도구 및 솔루션
Angular의 보안을 확보하는 것은 일회성 작업이 아닙니다. 지속적인 패치 적용, 취약점 모니터링, 그리고 지원 범위를 확보하는 과정입니다. 대부분의 팀은 이를 처리하기 위해 하나 이상의 도구가 필요합니다.
| 해결책 | 다루는 내용 | 가장 적합한 |
| Snyk / Dependabot / npm 감사 | 매니페스트 및 락파일에서 선언된 종속성에 영향을 미치는 알려진 보안 권고 사항 (직접적 및 전이적) | 현재 활발히 릴리스 중인 팀, CI 통합 완료 |
| CSP, 신뢰할 수 있는 유형, ZAP | 실행 시 XSS 보안 강화 및 애플리케이션 계층 스캔 | 보안에 중점을 둔 팀들이 운영 환경의 보안을 강화하고 있다 |
| OSS를 위한 TuxCare의 무한 라이프사이클 지원(ELS) | 지원 종료(EOL)된 Angular(버전 4~19) 및 해당 지원 종속 라이브러리를 위한 백포트 패치로, npm을 통해 제공됩니다. | 지원되지 않는 버전에 묶여 있어, 강제적인 재작성 없이도 감사에 대비할 수 있는 소프트웨어가 필요한 팀들 |
의존성 스캐너 (Snyk, Dependabot, npm audit)
소프트웨어 구성 분석(SCA) 도구는 의존성 트리를 모니터링하여, 직접 설치한 적이 없는 패키지에 포함된 알려진 CVE를 표시해 줍니다. Snyk와 GitHub의 Dependabot은 모두 이 기능을 훌륭하게 수행하며, npm audit 는 npm에 무료로 포함되어 제공됩니다. Snyk는 광범위한 상용 취약점 데이터베이스를 유지하고 있으며, Dependabot의 자동화된 PR(pull request) 기능은 최신 상태를 유지하는 데 드는 번거로움을 줄여줍니다. 코드 병합 전에 CI에 CVE 탐지 기능을 통합하고자 하는 활발한 개발 팀에 가장 적합합니다.
실행 시 보안 강화
의존성 스캐너는 패키지의 알려진 문제를 탐지합니다. 하지만 자체 코드에서 누락된 콘텐츠 보안 정책(CSP)이나 악용될 수 있는 DOM 쓰기 취약점은 탐지하지 못합니다. 오픈소스인 Zed Attack Proxy(이전 명칭 OWASP ZAP, 현재 Checkmarx에서 ZAP으로 유지 관리 중)를 포함한 동적 애플리케이션 보안 테스트(DAST) 도구는 실행 중인 애플리케이션을 대상으로 인젝션 결함, 취약한 헤더, CSRF 취약점 등을 테스트합니다. 단순히 패키지를 감사하는 것보다, 운영 중인 애플리케이션을 강화하려는 보안에 민감한 팀에 가장 적합합니다.
Angular를 위한 TuxCare의 무제한 라이프사이클 지원
해결하기 가장 어려운 문제는 EOL(지원 종료) 관련 문제입니다. 사용 중인 Angular 버전에 더 이상 수정 패치가 제공되지 않고, 마이그레이션도 당분간 이루어지지 않을 경우, 스캐너는 공식 채널을 통해 패치할 수 없는 문제들을 계속해서 지적하게 될 것입니다.
최신 Angular도 이 문제를 해결해 주지는 않으며, 단지 시한을 미루는 것뿐입니다. 모든 주요 릴리스는 결국 지원이 종료되며, 일단 지원이 종료되면 더 이상 업스트림의 정기적인 보안 패치를 받을 수 없게 됩니다. TuxCare는 지원이 종료된 프레임워크 버전과 해당 프레임워크가 포함하는 종속성들에 보안 패치를 역포트합니다.
Angular 버전 4부터 19까지는 모두 2026년 중반을 기점으로 지원 종료 2026년 중반을 기점으로 지원이 종료됩니다. 귀사의 팀에서 해당 버전 중 하나를 사용 중이며 단기간 내에 업그레이드가 어려운 경우, TuxCare의 ‘Angular용 Endless Lifecycle Support’ 는 귀사 팀이 이미 사용하고 있는 패키지 관리자인 npm을 통해 지속적인 보안 패치를 제공합니다. 지원 범위에는 앱이 의존하는 핵심 Angular 패키지인 @angular/core, @angular/platform-browser, @angular/common, @angular/router, @angular/forms, @angular/cli, @angular/compiler, @angular/compiler-cli, 그리고 @angular/platform-browser-dynamic – 및 이들이 지원하는 종속성을 추가 비용 없이 제공합니다.
실질적인 이점은 분명합니다. 보안 감사를 통과하기 위해 서둘러 마이그레이션을 진행할 필요 없이, 본인의 일정에 맞춰 업그레이드를 계획하는 동안에도 계속해서 보장을 받을 수 있습니다.
TuxCare로 Angular 보안 강화하기
Angular는 탄탄한 출발점을 제공하지만, 클라이언트 측 애플리케이션의 특정 부분만 보호합니다. 나머지는 개발팀의 몫입니다. 즉, 데이터 정화 관행, CSP 및 Trusted Types, 양쪽 끝단에서의 XSRF 구성, 서버 측 검증을 기반으로 한 라우트 인증, 타사 스크립트 제어, 그리고 종속성 패치 등이 포함됩니다.
대부분의 팀이 과소평가하는 부분은 바로 Angular 버전의 지원 종료 공식 수정 사항이 중단된 후 일어나는 일입니다. 바로 그 간극이 TuxCare의 ‘Endless Lifecycle Support’ 가 메우기 위해 마련된 바로 그 공백입니다
TuxCare는 Angular뿐만 아니라 그 이상의 영역을 지원합니다. React, Vue, AngularJS, jQuery, Next.js, Express 등 다른 자바스크립트 프레임워크나 라이브러리의 지원되지 않는 버전이 스택에 포함되어 있더라도, TuxCare는 이에 대한 지원도 제공합니다. 현재 지원 범위는 다음에서 확인하실 수 있습니다. 라이브러리 및 프레임워크에 대한 끝없는 라이프사이클 지원에서 현재 지원 범위를 확인해 보세요.
자주 묻는 질문
대체로 그렇습니다. Angular는 보간된 콘텐츠를 이스케이프 처리하고, 템플릿 바인딩 내의 신뢰할 수 없는 HTML 및 URL 값을 정제하며, 기본적으로 클라이언트 측 XSRF 및 XSSI 헬퍼를 제공합니다. 하지만 인증 정보 유출, 취약한 종속성, 서버 측 인증 누락, 또는 개발자가 정제 과정을 우회하는 경우로부터는 보호할 수 없습니다.
프로젝트 디렉터리에서 `ng version` 명령어를 실행하세요. 이 명령어는 Angular CLI, 핵심 프레임워크 및 주요 패키지의 버전을 표시하므로, 현재 버전이 지원되는 릴리스 기간 내에 있는지 확인할 수 있습니다.
자동으로 발생하는 것은 아니지만, 시간이 지날수록 위험은 커집니다. EOL(지원 종료) 버전은 더 이상 정기적인 보안 패치를 받을 수 없기 때문에, 프레임워크나 그 의존성 트리에 영향을 미치는 새로운 CVE는 사용자가 업그레이드하거나 공급업체의 지원을 받기 전까지 업스트림에서 수정되지 않은 상태로 남아 있습니다. 해당 버전을 계속 사용할수록, 사용 중인 버전에 영향을 미치는 새로 공개된 취약점이 패치되지 않은 채로 남을 가능성이 커집니다.
XSS는 가장 흔한 웹 애플리케이션 취약점 유형 중 하나이며, Angular 애플리케이션의 경우 대개 sanitization이 우회되거나, 콘텐츠가 신뢰할 수 있는 것으로 잘못 표시되거나, 프레임워크를 완전히 우회하는 직접적인 DOM 조작에서 기인합니다.
Angular의 HttpClient는 클라이언트 측 작업을 처리합니다. 즉, XSRF-TOKEN 쿠키를 읽어와 동일 출처 요청에서 상태가 변경될 때 이를 헤더로 첨부합니다. 완전한 CSRF 보호를 위해서는 서버 측에서도 세션마다 해당 쿠키를 발급하고, 상태가 변경되는 모든 적격 요청에 대해 헤더를 검증해야 합니다. Angular는 서버 측 작업을 대신 수행할 수 없습니다.
두 가지 선택지는 지원되는 버전으로 마이그레이션하거나 공급업체가 제공하는 보안 패치를 적용하는 것입니다. 단기간 내에 마이그레이션이 어려울 경우, TuxCare의 ‘Angular용 Endless Lifecycle Support’는 버전 마이그레이션 없이도 npm을 통해 제공되는 백포트된 보안 수정 사항을 통해 Angular 4부터 19 버전까지를 지원합니다.




