๐ก Dreamhack - Web Hacking Advanced (Client Side) ๋ฅผ ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ์์ต๋๋ค.
์น ๋ธ๋ผ์ฐ์ ๋ ์น ์๋ฒ๋ก๋ถํฐ ๋ฐ๋ ์ปจํ ์ธ ๊ฐ ์๋๋ ์ปจํ ์ธ ์ธ์ง ํ์ธํ ์ ์๊ธฐ์, ํ์ด์ง์ ์ปจํ ์ธ ์์ ์ฌ์ฉํ๋ ์์๋ค์ด ๋ชจ๋ ์น ์๋ฒ์์ ์๋ํ ์์์ด ๋ง๋์ง ํ์ธํ๊ธฐ ์ํด Content Security Policy(CSP)๊ฐ ํ์ํ๋ค.
Content Security Policy(CSP, ์ปจํ ์ธ ๋ณด์ ์ ์ฑ )๋ XSS๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ๋ฅ์ ๊ณต๊ฒฉ์ด ๋ฐ์ํ์์ ๋ ํผํด๋ฅผ ์ค์ด๊ณ ์น ๊ด๋ฆฌ์๊ฐ ๊ณต๊ฒฉ ์๋๋ฅผ ๋ณด๊ณ ๋ฐ์ ์ ์๋๋ก ์๋กญ๊ฒ ์ถ๊ฐ๋ ๋ณด์ ๊ณ์ธต์ด๋ค.
CSP ํค๋๋ 1๊ฐ ์ด์์ ์ ์ฑ
์ง์๋ฌธ์ด ์ธ๋ฏธ์ฝ๋ก ์ผ๋ก ๋ถ๋ฆฌ๋ ํํ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ ์ฑ
์ง์๋ฌธ์ ์ง์๋ฌธ(e.g. default-src
, srcipt-src
๋ฑ)๊ณผ 1๊ฐ ์ด์์ ์ถ์ฒ(e.g. 'self'
, https:
, *.dreamhack.io
๋ฑ)๊ฐ ๊ณต๋ฐฑ์ผ๋ก ๋ถ๋ฆฌ๋ ํํ๋ก ์ง์ ํ์ฌ์ผ ํ๋ค.
CSP ๊ตฌ๋ฌธ์ ๋ค์ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ฉํ ์ ์๋ค.
Content-Security-Policy
HTTP ํค๋์ ์ถ๊ฐํ์ฌ ์ ์ฉํ ์ ์๋ค. ํด๋น ๊ตฌ๋ฌธ์์ policy-directive
๋ถ๋ถ์ CSP๋ฅผ ์ ์ํ๋ ์ ์ฑ
๋๋ ํฐ๋ธ๋ฅผ ์์ฑํ๋ค.
Content-Security-Policy: <policy-directive>; <policy-directive>
ํ์ด์ง ๋ด๋ถ์ ์์๋ค์ด ๊ฐ์ ์ค๋ฆฌ์ง ํน์ https://example.com ์์๋ง ๋ก๋๋์ด์ผ ํจ์ ๋ํ๋ด๋ ์์
Content-Security-Policy: default-src 'self' https://example.com
CSP ํค๋๋ meta
ํ๊ทธ์ ์๋ฆฌ๋จผํธ๋ก๋ ์ ์ํ ์ ์๋ค.
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://example.com">
CSP๋ ์ธ๋ผ์ธ ์ฝ๋(Inline code)๋ฅผ ์ ํดํ๋ค๊ณ ๊ฐ์ฃผํ๋ค. ์ธ๋ผ์ธ ์ฝ๋๋ ํ๊ทธ์ src
์์ฑ์ผ๋ก ์ฝ๋๋ฅผ ๋ก๋ํ์ง ์๊ณ ํ๊ทธ ๋ด์ ์ง์ ์ฝ๋๋ฅผ ์ฝ์
ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
<script>alert(1);</script>
์ ๊ฐ์ด ํ๊ทธ ๋ด์ ์ฝ๋๋ฅผ ์ง์ ์ฝ์
ํ๊ธฐ ๋๋ฌธ์ ์ธ๋ผ์ธ ์ฝ๋์ด๋ค. ์ด๋ฌํ ํํ๋ฅผ ์ง์ํ๊ณ , <script src="alert.js"></script>
์ ๊ฐ์ด src
์์ฑ์ ์ฝ๋ ๊ฒฝ๋ก๋ฅผ ์ ์ํ๋ ๋ฐฉ์์ ๊ถ์ฅํ๋ค.
CSP๋ <script>
ํ๊ทธ ๋ด์ ์ฝ๋๋ฅผ ์ฝ์
ํ๋ ๊ฒ, on*
์ด๋ฒคํธ ํธ๋ค๋ฌ ์์ฑ, javascript:
URL ์คํด, CSS
์คํ์ผ ์ํธ๋ฅผ ๋ชจ๋ ์ธ๋ผ์ธ ์ฝ๋๋ก ๊ฐ์ฃผํ๊ณ ํ์ฉํ์ง ์๋๋ค.
CSP๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์์ด ํ ์คํธ๋ฅผ ์คํ ๊ฐ๋ฅํ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ ํํ๋ก ๋ณํํ๋ ๋งค์ปค๋์ฆ์ ์ ํดํ๋ค๊ณ ๊ฐ์ฃผํ๋ค.
eval
new Function()
setTimeout([string], ...)
setInterval([string], ...)
์์ ๊ฐ์ด ๋ฌธ์์ด ํํ๋ก ์ ๋ ฅ์ ๋ฐ๋ ํจ์์ ์คํ์ ๋ชจ๋ ์ฐจ๋จ๋๋ค. ๋ค๋ง ํด๋น ํจ์์ ๋ฌธ์์ด ์ ๋ ฅ์ด ์๋ ์ด๋ผ์ธ ํจ์ ํํ๋ก ํ๋ผ๋ฏธํฐ๊ฐ ์ ๋ฌ ๋ ๋์๋ ์ฐจ๋จ๋์ง ์๋๋ค.
<Policy-directive
๋ <directive> <value>
ํํ๋ก ๊ตฌ์ฑ๋๋ค.
<directive>
: ์ง์๋ฌธ. ์ปจํ
์ธ ๋ด์์ ๋ก๋ํ๋ ๋ฆฌ์์ค๋ฅผ ์ธ๋ถํํด ์ด๋ค ๋ฆฌ์์ค์ ๋ํ ์ถ์ฒ๋ฅผ ์ ์ดํ ์ง ๊ฒฐ์ ํ๋ค.<value>
: <directive>
์์ ์ ์ํ ๋ฆฌ์์ค์ ์ถ์ฒ๋ฅผ ์ ์ํ๋ค. <value>
์๋ ์ฌ๋ฌ ๊ฐ์ ์ถ์ฒ๊ฐ ์ ์๋ ์ ์๊ณ ๊ณต๋ฐฑ์ ํตํด ๊ตฌ๋ถ๋๋ค.์ง์๋ฌธ | ์ค๋ช |
---|---|
defulat-src | -src๋ก ๋๋๋ ๋ชจ๋ ๋ฆฌ์์ค์ ๊ธฐ๋ณธ ๋์์ ์ ์ด. ๋ง์ฝ CSP ๊ตฌ๋ฌธ ๋ด์์ ์ง์ ํ์ง ์์ ์ง์๋ฌธ์ด ์กด์ฌํ๋ค๋ฉด default-src์ ์ ์๋ฅผ ๋ฐ๋ผ๊ฐ๋ค. |
img-src | ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ ์ ์๋ ์ถ์ฒ๋ฅผ ์ ์ดํ๋ค. |
script-src | ์คํฌ๋ฆฝํธ ํ๊ทธ ๊ด๋ จ ๊ถํ๊ณผ ์ถ์ฒ๋ฅผ ์ ์ดํ๋ค. |
style-src | ์คํ์ผ์ํธ ๊ด๋ จ ๊ถํ๊ณผ ์ถ์ฒ๋ฅผ ์ ์ดํ๋ค. |
child-src | ํ์ด์ง ๋ด์ ์ฝ์ ๋ ํ๋ ์ธ ์ปจํ ์ธ ์ ๋ํ ์ถ์ฒ๋ฅผ ์ ์ดํ๋ค. |
base-uri | ํ์ด์ง์ ํ๊ทธ์ ๋ํ๋ ์ ์๋ URL์ ์ ์ดํ๋ค. |
์ถ์ฒ | ์ค๋ช |
---|---|
*://example.com | ์ถ์ฒ์ scheme์ ์์ผ๋์นด๋(*)๋ฅผ ์ด์ฉํด ํํํ ์ ์๋ค. |
https://*.example.com | ์ถ์ฒ์ ํธ์คํธ ์๋ธ๋๋ฉ์ธ์ ์์ผ๋์นด๋๋ฅผ ์ด์ฉํด ํํํ ์ ์๋ค.(๋จ, ์์ผ๋ ์นด๋๋ ํธ์คํธ์ ์ค๊ฐ์ ๋ค์ด๊ฐ ์ ์๋ค.) ์๋ธ๋๋ฉ์ธ์ ์์ผ๋์นด๋๋ก ํํํ ์, ์๋ธ๋๋ฉ์ธ์ด ๋ถ์ด์์ง ์๋ ๋๋ฉ์ธ์ ํฌํจ๋์ง ์๋๋ค. i.e) https://*.example.com์ผ๋ก ์ถ์ฒ๋ฅผ ํ๊ธฐํ ๊ฒฝ์ฐ, https:.//example.com์ ํฌํจ ์๋จ |
https://example.com:* | ์ถ์ฒ์ ํฌํธ๋ ์์ผ๋์นด๋๋ฅผ ์ด์ฉํด ํํํ ์ ์๋ค. |
none | ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ์ง ์๋๋ค. |
self | ํ์ด์ง์ ํ์ฌ ์ถ์ฒ(Origin) ๋ด์์ ๋ก๋ํ๋ ๋ฆฌ์์ค๋ง ํ์ฉํ๋ค. |
unsafe-inline | ์์ธ์ ์ผ๋ก ์ธ๋ผ์ธ ์ฝ๋์ ์ฌ์ฉ์ ํ์ฉํ๋ค. |
unsafe-eval | ์์ธ์ ์ผ๋กย eval๊ณผ ๊ฐ์ ํ ์คํธ-์๋ฐ์คํฌ๋ฆฝํธ ๋ณํ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉ์ ํ์ฉํ๋ค. |
nonce-<base64-value> | nonceย ์์ฑ์ ์ค์ ํ์ฌ ์์ธ์ ์ผ๋ก ์ธ๋ผ์ธ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ค.ย <base64-value>ย ๋ ๋ฐ๋์ ์์ฒญ๋ง๋ค ๋ค๋ฅธ ๋์ ๊ฐ์ผ๋ก ์ค์ ํด์ผ ํ๋ค. ํด๋น ์ถ์ฒ๋ฅผ ์ค์ ํ๋ฉดย unsafe-inlineย ์ ๋ฌด์๋๋ค. |
<hash-algorithm>-<base64-value> | scriptย ํน์ย styleย ํ๊ทธ ๋ด ์ฝ๋์ ํด์๋ฅผ ํํํ๋ค. ํด๋น ์ถ์ฒ๋ฅผ ์ค์ ํ๋ฉดย unsafe-inlineย ์ ๋ฌด์๋๋ค. |
Content-Security-Policy: default-src 'self'
: ๋ชจ๋ ๋ฆฌ์์ค์ ์ถ์ฒ๋ฅผ ํ์ฌ ํ์ด์ง์ ๊ฐ์ ์ถ์ฒ๋ก ์ ํํ๋ค.
Content-Security-Policy: default-src 'self' https://example.com
: ๋ชจ๋ ๋ฆฌ์์ค์ ์ถ์ฒ๋ฅผ ํ์ฌ ํ์ด์ง์ ๊ฐ์ ์ถ์ฒ์ https://example.com์ผ๋ก ์ ํํ๋ค.
Content-Security-Policy: default-src 'self'; img-src *; script-src static.example.com
: ๋ชจ๋ ๋ฆฌ์์ค์ ์ถ์ฒ๋ฅผ ํ์ฌ ํ์ด์ง์ ๊ฐ์ ์ถ์ฒ๋ก ์ ํ, ์ด๋ฏธ์ง์ ์ถ์ฒ๋ ๋ชจ๋ ํธ์คํธ๋ฅผ ํ์ฉ, ์คํฌ๋ฆฝํธ ํ๊ทธ์ ์ถ์ฒ๋ static.example.com์ผ๋ก ์ ํํ๋ค.
Content-Security-Policy: child-src 'self' frame.example.com
: ํ์ด์ง ๋ด์ ์ฝ์ ๋ ํ๋ ์ ์ปจํ ์ธ URL์ frame.example.com ๋ด์ ์ปจํ ์ธ ๋ง ๋ก๋ํ ์ ์๋ค.
Content-Security-Policy: base-uri 'none'
: base ํ๊ทธ์ URL์ ์ด๋ ๊ฒ๋ ํ์ฉํ์ง ์๋๋ค.
Content-Security-Policy: script-src 'unsafe-eval
: ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ ๋ด์ eval
๊ณผ ๊ฐ์ ํ
์คํธ-์๋ฐ์คํฌ๋ฆฝํธ ๋ณํ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉ์ ํ์ฉํ๋ค.
Content-Security-Policy: script-src 'unsafe-inline'
: ์คํฌ๋ฆฝํธ ํ๊ทธ ๋ด ์ธ๋ผ์ธ ์ฝ๋์ ์ฌ์ฉ์ ํ์ฉํ๋ค.
Content-Security-Policy: script-src 'nonce-YTQyYWZkODYtYWYyNy00ZGQzLTg2YjMtNzJhY2ZmOWY5OGNj'
: ์คํฌ๋ฆฝํธ ํ๊ทธ์ nonce ์์ฑ์ YTQyYWZkODYtYWYyNy00ZGQzLTg2YjMtNzJhY2ZmOWY5OGNj ๊ฐ์ด ์กด์ฌํ์ง ์์ผ๋ฉด ์คํฌ๋ฆฝํธ ๋ก๋์ ์คํจํ๋ค.
Content-Security-Policy: script-src 'sha256-5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA='
: ์คํฌ๋ฆฝํธ ํ๊ทธ ๋ด์ ์ฝ๋ ํน์ src ์์ฑ์ผ๋ก ์ง์ ๋ ํ์ผ์ sha256 ํด์๋ฅผ base64๋ก ์ธ์ฝ๋ฉํ ๊ฒฐ๊ณผ๊ฐ 5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA= ์ ๋ค๋ฅด๋ค๋ฉด ์คํฌ๋ฆฝํธ ๋ก๋์ ์คํจํ๋ค.
๋ธ๋ผ์ฐ์ ๊ฐ ๋ถ๋ฌ์ค๋ ์์์ ์ถ์ฒ๊ฐ ํ์ผ ์ ๋ก๋ ๋ฐ ๋ค์ด๋ก๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค๋ฉด, ๊ณต๊ฒฉ์๋ ์ถ์ฒ์ ์คํฌ๋ฆฝํธ์ ๊ฐ์ ์์์ ์ ๋ก๋ํ ๋ค ๋ค์ด๋ก๋ ๊ฒฝ๋ก๋ก ์น ํ์ด์ง์ ์์์ ํฌํจ์ํฌ ์ ์๋ค.
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<h1>๊ฒ์ ๊ฒฐ๊ณผ: <script src="/download_file.php?id=177742"></script></h1>
CSP์์ ํ์ฉํ ์ถ์ฒ๊ฐ JSONP API๋ฅผ ์ง์ํ๋ค๋ฉด, callback
ํ๋ผ๋ฏธํฐ์ ์ํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์
ํ์ฌ ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํ๋ค. ์๋ฅผ ๋ค์ด ์น ํ์ด์ง์์ *.google.com
์์ ์จ ์ถ์ฒ๋ง ํ์ฉํ ๊ฒฝ์ฐ, ๊ตฌ๊ธ์์ JSONP API๋ฅผ ์ง์ํ๋ ์๋ฒ๋ฅผ ์ฐพ์ callback
์ ์ํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์
ํ ์ ์๋ค.
https://accounts.google.com/o/oauth2/revoke?callback=alert(1);
CSP์ nonce
๋ฅผ ์ด์ฉํ๋ฉด ๋ฐ๋ก ๋๋ฉ์ธ์ด๋ ํด์ ๋ฑ์ ์ง์ ํ์ง ์์๋ ๊ณต๊ฒฉ์๊ฐ ์์ธกํ ์ ์๋ nonce
๊ฐ์ด ํ๊ทธ ์์ฑ์ ์กด์ฌํ ๊ฒ์ ์๊ตฌํจ์ผ๋ก์จ XSS ๊ณต๊ฒฉ์ ๋ฐฉ์ดํ ์ ์๋๋ฐ, ์ด๋ฅผ ์ํด์๋ nonce
๊ฐ ๊ณต๊ฒฉ์๊ฐ ์ทจ๋ํ๊ฑฐ๋ ์์ธกํ ์ ์๋ ๊ฐ์ด์ด์ผ ํ๋ค.
๊ทธ๋ฌ๋ ์ด ๊ฐ์ ์์ฑํ๋ ์๊ณ ๋ฆฌ์ฆ์ด ์ทจ์ฝํ์ฌ ๊ฐ์ ์์ธกํ ์ ์๋ค๋ฉด ๊ณต๊ฒฉ์๋ ์ด๋ฅผ ์ ์ถํด ์์ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์น ์ฌ์ดํธ์ ์ฝ์
ํ ์ ์๋ค. ex) ํ์ฌ ์๊ฐ(srand() / rand()
) ๋ฑ ๊ณต๊ฒฉ์๊ฐ ์ ์ ์๋ ์ ๋ณด.
HTML ํ์ดํผ๋งํฌ์์ ํธ์คํธ ์ฃผ์ ์์ด ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ํ์ฌ ๋ฌธ์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฌธ์๋ฅผ ํด์ํ๋ค. HTML <base>
ํ๊ทธ๋ ๊ฒฝ๋ก๊ฐ ํด์๋๋ ๊ธฐ์ค์ ์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ฉฐ, <a>
, <form>
๋ฑ์ target
์์ฑ์ ๊ธฐ๋ณธ ๊ฐ์ ์ง์ ํ๋๋ก ํ๋ค.
์ด๋, base-uri
CSP ๊ตฌ๋ฌธ์ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ base
ํ๊ทธ๋ฅผ ์ด์ฉํ์ฌ ์์ ์์์ ๋ก๋ํ ์ ์๋ค. ์ด๋ฌํ ํํ์ ๊ณต๊ฒฉ์ Nonce Retargeting์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
base-uri
ย ์ง์๋ฌธ์ ์์๋ก ์ง์ ํ์ง ์๋ ์ด์ย default
ย ์ด๊ธฐ ๊ฐ์ด ์กด์ฌํ์ง ์๋๋ค. ๋ฐ๋ผ์ ์น ์๋น์ค๋ฅผ ๊ฐ๋ฐํ ๋์๋ ๋ฐ๋์ย base-uri
ย ์ง์๋ฌธ์ ์ ์ํด์ฃผ์ด์ผ ํ๋ค.