Learn-json-web-tokens: ๋ณด์•ˆ ์ทจ์•ฝ์ 

์— ๋งŒ๋“  2019๋…„ 01์›” 04์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dwyl/learn-json-web-tokens

์ œ์•ˆ ์‚ฌํ•ญ: XSS, CSRF ๋“ฑ ํด๋ผ์ด์–ธํŠธ ์ธก(cookie/localStorage)์˜ ๋‹ค์–‘ํ•œ JWT ์ €์žฅ ๋ฐฉ๋ฒ•์— ๋ณด์•ˆ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

discuss enhancement help wanted

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@nelsonic

JWT์— ์ ์šฉ๋˜๋Š” ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ํ† ํฐ ์ฒด๊ณ„์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋„๋ฉ”์ธ์—์„œ XSS ๊ณต๊ฒฉ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ JWT๋ฅผ ํš๋“ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€๊ณ„์—†์ด ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•…์„ฑ JS๋Š” ์ฟ ํ‚ค์™€ localStorage๋ฅผ ์‰ฝ๊ฒŒ ์ฝ๊ณ  ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ถ„์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ JWT๋ฅผ ํš๋“ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” httpOnly ๋ฐ secure ์ฟ ํ‚ค์™€ ๊ฐ™์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ XSS ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ(ํ† ํฐ์„ ํ›”์น˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•…์˜์ ์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋“ฑ) ์ด๊ฒƒ์œผ๋กœ ์•„๋ฌด ๊ฒƒ๋„ ๋ณดํ˜ธํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฐ ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ localStorage ๋ฅผ ์‚ฌ์šฉํ•˜๋“  cookie ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์ƒ๊ด€์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. OWASP ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋“ค๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ๋ฅผ ๋ฐ›๋Š”๋‹ค๋ฉด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘์—์„œ ์•ˆ์ „ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ฝ๊ฐ„์˜ PR์„ ์ค€๋น„ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ง€๊ธˆ์€ ์‹œ๊ฐ„์ด ์ด‰๋ฐ•ํ•˜๊ณ  ์•ž์œผ๋กœ 1-2๊ฐœ์›” ์•ˆ์— ์ž์œ ๋กœ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ฐ€ ์ €๋ณด๋‹ค ๋ชป๋›ฐ๋ฉด ํ™๋ณด ์ข€ ํ• ๊ฒŒ์š” ๐Ÿ˜„

๋ชจ๋“  3 ๋Œ“๊ธ€

@sarneeh ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ‘
ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์‹œ๊ฐ„์ด ์žˆ๋‹ค๋ฉด ๊ฐ€์‹ญ์‹œ์˜ค! (_์ด ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค_)

JWT์— ์ ์šฉ๋˜๋Š” ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ํ† ํฐ ์ฒด๊ณ„์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋„๋ฉ”์ธ์—์„œ XSS ๊ณต๊ฒฉ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ JWT๋ฅผ ํš๋“ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€๊ณ„์—†์ด ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•…์„ฑ JS๋Š” ์ฟ ํ‚ค์™€ localStorage๋ฅผ ์‰ฝ๊ฒŒ ์ฝ๊ณ  ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ OWASP ๊ณต๊ฒฉ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜์ง€ ์•Š์œผ๋ฉฐ ์„œ๋ช…๋œ ํด๋ ˆ์ž„/๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” _ํŽธ๋ฆฌํ•œ_ ๋ฐฉ๋ฒ•์ผ ๋ฟ์ž„์„ ์•Œ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“

@nelsonic

JWT์— ์ ์šฉ๋˜๋Š” ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ํ† ํฐ ์ฒด๊ณ„์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋„๋ฉ”์ธ์—์„œ XSS ๊ณต๊ฒฉ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ JWT๋ฅผ ํš๋“ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€๊ณ„์—†์ด ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•…์„ฑ JS๋Š” ์ฟ ํ‚ค์™€ localStorage๋ฅผ ์‰ฝ๊ฒŒ ์ฝ๊ณ  ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ถ„์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ JWT๋ฅผ ํš๋“ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” httpOnly ๋ฐ secure ์ฟ ํ‚ค์™€ ๊ฐ™์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ XSS ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ(ํ† ํฐ์„ ํ›”์น˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•…์˜์ ์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋“ฑ) ์ด๊ฒƒ์œผ๋กœ ์•„๋ฌด ๊ฒƒ๋„ ๋ณดํ˜ธํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฐ ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ localStorage ๋ฅผ ์‚ฌ์šฉํ•˜๋“  cookie ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์ƒ๊ด€์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. OWASP ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋“ค๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ๋ฅผ ๋ฐ›๋Š”๋‹ค๋ฉด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘์—์„œ ์•ˆ์ „ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ฝ๊ฐ„์˜ PR์„ ์ค€๋น„ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ง€๊ธˆ์€ ์‹œ๊ฐ„์ด ์ด‰๋ฐ•ํ•˜๊ณ  ์•ž์œผ๋กœ 1-2๊ฐœ์›” ์•ˆ์— ์ž์œ ๋กœ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ฐ€ ์ €๋ณด๋‹ค ๋ชป๋›ฐ๋ฉด ํ™๋ณด ์ข€ ํ• ๊ฒŒ์š” ๐Ÿ˜„

@sarneeh ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์‹œ๊ฐ„์ด ์žˆ๋‹ค๋ฉด ๊ฐ€์‹ญ์‹œ์˜ค! (_์ด ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค_)

JWT์— ์ ์šฉ๋˜๋Š” ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ํ† ํฐ ์ฒด๊ณ„์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋„๋ฉ”์ธ์—์„œ XSS ๊ณต๊ฒฉ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ JWT๋ฅผ ํš๋“ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€๊ณ„์—†์ด ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•…์„ฑ JS๋Š” ์ฟ ํ‚ค์™€ localStorage๋ฅผ ์‰ฝ๊ฒŒ ์ฝ๊ณ  ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ OWASP ๊ณต๊ฒฉ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜์ง€ ์•Š์œผ๋ฉฐ ์„œ๋ช…๋œ ํด๋ ˆ์ž„/๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” _ํŽธ๋ฆฌํ•œ_ ๋ฐฉ๋ฒ•์ผ ๋ฟ์ž„์„ ์•Œ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด ์ฟ ํ‚ค๋Š” httpOnly ์˜ต์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ธฐ์‚ฌ ์— ๋”ฐ๋ฅด๋ฉด httponly ์ฟ ํ‚ค ๋Œ€์‹  localstorage๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰