๐Ÿ˜ณ ๋‹น์‹ ์˜ ์ธ์ฆ ๋ฐฉ์‹ ์ •๋ง ์•ˆ์ „ํ•ฉ๋‹ˆ๊นŒ??(with ์†Œ์…œ๋กœ๊ทธ์ธ)

Minchoยท2024๋…„ 4์›” 19์ผ
2

cs์ง€์‹

๋ชฉ๋ก ๋ณด๊ธฐ
10/10

์ธ์ฆ ์ธ๊ฐ€ ๋ฐฉ์‹์— ๋Œ€ํ•œ BEST PRACTICE??

์ด๋ฒˆ์— ์ฒ˜์Œ ์†Œ์…œ ๋กœ๊ทธ์ธ๋ฐฉ์‹์„ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ ๋งŽ์€ ๋ถ„๋“ค์˜ ๋ธ”๋กœ๊ทธ ์ •๋ฆฌ๊ธ€์„ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋กœ๊ทธ์ธ ๋ฐฉ์‹๋„ ๋‹ค์–‘ํ–ˆ๊ณ , ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ ๋งž์•„? ๋ผ๋Š” ์˜๊ตฌ์‹ฌ์ด ๊ฐ–๊ฒŒํ•˜๋Š” ๋ฐฉ์‹๋„ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŽ์•„์ง€๋ฉด์„œ ๊ด€๋ จ ์ •๋ฆฌ๊ธ€๋„ ๋งŽ์•„์ง€๋ฉด์„œ ๋ถ€์กฑํ•œ ๊ด€์ ์—์„œ ์ ์€ ๊ธ€๋„ ๋งŽ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ์ด ์ฐธ์— ์ธ์ฆ ์ธ๊ฐ€ ๋ฐฉ์‹์— ๋Œ€ํ•œ BEST PRACTICE๋ฅผ ์ฐพ๊ณ  ์ด์— ๋Œ€ํ•œ ์ƒ๊ฐ์„ ์ •๋ฆฌํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ธ์ฆ, ์ธ๊ฐ€ ๋ฐ ์†Œ์…œ๋กœ๊ทธ์ธ์˜ ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

์†Œ์…œ๋กœ๊ทธ์ธ์„ ์œ„ํ•œ ์—ฌ์ •

์šฐ์„  ์†Œ์…œ๋กœ๊ทธ์ธ ๊ฐ™์€ ๊ฒฝ์šฐ OAuth2.0๊ธฐ๋ฐ˜์˜ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์ œ 3์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•ด HTTP์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ํ‰์†Œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” naver๋‚˜ ๊ตฌ๊ธ€ ๊ณ„์ •์„ ์ด์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์„œ ์ด์šฉํ•˜๋Š” ์ •๋ณด๋ฅผ ํ†ตํ•ด ํƒ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ธ๋ฐ์š”. ๊ทธ๋ž˜์„œ ์ธ์ฆ๋ณด๋‹ค๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์— ์ดˆ์ ์ด ๋งž์ถฐ์ค˜ ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†Œ์…œ ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ํ”ํžˆ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

์ด์ „์— ๊ตฌํ˜„ํ–ˆ๋˜ flow... ์ง€๊ธˆ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค..๐Ÿ˜ข

๊ตฌ๊ธ€๋ง์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๋„๋ฆฌ ํผ์ ธ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜๋ฌธ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ ๋ฐ›๋Š”๊ฒŒ ๋งž๋Š” ๊ฒƒ์ผ๊นŒ?
์ด๋Ÿฐ ๋ฐฉํ–ฅ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐœ์ƒํ•˜๋Š” 2๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ์ธ๊ฐ€ ์ฝ”๋“œ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœ๋˜๋Š” ๋ฌธ์ œ
  • ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฌธ์ œ ๋ฐœ๊ธ‰ ๋„๋ฉ”์ธ ๋กœ์ง์ด ํด๋ผ์ด์–ธํŠธ์— ์กด์žฌํ•˜๋Š” ๋ฌธ์ œ

์†Œ์…œ ๋กœ๊ทธ์ธ ์‹œ์— ๋กœ๊ทธ์ธ ์ดํ›„ ๋“ฑ๋ก๋œ redirect url์— ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋กœ code๋ฅผ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด url์— code๊ฐ€ ๋…ธ์ถœ๋˜์–ด ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ธก์— ๋…ธ์ถœ์‹œ์ผœ ๋ฒ„๋ฆฌ๋ฉด ๊ณ ์†Œ ๋‹นํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š”?? ๋ง๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฒ€์ฆ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋…ธ์ถœ๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ฒŒ๋‹ค๊ฐ€ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ›์•„์˜ค๊ณ  ์ด๋ฅผ ๋ฐฑ์—”๋“œ์— ์ „์†กํ•˜๊ณ  ๋ฐฑ์—”๋“œ์—์„œ ๋‹ค์‹œ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜๋Š” ํ๋ฆ„์ด ๋ณต์žกํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ ๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฐฑ์—”๋“œ์—์„œ ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ์—์„œ ๋กœ๊ทธ์ธ ์ดํ›„ redirect url์„ ๋ฐฑ์—”๋“œ url๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ฐฑ์—”๋“œ url๋กœ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐฑ์—”๋“œ์—์„œ๋Š” redirect url์—์„œ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  3. ๋ฐ›์€ ์ธ๊ฐ€์ฝ”๋“œ๋กœ ์ธ์ฆ ํ† ํฐ์„ ๋ฐœ๊ธ‰ ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ด๋Ÿฌํ•œ ํ๋ฆ„์€ ์นด์นด์˜ค developer ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ํ™•์ธํ•ด ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ์—์„œ ํ† ํฐ ๋ฐœ๊ธ‰์ดํ›„ ์ฒ˜๋ฆฌ

๋ฐฑ์—”๋“œ์—์„œ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ† ํฐ์„ ๋ฐœ๊ธ‰ ๋ฐ›์€ ์ดํ›„์—๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๊นŒ์š”??

๋‘๊ฐ€์ง€ ๋ถ„๊ธฐ๋ฅผ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๊ธฐ์กด USER
  • ์‹ ๊ทœ USER

๊ธฐ์กด์— ๊ฐ€์ž… ๋˜์–ด ์žˆ๋Š” ์‚ฌ์šฉ์ž์ผ ๊ฒฝ์šฐ, accessToken์„ ๋ฐœ๊ธ‰ํ•˜๊ณ  refreshToken์„ ์„œ๋ฒ„๋‹จ(DB ํ˜น์€ Redis)์— ์œ ํšจ๊ธฐ๊ฐ„์„ ์„ค์ •ํ•œ ์ฑ„ ๋‹ด์•„๋†จ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  redirect Url์„ ๋ฉ”์ธํŽ˜์ด์ง€๋กœ ์ด๋™์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•ด์•ผํ•  ์‚ฌํ•ญ์€ ๋”ฑํžˆ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ ๊ทœ ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์‚ฌํ•ญ์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ ์„œ๋น„์Šค๋Š” ์‹ ๊ทœ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ธ๊ฐ€๋ฅผ ๋ฐ›๊ณ  ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์—์„œ ๊ธฐ๋ณธ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€ DB์— ์ €์žฅํ•˜๊ณ , ์ดํ›„ ํด๋ผ์ด์–ธํŠธ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ redirect(Url์— accessToken์„ ํฌํ•จ)ํ•˜์—ฌ ์ถ”๊ฐ€์ •๋ณด๋ฅผ ๋ฐ›์•„ ์ตœ์ข…์ ์œผ๋กœ ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ์‹ ๊ทœ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญํ›„ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์—์„œ ํšŒ์›๊ฐ€์ž…์„ ํ•˜์ง€ ์•Š๊ณ  ์ดํƒˆํ•˜๋Š” ์ผ€์ด์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ๊ฐ€? ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ํšŒ์› ์ •๋ณด๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— DB๋ฅผ ํ™•์ธํ•˜์—ฌ ํšŒ์›๊ฐ€์ž…ํ•˜์ง€ ์•Š์€ ์ •๋ณด๋ฅผ ๋งค๋ฒˆ ์ง€์›Œ์ฃผ๋Š” ๋กœ์ง์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €ํฌ๋Š” ๋ถˆํ•„์š”ํ•œ ์œ ์ € ์ •๋ณด๋ฅผ ์„œ๋ฒ„์—์„œ ํ™•์ธํ•˜์—ฌ ๋งค์ผ ์ง€์šฐ๋Š” ํ˜•์‹์œผ๋กœ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. (๋ฐฑ์—”๋“œ ํ˜„์—…์ž๋ถ„์ด ๋ณธ์ธ ์‹ค๋ฌด์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ–ˆ๋‹ค๊ณ  ๋ง์”€ํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๋ชจ๋ฒ”์‚ฌ๋ก€์ธ์ง€๋Š” ์ •ํ™•ํžˆ๋Š” ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค...)

ํ๋ฆ„ ์ •๋ฆฌ

  1. ์„œ๋ฒ„์—์„œ ์ธ์ฆ์ด ์™„๋ฃŒ๋˜๋ฉด, ํด๋ผ์ด์–ธํŠธ ์ฃผ์†Œ๋กœ redirectํ•ฉ๋‹ˆ๋‹ค.(์ด๋•Œ accessToken์„ queryparemeter์— ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค.)
  2. ๊ธฐ์กด ํšŒ์›์ผ ๊ฒฝ์šฐ ๋ฉ”์ธํŽ˜์ด์ง€, ์‹ ๊ทœ ํšŒ์›์ผ ๊ฒฝ์šฐ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ redirectํ•ฉ๋‹ˆ๋‹ค.
  3. ํด๋ผ์ด์–ธํŠธ์—์„œ queryparemeter์— ์žˆ๋Š” accessToken์„ ๋ธŒ๋ผ์šฐ์ € ์ €์žฅ์†Œ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์š”์ฒญ์—๋Š” header์— accessToken์„ ํฌํ•จํ•ด ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  4. ์‹ ๊ทœ ํšŒ์›์ด์ง€๋งŒ ํšŒ์› ๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ์ดํƒˆํ•  ๊ฒฝ์šฐ ์„œ๋ฒ„์—์„œ ํ•˜๋ฃจ ๋‹จ์œ„๋กœ ํ™•์ธํ•ด DB๋ฅผ ์ง€์›๋‹ˆ๋‹ค.

accessToken๊ณผ refreshToken

์ €์˜ ๊ฒฝ์šฐ accessToken์„ localStorage์— ์ €์žฅํ•˜๊ณ , ์ด๋ฅผ header๋‹ด์•„ ์„œ๋ฒ„์— ์š”์ฒญ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. localStorage์— ์ €์žฅํ–ˆ๋˜ ์ด์œ ๋Š” ํƒญ์„ ๋‹ซ๊ฑฐ๋‚˜, ๊ฐ•์ œ๋กœ ์ง€์šฐ์ง€ ์•Š๋Š” ์ด์ƒ ์‚ฌ๋ผ์ง€์ง€ ์•Š์•„ ๋กœ๊ทธ์ธ์„ ์œ ์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์ปธ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋ณด์•ˆ์ ์ธ ์š”์†Œ๋„ ์ƒ๊ฐํ•ด ๋ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

XSS๊ณต๊ฒฉ

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ๋ณด์ด๋Š” ์ทจ์•ฝ์  ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ, ์›น์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ ์ œ3์ž๊ฐ€ ์›น์‚ฌ์ดํŠธ์— ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•ด ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝ์ ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ € ์ €์žฅ์†Œ๋Š” window global๊ฐ์ฒด, ์ฆ‰ javascript๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๊ณ  XSS๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

++์ถ”๊ฐ€๋กœ React์—์„œ ์˜ ์ฒ˜๋ฆฌ

//์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ
const insertHtml = `<span><svg/onload=alert(origin)></span>`

const App = () => {
	
  return <div dangerouslySetInnerHTML={{ __html : insertHtml }}/>
}

dangerouslySetInnerHTML ์†์„ฑ์€ ํŠน์ • ๋ธŒ๋ผ์šฐ์ € DOM์˜ innerHTML์„ ํŠน์ • ๋‚ด์šฉ์œผ๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ insertHtml์ด๋ผ๋Š” ์•…์„ฑ ์ฝ”๋“œ๋ฅผ ์ œ3์ž๊ฐ€ ์‚ฝ์ž…ํ•˜๊ฒŒ ๋˜๋ฉด div์— ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค react์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ XSS๋ฅผ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•œ ์ด์Šค์ผ€์ดํ•‘ ์ž‘์—…์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

const insertHtml = `<span><svg/onload=alert(origin)></span>`
const App = () => {
	return <div id={html}>{html}</div>
}

์ด์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌ ํ–ˆ๋‹ค๋ฉด ์‹ค์ œ Html์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ž์˜ ํ™œ์šฉ๋„์— ๋”ฐ๋ผ ์›๋ณธ ๊ฐ’์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— dangerouslySetInnerHTML์†์„ฑ์œผ๋กœ ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ์ฒ˜๋ฆฌ ํ•ด๋†จ์Šต๋‹ˆ๋‹ค.


CSRF๊ณต๊ฒฉ

์ œ3์ž๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ(cross site)์—์„œ ์‚ฌ์ดํŠธ์— API์ฝœ์„ ์š”์ฒญํ•ด ์‹คํ–‰ํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. ์ œ3์ž๋Š” ์œ ์ €์˜ ๊ถŒํ•œ์œผ๋กœ ํŠน์ • ํ–‰์œ„๋ฅผ ํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์—ฌ ์„œ๋ฒ„์— ์š”์ฒญํ•˜์—ฌ ํ”ผํ•ด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ณดํ†ต ์€ํ–‰๊ถŒ์—์„œ ํ”ผํ•ด ์‚ฌ๋ก€๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ3์ž๊ฐ€ ํ”ผํ•ด์ž์˜ ๊ถŒํ•œ์œผ๋กœ ํŠน์ • ๊ณ„์ขŒ๋กœ ์ด์ฒดํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ๊ณต๊ฒฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ๊ณต๊ฒฉ๋“ค์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ํ† ํฐ์„ ์–ด๋””์— ์ €์žฅํ•˜๋ƒ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ๋ณด์•ˆ ์กฐ์ทจ๊ฐ€ ์ด๋ค„์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์–ด๋–ป๊ฒŒ ์ €์žฅํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ์žฅ๋‹จ์ ์ด ์žˆ๊ณ  ์˜๊ฒฌ์ด ๋ถ„๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ˜… ํ† ํฐ์„ localStorage์— ์ €์žฅํ•˜์ž

cookie์— ํ† ํฐ์„ ์ €์žฅํ•˜๊ฒŒ ๋˜๋ฉด Http์š”์ฒญ์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ์ „์†ก๋˜๋Š” ์ ๊ณผ jsํ”„๋ ˆ์ž„์›Œํฌ ๋“ค์€ XSS๊ณต๊ฒฉ์— ๋Œ€ํ•œ ์ด์Šค์ผ€์ดํ•‘ ๊ธฐ๋Šฅ์ด ๊ฐ•๋ ฅํ•˜๋‹ค๋ผ๋Š” ์ ์—์„œ csrf๊ณต๊ฒฉ์„ ๋” ์ค‘์š”์‹œํ•ด์•ผ ํ•œ๋‹ค๋ผ๋Š” ์˜๊ฒฌ์ž…๋‹ˆ๋‹ค.

๐Ÿ˜ ํ† ํฐ์„ ์ฟ ํ‚ค์— ์ €์žฅํ•˜์ž

ํ† ํฐ์„ ํ† ํฐ์— ์ €์žฅํ•˜๋Š”๊ฒŒ ํ˜„๋ช…ํ•˜๋‹ค๋Š” ์˜๊ฒฌ.
์š”์•ฝ - ์›น ์ €์žฅ์†Œ์— ํ† ํฐ์„ ์ €์žฅํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ XSS๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜๋ฉฐ, jsํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ด์Šค์ผ€์ดํ•‘ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋ชจ๋“  ์ทจ์•ฝ์ ์„ ๋‹ค๋ฃจ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์›น ์Šคํ† ๋ฆฌ์ง€๋Š” ์–ด๋– ํ•œ ๋ณด์•ˆ ํ‘œ์ค€๋„ ์‹œํ–‰๋˜๊ณ  ์žˆ์ง€ ์•Š์ง€๋งŒ ์ฟ ํ‚ค๋Š” ์—ฌ๋Ÿฌ ๋ณด์•ˆ ์†”๋ฃจ์…˜์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์ฟ ํ‚ค๋Š” XSS๊ณต๊ฒฉ์— ๋Œ€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก httpOnly์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ๊ฐ™์€ ์‚ฌ์ดํŠธ์—์„œ์˜ ์š”์ฒญ์ธ์ง€ ํŒ๋‹จํ•˜๋Š” same-site์˜ต์…˜๊ณผ httpsํ†ต์‹  ํ•  ๋•Œ๋งŒ ์ฟ ํ‚ค๋ฅผ ํ—ˆ์šฉํ•˜๋Š” secure์˜ต์…˜ ๋“ฑ์„ ํ†ตํ•ด ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ด€๋ จ ๋งํฌ

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ† ํฐ์„ ์ฟ ํ‚ค์— ์ €์žฅํ•ด๋†“๊ณ  ์œ„์—์„œ ๋‚˜์—ดํ•œ ์˜ต์…˜๋“ค์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋ณด์•ˆ์š”์†Œ๋ฅผ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

Refreshํ† ํฐ์˜ ๊ด€๋ฆฌ

accessToken์€ ๊ฒฐ๊ตญ http์˜ stateless, connectionless ์„ฑ๊ฒฉ์„ ์ž˜ ์ด์šฉํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ์ด ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ์ธก ์ฟ ํ‚ค์— ์ €์žฅํ•ด์•ผ ๋˜๋ฉฐ, ์ด๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๋…ธ์ถœ์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— refresh token์„ ์ถ”๊ฐ€์ ์œผ๋กœ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

refreshToken์€ accessToken์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ ์žฌ๋ฐœ๊ธ‰์„ ์œ„ํ•œ ํ† ํฐ์ด๋ผ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ต์‹ฌ์€ accessToken์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ์ตœ๋Œ€ํ•œ ์งง๊ฒŒ ์ฃผ๊ณ  refreshToken์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ๊ธธ๊ฒŒ ๊ฐ€์ ธ๊ฐ€ accessToken์ด ๋…ธ์ถœ๋˜๋”๋ผ๋„ ์‰ฝ๊ฒŒ ์ œ3์ž๊ฐ€ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ๋ช… IT๊ธฐ์—…์˜ ํ† ํฐ ์œ ํšจ์‹œ๊ฐ„

ํ† ํฐ์˜ ์œ ํšจ ์‹œ๊ฐ„์€ ์ทจํ–ฅ์ฐจ์ด...??

๊ทธ๋ ‡๋‹ค๋ฉด refreshํ† ํฐ์€ ์–ด๋””์— ์ €์žฅํ•˜๋Š” ๊ฒŒ ์ข‹์„๊นŒ์š”??

๐Ÿ˜… DB

ํ˜„์žฌ ์„œ๋ฒ„ DB์— ๋กœ๊ทธ์ธ ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. accessToken์ด ๋งŒ๋ฃŒ ๋˜์—ˆ์„ ๋•Œ refreshToken์„ ์กฐํšŒํ•˜๊ณ  accessToken์„ ์žฌ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์š”์ฒญํ•˜๊ฒŒ ๋˜๋ฉด DB์— ์ €์žฅํ•œ๋‹ค๋ฉด ํ† ํฐ์„ ์กฐํšŒํ•˜๋Š”๋ฐ ๋งŽ์€ ๋ถ€๋‹ด์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

accessToken๋งŒ๋ฃŒ ์‹œ๊ฐ„์ด 10๋ถ„์ด๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ 100์ด 1์‹œ๊ฐ„ ๋™์•ˆ ์„œ๋น„์Šค ์ด์šฉํ•  ๋•Œ => ์ฟผ๋ฆฌ ์š”์ฒญ ์•ฝ 600๋ฒˆ

๋˜ํ•œ DB์— ์ €์žฅ๋œ refreshํ† ํฐ์ด ๋งŒ๋ฃŒ๋œ๋‹ค๋ฉด ์ฃผ๊ธฐ์ ์œผ๋กœ ์ด ํ† ํฐ์„ ์‚ญ์ œํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋Š” ๋“ฑ์˜ ์ฃผ๊ธฐ์ ์ธ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์šฉ๋„๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ถ”์ฒœ๋“œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐Ÿ˜ Redis(์ถ”์ฒœ)


๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Redis์— ์ €์žฅํ•˜๋Š” ๋ฐฉ์•ˆ์ž…๋‹ˆ๋‹ค. Redis๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ(์ผ๋ฐ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฒฝ์šฐ SSD,HDD๊ฐ™์€ ๋ณด์กฐ๊ธฐ์–ต์žฅ์น˜์ด์ง€๋งŒ Redis๋Š” RAM)์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋””์Šคํฌ ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ณด๋‹ค ๋น ๋ฅธ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ฆ ์‹œ์Šคํ…œ์—์„œ ๋งŽ์€ ์š”์ฒญ์„ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ฃผ๋ชฉํ•ด์•ผ ํ• ์ ์€ ์บ์‹œ์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ์„ธํŒ…ํ•ด ๋†“์„ ์ˆ˜ ์žˆ์–ด ์ง์ ‘ DB์— ์ ‘๊ทผํ•ด ์ง€์šธ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ฃผ๊ธฐ์ ์œผ๋กœ DB์— ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ์ธ์ฆ,์ธ๊ฐ€ ๋ฐฉ์‹์—๋Š” Redis๋ฅผ ์‚ฌ์šฉ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


๋„ˆ๋ฌด ๋ธ”๋กœ๊ทธ๊ธ€์„ ๋งน์‹ ํ•˜์ง€๋Š” ๋ง์ž...

์†Œ์…œ ๋กœ๊ทธ์ธ์„ ๋‹ค๋ฃจ๋Š” ๋งŽ์€ ๋ธ”๋กœ๊ทธ๊ธ€๋“ค์„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์ฒด๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์€ ๋น„์Šทํ•œ๊ฒƒ์ด ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—์„œ ํ† ํฐ์ด๋‚˜ ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ์‹œํ‚ค๊ณ  ๋ฐฑ์—”๋“œ์— ์ „์†กํ•œ ํ›„ ๋ฆฌ์†Œ์Šค์„œ๋ฒ„์— ์ธ์ฆ๋ฐ›๋Š” ๋ฐฉ์‹์ด ๋งŽ์•˜๋Š”๋ฐ์š”. ์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ด ๋ฐฉ์‹์ด ์˜ณ์€ ๊ฒƒ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.(๊ทธ๋ ‡๋‹ค๊ณ  ์ œ ํ•ด๊ฒฐ ๋ฐฉ์‹์ด ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ผ๊ณ  ๋ง์”€์€ ๋“œ๋ฆฌ์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค...)

๊ฐœ๋ฐœ์ž์˜ ๊ณต๊ธ‰์ด ๋งŽ์•„์ง€๋ฉด์„œ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜์‹œ๋Š” ๋ถ„์ด ๋งŽ์•„์กŒ์Šต๋‹ˆ๋‹ค. ๊ณ ํ€„๋ฆฌํ‹ฐ์˜ ๊ธ€๋ถ€ํ„ฐ ํ—ˆ๋ฌด๋งน๋ž‘ํ•œ ๊ธ€๊นŒ์ง€ ๋‹ค์–‘ํ•œ ๊ธ€์ด ์žˆ์—ˆ๋Š”๋ฐ์š”. ๋‹จ์ˆœํžˆ ์–ด๋–ค ์ •๋ณด๋ฅผ ์„œ์นญํ•  ๋•Œ ๋‹จ์ˆœํžˆ ๋ช‡๊ฐœ์˜ ๊ธ€ ๊ฐ€์ง€๊ณ  ํŒ๋‹จํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ๋˜๋„๋ก ๋‹ค์–‘ํ•œ ๊ธ€์„ ํ†ตํ•ด ์ •๋ณด๋ฅผ ์Šต๋“ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

reference

https://velog.io/@ch4570/OAuth-2.0-JWT-Spring-Security%EB%A1%9C-%ED%9A%8C%EC%9B%90-%EA%B8%B0%EB%8A%A5-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0-OAuth-2.0%EC%9D%84-%EC%84%A0%ED%83%9D%ED%95%9C-%EC%9D%B4%EC%9C%A0
https://nordvpn.com/ko/blog/csrf/

๐Ÿ‘ํ”ผ๋“œ๋ฐฑ์€ ์–ธ์ œ๋“ ์ง€ ํ™˜์˜์ž…๋‹ˆ๋‹ค~!

profile
์‚ฌ์ง„์ฐ๋Š” ๊ฐœ๋ฐœ์ž.

0๊ฐœ์˜ ๋Œ“๊ธ€