Home 차량용 사이버보안 블로그
차량용 사이버보안

외부 라이브러리 무결성 검증을 위한 SRI 해시값 생성 및 보안 적용 원리

2026년 3월 4일
악성 코드가 컴퓨터 스크립트를 변조하는 사이버 공격 상황을 배경으로, 균열이 간 CDN 서버 아이콘에서 경고 신호가 발산되는 위험한 디지털 보안 사고를 묘사한 이미지입니다.

증상 진단: 스크립트 변조 및 CDN 공격 위험성

웹사이트에 jQuery, Bootstrap, Google Fonts 등 외부 CDN(Content Delivery Network)에서 호스팅되는 자바스크립트나 CSS 라이브러리를 로드하고 계십니까? 만약 그렇다면, 현재 귀하의 웹사이트는 “공급망 공격(Supply Chain Attack)”에 노출된 상태일 수 있습니다. 이와 같은 cDN 서버가 해킹되거나, 라이브러리 파일이 악의적으로 변조되어 사용자 브라우저에 배포될 경우, XSS(Cross-Site Scripting) 공격, 데이터 유출, 암호화폐 채굴 스크립트 주입 등 심각한 보안 사고로 이어집니다. 이는 방화벽이나 WAF(Web Application Firewall)만으로는 완벽히 차단할 수 없는 취약점입니다. 중요한 점은 sRI(Subresource Integrity)는 이러한 무결성 문제를 해결하기 위한 최종 보루 역할을 합니다.

원인 분석: 정적 리소스의 신뢰 체인 붕괴

전통적인 웹 개발에서는 성능 최적화를 위해 널리 알려진 라이브러리를 공용 CDN에서 로드해 왔습니다. 이 방식의 근본적 취약점은 “신뢰”에 기반한다는 점입니다. 개발자는 해당 CDN 제공자가 항상 정상적이고 변조되지 않은 파일을 서빙할 것이라고 믿어야 합니다. 하지만 이 신뢰 체인은 여러 단계에서 깨질 수 있습니다. 첫째, CDN 운영사 자체의 보안 사고. 둘째, 라이브러리 개발자 계정 탈취로 인한 악성 코드가 포함된 버전 배포. 셋째, 중간자 공격(Man-in-the-Middle)을 통한 네트워크 구간에서의 파일 변조. SRI는 암호학적 해시 함수를 이용해 이 신뢰 체인을 “검증 가능한 사실”로 대체합니다. 브라우저가 파일을 다운로드한 후, 개발자가 미리 제공한 해시값과 실제 파일의 해시값을 비교하여 일치하지 않으면 파일 실행을 차단합니다.

악성 코드가 컴퓨터 스크립트를 변조하는 사이버 공격 상황을 배경으로, 균열이 간 CDN 서버 아이콘에서 경고 신호가 발산되는 위험한 디지털 보안 사고를 묘사한 이미지입니다.

해결 방법 1: SRI 해시값 생성 및 기본 적용

SRI를 적용하기 위한 첫 단계는 사용하려는 정적 리소스 파일의 무결성 해시값을 생성하는 것입니다. 이 해시값은 파일 내용이 단 한 바이트라도 변경되면 완전히 달라지므로, 변조 탐지의 핵심 지표가 됩니다.

해시값 생성 실습 (OpenSSL 또는 터미널 사용)

대부분의 Unix 기반 시스템(Linux, macOS)과 Windows의 WSL(Windows Subsystem for Linux)에서는 OpenSSL 명령어를 통해 쉽게 해시를 생성할 수 있습니다. 아래는 가장 일반적으로 사용되는 SHA-384 알고리즘을 기준으로 한 생성 방법입니다.

  1. 먼저, 적용할 라이브러리 파일을 로컬에 다운로드합니다. CDN에서 제공하는 URL이 아닌, 공식 출처(GitHub 릴리스 페이지 등)에서 직접 다운로드 받는 것이 안전합니다.
  2. 터미널(또는 명령 프롬프트)을 열고 해당 파일이 있는 디렉토리로 이동합니다.
  3. 다음 명령어를 실행하여 SHA-384 해시를 Base64 형식으로 인코딩된 값을 생성합니다, openssl dgst -sha384 -binary [파일명.js] | openssl base64 -a
    실제로, `jquery-3.6.0.min.js` 파일의 해시를 생성하려면:
    openssl dgst -sha384 -binary jquery-3.6.0.min.js | openssl base64 -a
  4. 명령어 실행 후 터미널에 출력된 긴 문자열(예: `verylogo…`)이 바로 필요한 sri 해시값입니다. 이 값을 복사합니다.

온라인 생성 도구를 선호하는 경우, [srihash.org](https://www.srihash.org/)와 같은 신뢰할 수 있는 사이트를 이용할 수 있으나, 보안 상의 이유로 민감한 파일은 로컬에서 생성하는 것이 원칙입니다.

HTML 스크립트/링크 태그에 SRI 적용

생성된 해시값을 웹페이지의 해당 리소스 로딩 태그에 `integrity` 속성으로 추가합니다. `crossorigin=”anonymous”` 속성도 함께 지정해야 브라우저가 해시 검증을 수행합니다.

  1. 자바스크립트 라이브러리 적용 예시:
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" integrity="sha384-[여기에_생성한_해시값_입력]" crossorigin="anonymous"></script>
  2. CSS 라이브러리 적용 예시:
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-[여기에_생성한_해시값_입력]" crossorigin="anonymous" />

해결 방법 2: 빌드 도구를 활용한 자동화 및 고급 관리

수동으로 해시를 생성하고 관리하는 것은 소규모 프로젝트에는 적합할 수 있지만. 라이브러리 버전이 자주 업데이트되는 대형 프로젝트에서는 실수와 유지보수 부담이 커집니다. 현대적인 프론트엔드 빌드 도구(Webpack, Vite, Parcel 등)와 패키지 매니저(npm, yarn)를 활용하면 이 과정을 완전히 자동화할 수 있습니다.

Webpack과 `webpack-subresource-integrity` 플러그인

Webpack을 사용한다면 `webpack-subresource-integrity` 플러그인을 설치하여 번들링 과정에서 자동으로 SRI 해시를 계산하고 HTML 출력에 삽입하도록 구성할 수 있습니다.

  1. 플러그인 설치:
    npm install --save-dev webpack-subresource-integrity
  2. Webpack 설정 파일(`webpack.config.js`)에 플러그인 추가:
    
    const SriPlugin = require('webpack-subresource-integrity');
    module.exports = {
     // ... 다른 설정
     output: {
     crossOriginLoading: 'anonymous', // 필수
     },
     plugins: [
     new SriPlugin({
     hashFuncNames: ['sha384'], // 사용할 해시 알고리즘
     enabled: process.env.NODE_ENV === 'production', // 프로덕션 모드에서만 활성화
     }),
     ],
    };
     
  3. 빌드 후 생성된 HTML 파일을 확인하면, Webpack이 출력한 청크(chunk) 파일들의 `<script>`와 `<link>` 태그에 자동으로 `integrity` 속성이 추가된 것을 볼 수 있습니다.

이 방식의 최대 장점은 외부 CDN 리소스또한 자체적으로 번들링한 모든 정적 자산에 동일한 보안 수준을 적용할 수 있다는 점입니다. 내부 스크립트도 변조 위험에서 자유롭지 않습니다.

해결 방법 3: CSP(Content Security Policy)와의 연동을 통한 심층 방어

SRI는 파일 단위의 무결성을 보장하지만, 어떤 파일이 로드될 수 있는지에 대한 정책은 정의하지 않습니다. CSP는 이를 보완하는 강력한 메커니즘입니다. CSP 헤더에 `require-sri-for` 지시문을 사용하면 특정 유형의 리소스에 SRI 적용을 강제할 수 있습니다.

주의사항: `require-sri-for` 지시문은 CSP Level 3 명세에 포함되어 있으나, 2023년 기준 모든 브라우저에서 완전히 지원되지 않을 수 있습니다. 프로덕션 적용 전 대상 브라우저 호환성을 반드시 확인해야 합니다. 지원되지 않는 경우, SRI와 CSP를 독립적으로 운용하는 것이 안전합니다.

  1. CSP 헤더 설정 예시 (지원 가정 하):
    HTTP 응답 헤더에 다음 정책을 추가합니다. Content-Security-Policy: script-src https://cdn.example.com; require-sri-for script;
    이 정책은 두 가지를 명시합니다. 첫째, 스크립트는 `https://cdn.example.com` 출처에서만 로드 가능합니다. 둘째, 로드되는 모든 스크립트는 유효한 `integrity` 속성을 가져야 합니다. SRI 검증에 실패하면 스크립트는 실행되지 않습니다.
  2. 보고서 전용 모드 활용:
    CSP를 즉시 강제 적용하기 전에, `Content-Security-Policy-Report-Only` 헤더를 사용하여 정책 위반 사례를 먼저 수집하는 것이 현명한 접근법입니다. 이 모드에서는 위반 사항이 사용자에게 영향을 주지 않고 지정된 URI로 보고서만 전송됩니다. Content-Security-Policy-Report-Only: script-src https://trusted.cdn.com; require-sri-for script; report-uri /csp-violation-report-endpoint;
    수집된 보고서를 분석하여 SRI 해시값 누락이나 잘못된 출처의 스크립트 로드를 사전에 식별하고 수정할 수 있습니다.

주의사항 및 전문가 팁

SRI는 강력한 도구이지만, 오용 시 정상적인 서비스를 중단시킬 수 있습니다. 다음 사항을 준수해야 시스템 무결성과 가용성을 동시에 확보할 수 있습니다.

  • 해시값 갱신 절대 불가피: 라이브러리 버전을 업그레이드하면 파일 내용이 변경되므로 반드시 새로운 해시값을 생성하여 `integrity` 속성값을 갱신해야 합니다. 갱신하지 않으면 브라우저는 새 파일을 “변조된 파일”로 판단하고 차단하여 웹사이트 기능이 마비됩니다. 이 과정을 자동화하지 않았다면 배포 체크리스트의 최상위 항목으로 관리해야 합니다.
  • 폴백(Fallback) 전략 수립: 기본 CDN 리소스가 SRI 검증 실패로 로드되지 않을 경우를 대비한 폴백 로직을 구현하는 것이 좋습니다. 예를 들어, 스크립트 로드에 실패하면 동일한 라이브러리의 로컬 백업 복사본을 로드하도록 하는 방법입니다.
  • 알고리즘 선택: SHA-256, SHA-384, SHA-512 중 선택이 가능합니다. 보안 강도는 SHA-512가 가장 높지만, 해시값 길이도 가장 깁니다. 현재 업계 표준 및 브라우저 호환성을 고려할 때 SHA-384를 사용하는 것이 가장 안전하고 권장되는 선택입니다. SHA-1은 이미 취약성이 확인되어 사용해서는 안 됩니다.

전문가 팁: SRI는 정적 리소스에 대한 방어 수단입니다. 동적으로 생성되는 스크립트 인라인 코드에는 적용할 수 없습니다. 인라인 스크립트의 보안은 CSP의 `unsafe-inline` 제한과 `nonce` 또는 `hash` 소스를 활용하여 관리해야 합니다. 이처럼 sRI와 CSP를 조합하여 사용하면 정적 리소스의 무결성과 리소스 로드 정책을 통합적으로 제어하는 완벽에 가까운 클라이언트 측 보안 아키텍처를 구축할 수 있습니다. 최종 점검은 브라우저의 개발자 도구(F12) 콘솔(Console) 탭을 확인하여 “Integrity verification failed”와 같은 에러가 없는지 확인하는 것으로 마무리하십시오.