XSS, CSRF, and SSRF
XSS, CSRF, ๊ทธ๋ฆฌ๊ณ SSRF
๐กSpring security๋ฅผ ์ค์ ํ๋ฉด์, ๋ ์น ๋ณด์์ ๋ํด ํ์ตํ๋ฉด์ ๊ณ์ ๊น๋จน๊ณ ๊ตฌ๊ธ๋งํ๊ฒ ๋์ด ํ์คํ๊ฒ ์ ๋ฆฌํด ๋๊ณ ์ ํฌ์คํ ์ ์์ฑํ๋ค.
XSS(Cross-Site Scripting)
์
์์ ์ธ ์ฌ์ฉ์๊ฐ ๊ณต๊ฒฉํ๋ ค๋ ์ฌ์ดํธ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฃ๋ ๊ธฐ๋ฒ, html
์ <script/>
ํ๊ทธ๊ฐ ์ฌ์ฉ๋๋ค.
XSS ๊ณต๊ฒฉ์ Reflected XSS
์ Stored XSS(๋๋ Persist XSS)
๋ก ๋๋๋ค.
ํ ํฐ ๋ฑ์ ์ ์ฅํ ๋ ๋ก์ปฌ ์คํ ๋ฆฌ์ง ์ฌ์ฉ์ javascript์์ ์ง์ ์์ธ์ค ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ XSS์ ์ทจ์ฝํ๋ค.
XSS ์ทจ์ฝ์ ์ ํด๋ผ์ด์ธํธ ์ธก์ ์ํด ๋ฐ์ํ๋ค.
Reflected XSS
์ผ๋ฐ ์ ์ ์ ์์ฒญ(request)์ ์ ์ฑ์ฝ๋ ์ฌ์
๊ณต๊ฒฉ ์๋๋ฆฌ์ค
- ๊ณต๊ฒฉ์๊ฐ ์ทจ์ฝํ ์ฌ์ดํธ ๋ฐ๊ฒฌ.
- ์ทจ์ฝํ ์ฌ์ดํธ์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํ๋ํ ์ ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ด๊ธด URL์ ๋ง๋ค์ด ์ผ๋ฐ ์ฌ์ฉ์์๊ฒ ํน์ ๋ฐฉ๋ฒ์ผ๋ก ์ ๋ฌ.
- ์ผ๋ฐ ์ฌ์ฉ์๋ ์ ๋ฌ๋ฐ์ URL ๋งํฌ๋ฅผ ํด๋ฆญ. ์ผ๋ฐ ์ฌ์ฉ์ ๋ธ๋ผ์ฐ์ ์์ ์ทจ์ฝํ ์ฌ์ดํธ๋ก ์์ฒญ์ ์ ๋ฌ.
- ์ผ๋ฐ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์์ ์๋ฒ๋ก๋ถํฐ์ ์๋ต ๋ฉ์์ง(response)๋ฅผ ์คํํ๋ฉด์ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ์คํ.
- ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์ฌ์ฉ์ ์ ๋ณด๊ฐ ๊ณต๊ฒฉ์์๊ฒ ์ ๋ฌ๋จ.
Stored XSS
์๋ฒ์ธก(๊ฒ์ํ)์ ์ ์ฑ์ฝ๋ ์ฌ์
๊ณต๊ฒฉ ์๋๋ฆฌ์ค
- ๊ณต๊ฒฉ์๊ฐ ์ทจ์ฝํ ์ฌ์ดํธ๋ฅผ ๋ฐ๊ฒฌ.
- ์ทจ์ฝํ ์ฌ์ดํธ์์ ์ ๊ณตํ๋ ๊ฒ์ํ์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํ๋ํ ์ ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ฌ ๊ฒ์.
- ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ณต๊ฒฉ์๊ฐ ์์ฑํ ๊ฒ์๊ธ์ ์ฝ์ผ๋ฉด, ์๋ฒ๋ก๋ถํฐ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ๋ด๊ธด ๊ฒ์๊ธ ์๋ต์ ์ ๋ฌํจ.
- ์ผ๋ฐ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์์ ์๋ฒ๋ก๋ถํฐ์ ์๋ต ๋ฉ์์ง(response)๋ฅผ ์คํํ๋ฉด์ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ์คํ.
- ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์ฌ์ฉ์ ์ ๋ณด๊ฐ ๊ณต๊ฒฉ์์๊ฒ ์ ๋ฌ๋จ.
XSS ๋์๋ฐฉ๋ฒ
<script>
์ ์
๋ ฅ์ ์ฐจ๋จํ๋ฉด ๋๋ค. ํน์๋ฌธ์๋ฅผ ์นํ, ์ ๊ฑฐํ๊ฑฐ๋ ์ฌ์ฉ์ ์
๋ ฅ์ ๊ฒ์ฆํ๋ ๊ฒ์ด ํด๊ฒฐ์ฑ
์ด ๋ ์ ์๋ค.
CSRF(Cross-Site Request Forgery)
์ฌ์ดํธ๊ฐ ์์ฒญ ์์กฐ์ ์ฝ์๋ก, ์ฌ์ฉ์๊ฐ ์ ๋ขฐํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํด ์ฌ์ฉ์์ ๊ถํ์ ๋์ฉํ์ฌ ์์น ์๋ ํ๋์ ์ํํ๊ฒ ๋ง๋๋ ๊ณต๊ฒฉ์ด๋ค. ๊ณต๊ฒฉ์๋ ์ฌ์ฉ์๊ฐ ์ด๋ฏธ ์ธ์ฆ๋ ์ธ์ ์ ๊ฐ์ง๊ณ ์๋ค๋ ์ ์ ์ ์ฉํ์ฌ, ์ฌ์ฉ์๊ฐ ์๋ํ์ง ์์ ์์ฒญ์ ์ํํ๋๋ก ํ๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ๋ ์ํ์์ ์ ์ฑ ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด, ๊ทธ ์ฌ์ดํธ์์ ์ฌ์ฉ์๊ฐ ์ธ์ฆ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฒญ์ ๋ณด๋ผ ์ ์๋ค.
CSRF ์ทจ์ฝ์ ์ ์ฃผ๋ก ์๋ฒ ์ธก์ ์ํด ๋ฐ์ํ๋ค.
CSRF ๊ณต๊ฒฉ์ ์ ์ ์กฐ๊ฑด
๊ณต๊ฒฉ์๊ฐ CSRF ๊ณต๊ฒฉ์ ํ๊ธฐ ์ํด์ ์๋ ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํด์ผํ๋ค.
- ์ฌ์ฉ์๊ฐ ๋ณด์์ด ์ทจ์ฝํ ์๋ฒ๋ก๋ถํฐ ์ด๋ฏธ ์ธ์ฆ์ ๋ฐ์ ์ํ์ฌ์ผ ํ๋ค.
- ์ฟ ํค ๊ธฐ๋ฐ์ผ๋ก ์๋ฒ ์ธ์ ์ ๋ณด๋ฅผ ํ๋ํ ์ ์์ด์ผ ํ๋ค.
- ๊ณต๊ฒฉ์๋ ์๋ฒ๋ฅผ ๊ณต๊ฒฉํ๊ธฐ ์ํ ์์ฒญ ๋ฐฉ๋ฒ์ ๋ํด ๋ฏธ๋ฆฌ ํ์ ํ๊ณ ์์ด์ผ ํ๋ค. ์์์น ๋ชปํ ํ๋ผ๋ฏธํฐ๊ฐ ์์ผ๋ฉด ๋ถ๊ฐ๋ฅํ๋ค.
CSRF ๊ณต๊ฒฉ ์์(GET ์์ฒญ์ธ ๊ฒฝ์ฐ)
๊ณต๊ฒฉ์์ ์ ์ฑ ์น ์ฌ์ดํธ
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Attacker Site</title>
</head>
<body>
<div id="wrap">
<img src="http://vulnerable-site/change?name=NameChangedByImageTag" style="width: 0px; height: 0px;"/>
</div>
</body>
</html>
๊ณต๊ฒฉ์๋ ์์ ๊ฐ์ ์
์ฑ ์ฌ์ดํธ๋ฅผ ๋ง๋ค์ด ํ๊ฒ์๊ฒ ์ ๋ฌํ๋ค. ํ๊ฒ์ด ํด๋น ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด, img
ํ๊ทธ(๋๋ a
ํ๊ทธ)์ ์๋ฒ๋ก GET์์ฒญ์ ๋ณด๋ธ๋ค.
width ๋ฐ height ๊ฐ์ด 0์ด๋ฏ๋ก ๋ธ๋ผ์ฐ์ ์ ๋ณด์ด์ง ์๋๋ค.
CSRF ๊ณต๊ฒฉ ์์(POST ์์ฒญ์ธ ๊ฒฝ์ฐ)
๊ณต๊ฒฉ์์ ์ ์ฑ ์น ์ฌ์ดํธ
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Attacker Site</title>
</head>
<body>
<div id="wrap">
<form action="http://vulnerable-site/change" method="POST">
<input type="hidden" id="memberName" name="memberName" value="NameChangedByFormSubmit"/>
</form>
<script>
setTimeout(function () {
document.forms[0].submit();
}, 1000);
</script>
</div>
</body>
</html>
<form/>
ํ๊ทธ์ hidden ํ์
์ <input />
ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋ค. JavaScript๋ฅผ ์ด์ฉํด ํ์ด์ง ๋ ๋๋ง์ด ์ํ๋๊ณ 1์ด ๋ค ํผ ์ ์ก์ ์๋ํ๋ค.
CSRF ๋์ ๋ฐฉ๋ฒ
- Referrer ๊ฒ์ฆ
์์ฒญ ํค๋(request header) ์ ๋ณด์์ Referrer ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค. ๋ณดํต host์ Referrer ๊ฐ์ด ์ผ์นํ๋ฏ๋ก ๋์ ๋น๊ตํ๋ค. CSRF ๊ณต๊ฒฉ์ ๋๋ถ๋ถ Referrer ๊ฐ์ ๋ํ ๊ฒ์ฆ๋ง์ผ๋ก ๋ฐฉ์ด๊ฐ ๊ฐ๋ฅํ๋ค๊ณ ํ๋ค.
์์: Java servlet์ ๊ฒฝ์ฐ
String referer = request.getHeader("Referer");
String host = request.getHeader("host");
- CSRF ํ ํฐ ๊ฒ์ฆ
ํด๋ผ์ด์ธํธ ๋ณ๋ก ๋ค๋ฅธ ํ ํฐ์ ์์ฑํ์ฌ hidden
ํ์
input
ํ๊ทธ๊ฐ ํฌํจ๋ ํ์ด์ง๋ฅผ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ, ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ๋ณด๋ด๋ฉด ํด๋น ํ๊ทธ์ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ๊ณ ์ ํ ํ ํฐ์ด ํฌํจ๋์ด ์์ด์ผ ํจ. ์๋ฒ๋ ํด๋น ํ ํฐ์ ์ธ์
๋ฑ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์์ด์ผ ํจ.
๋ง์ฝ ํ ํฐ์ด ๋๋ฝ๋์ด ์๋ค๋ฉด CSRF ๋ก ์์ฌํ ์ ์์.
- Double submit cookie
์น๋ธ๋ผ์ฐ์ ์ Same Origin ์ ์ฑ
์ผ๋ก ๊ณต๊ฒฉ์๊ฐ ์ฟ ํค๊ฐ์๋ ์ ๊ทผํ ์ ์๋๊ฒ์ ์ด์ฉํ์ฌ
1.๋ธ๋ผ์ฐ์ ๋ get์์ฒญ์ผ๋ก ํ ํฐ๊ฐ๊ณผ _csrf(์ํฌ๋ฆฟํค)๊ฐ์ ์๋ฒ๋ก ๋ถํฐ ๋ฐ๋๋ค
2.๋ธ๋ผ์ฐ์ ์์ write์์ฒญ์ header์ ํ ํฐ๊ฐ์ ์ฃผ๊ณ ์ฟ ํค๊ฐ์ ์ํฌ๋ฆฟํค๋ฅผ ๋ถ์ฌํ์ฌ ์๋ฒ์ ๋ฏธ๋ค์จ์ด์์ ํ ํฐ๊ฐ์ decodeํด์ decodeํ ์ํฌ๋ฆฟํค๊ฐ ์ฟ ํค๊ฐ๊ณผ ์ผ์นํ๋์ง ์ฒดํฌํ๋ค
SSRF(Server-Side Request Forgery)
์๋ฒ๊ฐ ์์กฐ๋ ์์ฒญ์ ๋ณด๋ด๋๋ก ํ๋ ์ทจ์ฝ์ ์ด๋ค. Client-Side Request Forgery(CSRF, ํด๋ผ์ด์ธํธ ์ธก ์์ฒญ ์์กฐ) ๊ธฐ๋ฒ์์ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ ์ฃผ์ฒด๋ง ๋ธ๋ผ์ฐ์ (Client) ์์ ์๋ฒ(Server) ๋ก ๋ฐ๋์๋ค๊ณ ์ดํดํด๋ ์ข๋ค.
HTTP GET ์์ฒญ์ ํตํ SSRF ๊ณต๊ฒฉ ์์
GET /api/fetch?url=http://internal-service.local/admin HTTP/1.1
Host: example.com
url์ ์ธ๋ถ๋ง์์ ์ ์ ๋ถ๊ฐ๋ฅํ internal-service.local/admin
๋ก์ ์์ฒญ์ ์๋ฒ๊ฐ ๋์ ๊ณต๊ฒฉ์์๊ฒ ์ ๋ฌํ๋๋ก ํ๋ ์์์ด๋ค.
SSRF ๊ณต๊ฒฉ ์๋๋ฆฌ์ค
์ทจ์ฝํ ๊ฒ์ํ ์๋ฒ๊ฐ ์๋ค๊ณ ํ์. ํด๋น ์๋ฒ๋ ๊ณต๊ฒฉ์๊ฐ ์ด๋ฏธ์ง๊ฐ ํฌํจ๋ ๊ฒ์๊ธ์ ์์ฑํ๋ฉด, ํด๋น ๊ฒ์๊ธ์ ์ด๋ํ๋ ์ ์ ๋ค์๊ฒ ํด๋น ์ด๋ฏธ์ง์ url์ ๊ฒ์ฆ ์์ด ๋ณด์ฌ์ค๋ค.
- ๊ณต๊ฒฉ์๋
image_url
์ ์ ์์ ์ธ url๋์ ์ ์์ ์ธ url์ ์ฝ์ ํ๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์์ฒญ์ ๋ณด๋ผ ์ ์๋ค.์ฌ๊ธฐ์POST /upload-image HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded image_url=http://localhost/admin
http://
๋ถ๋ถ์ ์คํค๋ง(scheme)๋ก์จ, ์์ธํ ๋ด์ฉ์ ํ๋จ์ ํ์ ํ๋ค. - ๊ณต๊ฒฉ์๊ฐ ์์ฑํ ๊ฒ์๊ธ์ ์ ๊ทผํ๋ฉด, ์๋ฒ๋
localhost/admin
์ผ๋ก์ ์์ฒญ์ ๋ณด๋ด๊ณ , ์๋ต์ ์ ๊ทผ์์๊ฒ ์๋นํ๋ค. - ๊ณต๊ฒฉ์๋ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ์ด๋ฏธ์ง์ ์ํ์ ๋ฐ๋ผ ์๋ฒ์ ๋ด๋ถ ๋คํธ์ํฌ ๊ตฌ์กฐ์ ์ ๋ณด๋ฅผ ๋๋ต์ ์ผ๋ก ํ์ ํ ์ ์๊ฒ ๋๋ค. ๋ง์ฝ ์๋ฒ๊ฐ ์๋ฌ ๋ฉ์์ง๋ ํ์ด์ง ๋ด์ฉ์ ํฌํจํ์ฌ ๋ฐํํ๋ค๋ฉด, ์ด๋ฅผ ํตํด ๋ด๋ถ ๋คํธ์ํฌ์ ์ทจ์ฝ์ ์ ํ์ ํ ์ ์๋ค.
๐ก์คํค๋ง๋?
URL์์ ์คํค๋ง(schema)๋ ํ๋กํ ์ฝ์ ์ ์ํ๋ฉฐ, ํด๋ผ์ด์ธํธ๊ฐ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ๋ฐฉ์์ ๊ฒฐ์ ํ๋ค. ์คํค๋ง๋ URL์ ๋งจ ์ ๋ถ๋ถ์ ์์นํ๋ฉฐ, ์ฝ๋ก ๊ณผ ๋ ๊ฐ์ ์ฌ๋์(://)๋ก ๋๋๋ค. ์คํค๋ง๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ด๋ป๊ฒ ํต์ ํด์ผ ํ๋์ง๋ฅผ ์ง์ ํ๋ค. ์๋ฅผ ๋ค์ด, HTTP, HTTPS, FTP, FILE ๋ฑ์ด ์๋ค.
์ ์์์์,http...
๋์ ,file:///etc/passwd
๋ฅผ ๋ฃ์ผ๋ฉด, ์๋ฒ ํ์ผ ์์คํ ์ ์ ์ ์ ๋ณด๋ฅผ ์ทจ๋ํ ์ ์๋ค.
SSRF ๋์ ๋ฐฉ๋ฒ
- URL ๊ฒ์ฆ: ์ ๋ก๋๋๋ URL์ด ์ธ๋ถ ๋๋ฉ์ธ์ ์ํ๋์ง ์ฒ ์ ํ ๊ฒ์ฆํ๋ค.
- ํ์ดํธ๋ฆฌ์คํธ: ํ์ฉ๋ ๋๋ฉ์ธ์ ๋ชฉ๋ก์ ์ฌ์ฉํ์ฌ URL์ ์ ํํ๋ค.
- ํ๋ก์ ์๋ฒ ์ฌ์ฉ: ์ง์ ์ ์ธ URL ์ ๊ทผ ๋์ ํ๋ก์ ์๋ฒ๋ฅผ ํตํด ์์ฒญ์ ํํฐ๋งํ๋ค.
- ์๋ต ๋ด์ฉ ์ ํ: ์๋ฒ๊ฐ ์ธ๋ถ๋ก ๋ฐํํ๋ ์๋ต ๋ด์ฉ์ ์ ํํ์ฌ ๋ด๋ถ ์ ๋ณด๊ฐ ๋ ธ์ถ๋์ง ์๋๋ก ํ๋ค.