[Spring Security] ์น ๋ณด์ ๊ณต๊ฒฉ #2 ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ, JWT ํ ํฐ ํ์ทจ + ๋์ ์ ๋ต
1ํธ: https://syleeblog.tistory.com/51
[Spring Security] ์น ๋ณด์ ๊ณต๊ฒฉ #1: CSRF๊ณต๊ฒฉ๊ณผ XSS ๊ณต๊ฒฉ + ๋์ ์ ๋ต
์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํ ์ ์๋ 4๊ฐ์ง ์ฃผ์ ๋ณด์ ๊ณต๊ฒฉ: CSRF ๊ณต๊ฒฉ, XSS ๊ณต๊ฒฉ, ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ, JWT ํ์ทจ ๊ณต๊ฒฉ์ ๋ํด ์์๋ณด๊ณ ,์ด๋ฅผ ๋ฐฉ์ดํ ์ ์๋ Spring Security ๋๋ ์ผ๋ฐ์ ์ธ ๋์ ์ ๋ต์ ์ดํด
syleeblog.tistory.com
๐์ธ์ ๊ณ ์ ๊ณต๊ฒฉ
์ธ์ ๊ณ ์ ๊ณต๊ฒฉ์ ๊ณต๊ฒฉ์๊ฐ ์ธ์ ID๋ฅผ ๋ฏธ๋ฆฌ ์ ํด๋๊ณ , ํผํด์๊ฐ ๊ทธ ์ธ์ ์ ์ฌ์ฉํ๊ฒ ๋ง๋ ๋ค,
ํผํด์๊ฐ ๊ฐ์ ์ธ์ ์ผ๋ก ๋ก๊ทธ์ธํ์ ๋ ํผํด์์ ๊ถํ์ ํ์ทจํ๋ ๊ณต๊ฒฉ์ ๋๋ค.
์ฆ, ์ธ์
ID๋ฅผ ๋จผ์ ๋ง๋ ์ฌ๋์ด ๋ก๊ทธ์ธ ํ์๋ ๊ณ์ ๊ทธ ์ธ์
์ ์ฌ์ฉํ ์ ์๋ค๋ฉด,
๊ณต๊ฒฉ์๋ ํผํด์์ ๋ก๊ทธ์ธ ์ธ์
์ ๊ทธ๋๋ก ํ์ทจํ ์ ์์ด์.
- ๊ณต๊ฒฉ์๊ฐ ์น ์๋ฒ์ ์ ์ํ์ฌ ์ธ์
ID(ABC123)๋ฅผ ๋ถ์ฌ๋ฐ์ต๋๋ค.
- ์น ์๋ฒ๋ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๊ด๊ณ ์์ด ๋ธ๋ผ์ฐ์ ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด ์ธ์ ID๋ฅผ ๋ถ์ฌํฉ๋๋ค.
- ์ด ์ธ์
ID๊ฐ ์๋ ๋ก๊ทธ์ธ ๋งํฌ๋ฅผ ํผ์ฑ ์ด๋ฉ์ผ ๋ฑ์ ํตํด ์ฌ์ฉ์์๊ฒ ๋ณด๋ด๊ณ ,
- ํผํด์์๊ฒ http://example.com/login;jsessionid='ABC123' ๋งํฌ๋ฅผ ๋ณด๋ด๊ณ , ํผํด์๊ฐ ๋ชจ๋ฅด๊ณ ์ด ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ก๊ทธ์ธํฉ๋๋ค.
- ์ด ๊ฒฝ์ฐ๋ ์ฟ ํค ๊ธฐ๋ฐ์ด ์๋๋ผ URL์ ์ธ์ ID๋ฅผ ๋ถ์ด๋ ๋ฐฉ์์ ๋๋ค.
- ์ฌ์ฉ์๊ฐ ์ด ๋งํฌ๋ก ๋ก๊ทธ์ธ์ ํ๊ฒ ๋๋ฉด, ์ด ์ธ์ ID(ABC123๋ ๋ก๊ทธ์ธ๋(์ธ์ฆ๋) ์ํ๊ฐ ๋ฉ๋๋ค.
- ๊ณต๊ฒฉ์๋ ๊ฐ์ ์ธ์ ID๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ํผํด์์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ๋ ์ํ๋ก ์น์ฌ์ดํธ๋ฅผ ์ด์ฉํ ์ ์์ต๋๋ค.
๐ ๋์ ์ ๋ต
๊ณต๊ฒฉ์๊ฐ ๊ฐ์ง๊ณ ์๋ ์ธ์ ID๊ฐ ๋ก๊ทธ์ธ ์ดํ์๋ ๊ทธ๋๋ก ์ ์ง๋ ๋,
์ฆ ์ธ์ ์ด ๊ณ ์ ๋ ๋ ์ด ๊ณต๊ฒฉ์ด ์ ํจํฉ๋๋ค.
๋ฐ๋ผ์ ๋ก๊ทธ์ธ ๋๋ง๋ค ์ธ์ ์ ๋ฐ๊พธ๋ ์์ผ๋ก ๋ฐฉ์ดํ ์ ์์ต๋๋ค.
Spring Security์ SecurityFilterChain์์ sessionManager์ ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ ๋ฐฉ์ด ์ค์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
http.sessionManagement(s -> s
.sessionFixation(sf -> sf.changeSessionId())); // ์ธ์
ID๋ง ๋ณ๊ฒฝํ๋ ๋ชจ๋ ์ ํ
๋ค์๊ณผ ๊ฐ์ ์ต์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
- none: ์๋ฌด๊ฒ๋ ํ์ง ์๊ณ , ์ธ์ ID๋ฅผ ์ ์งํฉ๋๋ค. ์ธ์ ์ด ๋ณดํธ๋์ง ์์ต๋๋ค.
- newSession: ๋ก๊ทธ์ธ ์ ์๋ก์ด ์ธ์ ์ ์์ฑํ์ฌ ์ฌ์ฉํฉ๋๋ค.
- migrateSession: ๋ก๊ทธ์ธ ์ ์๋ก์ด ์ธ์
์ ์์ฑํ๊ณ , ์ธ์
ID๋ฅผ ์ ์ธํ๊ณ ์ด์ ์ธ์
์ ์์ฑ๋ค(๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ์ด๋ฆ ๋ฑ)์ ์๋ก์ด ์ธ์
์ผ๋ก ๋ณต์ฌํฉ๋๋ค.
- ํ์ฌ ๊ธฐ๋ณธ๊ฐ
- changeSession: ์ธ์ ์์ฒด๋ ์ ์งํ๊ณ ์ธ์ ID๋ง ๋ณ๊ฒฝ๋ฉ๋๋ค.
๐JWT ํ ํฐ ํ์ทจ
JWT ํ ํฐ์ ์ด์ฉํ ์ธ์ฆ ๋ฐฉ์์ ์ฐ๋ ์ฌ์ดํธ๊ฐ ์์ต๋๋ค.
์ด ์ฌ์ดํธ์ ์ฌ์ฉ์๊ฐ ์ ์์ ์ผ๋ก ๋ก๊ทธ์ธํ๋ฉด ์ ํจํ JWT ํ ํฐ์ ๋ฐ๊ธ ๋ฐ์ต๋๋ค.
์ด๋ ๊ณต๊ฒฉ์๊ฐ XSS ๊ณต๊ฒฉ ๋ฑ ์ด๋ค ๋ฐฉ๋ฒ์ผ๋ก JWT ํ ํฐ๊ฐ์ ์์๋ด๊ณ
๊ณต๊ฒฉ์๊ฐ ์ด ํ ํฐ์ ์์ ์ด ๋ณด๋ด๋ ์์ฒญ์ Authorization ํค๋์ ๋ฃ์ด์ ์๋ฒ์ ๋ณด๋ด๋ฉด
์๋ฒ์์๋ ์ ํจํ ํ ํฐ์ด๋ฏ๋ก ์์ฒญ์ ์ํํฉ๋๋ค.
๐ ๋์ ์ ๋ต
ํ ํฐ ์์ฒด๋ฅผ ํ์ทจ๋ฅผ ๋ง๊ธฐ ์ํด์ HTTPS ์ฌ์ฉ, XSS ๊ณต๊ฒฉ ๋ฐฉ์ด ๋ฑ์ ํ ์ ์์ต๋๋ค.
์๋๋ฉด JWT ํ ํฐ์ ์ฟ ํค์ ์ ์ฅํ๊ณ , CSRF ๊ณต๊ฒฉ์ ๋ง๋๋ก ์ ๊ฒฝ์ธ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ํ์ทจ๋ฅผ ์์ ํ ๋ง๊ธฐ ์ด๋ ค์ฐ๋ฏ๋ก, ํ์ทจ๋ ํ ํฐ์ด ์ค๋ ์ฌ์ฉ๋์ง ์๋๋ก ์ค๊ณํด์ผ ํฉ๋๋ค.
์ ํจํ ํ ํฐ์ด ํ์ทจ๋ ๋์์๋ ๊ณต๊ฒฉ์์ ํ๋์ ๋ง๊ธฐ ์ด๋ ต์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ณต๊ฒฉ์๊ฐ ํ์ทจํ ํ ํฐ์ด ๊ธ๋ฐฉ ์ธ๋ชจ ์์ด์ง๋๋ก์ ํ ์ ์์ต๋๋ค.
Access Token๊ณผ Refresh Token์ ๊ฐ์ด ์ฐ๋ 2๋จ ๊ตฌ์กฐ๋
- Access Token์ ์๋ช ์ ์งง๊ฒ ์ค์ ํ๊ณ (ex 5-30๋ถ)
- Refresh Token์ ์๋ช ์ ๊ธธ๊ฒ ์ค์ ํ์ฌ(ex 1-30์ผ)
Access Token์ด ๊ธ๋ฐฉ ๋ง๋ฃ๋์ด๋ Refresh Token์ ์ด์ฉํด ์๋ก์ด AccessToken์ ๋ค์ ๋ฐ๊ธํ ์ ๋ ๊ตฌ์กฐ์ ๋๋ค.
ํ์ทจ๋ Access Token์ ๊ณง ๋ง๋ฃ๋์ด ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํด์ง๊ณ , Refresh Token์ ์๋ฒ์์๋ง ์ ์ฅํ๊ฑฐ๋, ์์ ํ๊ฒ ๋ณดํธ๋๋ฏ๋ก ์ฌ๋ฐ๊ธ๋ ์ด๋ ต์ต๋๋ค.
Refresh Token ์์ฒด๋ ํ์ทจ๋ ์๋ ์์ง๋ง, ๋ฐ๋์ ๋ชจ๋ ์์ฒญ๋ง๋ค ํฌํจํ ํ์๊ฐ ์๊ณ Access Token์ด ๋ง๋ฃ๋ ๋๋ง ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ๋ ธ์ถ ๊ธฐํ๊ฐ ์ ์ด Access Token ๋ณด๋ค๋ ํ์ทจ๋ ํ๋ฅ ์ด ๋ฎ์ต๋๋ค.
์ฐธ๊ณ ์๋ฃ