Web Security: SOP์™€ CORS

0

Web Security

๋ชฉ๋ก ๋ณด๊ธฐ
1/1
post-thumbnail

๐Ÿ“Œ 1. SOP(Same-origin Policy)๋ž€?


๐Ÿ“Ž SOP๋ž€?

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same-origin Policy)์€ ์–ด๋–ค ์ถœ์ฒ˜์—์„œ ๋ถˆ๋Ÿฌ์˜จ ๋ฌธ์„œ๋‚˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๊ฐ€์ ธ์˜จ ๋ฆฌ์†Œ์Šค์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๋Š” ์ค‘์š”ํ•œ ๋ณด์•ˆ ๋ฐฉ์‹์ด๋‹ค.

๐Ÿ“Ž SOP์˜ ํ•„์š”์„ฑ

์ธํ„ฐ๋„ท์ƒ์˜ ์•…์˜์ ์ธ ์‚ฌ์ดํŠธ๋“ค์˜ ๊ณต๊ฒฉ๋“ค๊ณผ ์ž ์žฌ์ ์œผ๋กœ ํ•ด๋กœ์šธ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๊ฒฉ๋ฆฌํ•ด ๋ณด์•ˆ ์œ„ํ˜‘์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ๋‹ค.

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

๋•Œ๋ฌธ์— SOP์™€ ๋”๋ถˆ์–ด CORS๋Š” ์•…์˜์ ์ธ ๊ณต๊ฒฉ์„ ๋ง‰๋Š” ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ์กด์žฌ๋“ค์ด๋‹ค.

๐Ÿ“Ž ์ถœ์ฒ˜(Origin)๋ž€?

SOP์—์„œ ์ด์•ผ๊ธฐํ•˜๋Š” ์ถœ์ฒ˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋จผ์ € ์‚ดํŽด๋ณด๊ธฐ ์ „์— URL ๊ตฌ์กฐ๋ฅผ ์•Œ๊ณ  ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. URL ๊ตฌ์กฐ๋Š” ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™๋‹ค.
ํ”„๋กœํ† ์ฝœ์˜ HTTP๋Š” 80๋ฒˆ, HTTPS๋Š” 443๋ฒˆ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, 80๋ฒˆ๊ณผ 443๋ฒˆ ํฌํŠธ๋Š” ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ถœ์ฒ˜๋Š”, ์œ„ URL ๊ตฌ์กฐ์—์„œ ์‚ดํŽด๋ณธ Protocol, Host, Port๋ฅผ ํ•ฉ์นœ ๊ฒƒ์„ ๋งํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ์ฝ˜์†” ์ฐฝ์— location.origin๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Ž ๋™์ผ ์ถœ์ฒ˜(Same-origin)์˜ ์ •์˜

์š”์ฒญํ•œ ์ถœ์ฒ˜์™€ ์‘๋‹ตํ•  ์ถœ์ฒ˜๋ฅผ ๋น„๊ตํ•ด์„œ Protocal, host, port๊ฐ€ ๊ฐ™๋‹ค๋ฉด ๋™์ผ์ถœ์ฒ˜(Same-origin)์ด๋ผ๊ณ  ํ•œ๋‹ค.

์•„๋ž˜ ํ‘œ๋Š” https://news.google.com์™€ ๋™์ผ ์ถœ์ฒ˜(Same Origin)์ธ๊ฐ€๋ฅผ ๋น„๊ตํ•œ ๊ฒƒ์ด๋‹ค.

URL๊ฒฐ๊ณผ์ด์œ 
https://news.google.com/other.html ์„ฑ๊ณต๊ฒฝ๋กœ๋งŒ ๋‹ค๋ฅธ๊ฑด ๊ดœ์ฐฎ์Œ
https://news.google.com:8080์‹คํŒจํฌํŠธ๊ฐ€ ๋‹ค๋ฆ„
http://news.google.com์‹คํŒจํ”„๋กœํ† ์ฝœ์ด ๋‹ค๋ฆ„
https://coin.google.com์‹คํŒจํ˜ธ์ŠคํŠธ๊ฐ€ ๋‹ค๋ฆ„

๐Ÿ“Ž ์ถœ์ฒ˜(Origin)์˜ ์ƒ์†

about:blank์™€ javascript: URL์€ ์ถœ์ฒ˜ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ URL์—์„œ ์‹คํ–‰ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•ด๋‹น URL์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฌธ์„œ์˜ ์ถœ์ฒ˜๋ฅผ ์ƒ์†ํ•œ๋‹ค.

๐Ÿ“Ž Internet Explorer์—์„œ ์˜ˆ์™ธ์‚ฌํ•ญ

๐Ÿ‘‰ Trust Zones: ์–‘์ชฝ ๋„๋ฉ”์ธ ๋ชจ๋‘๊ฐ€ ๋†’์€ ๋‹จ๊ณ„์˜ ๋ณด์•ˆ ์ˆ˜์ค€์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ๋™์ผ ์ถœ์ฒ˜ ์ œ์•ฝ์„ ์ ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
๐Ÿ‘‰ Port: ํฌํŠธ๋ฒˆํ˜ธ๋Š” Origin์„ ์ฒดํฌํ•  ๋•Œ ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ๋‹ค๋ฅธ ํฌํŠธ๋กœ ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Ž ์ถœ์ฒ˜(Origin)์˜ ๋ณ€๊ฒฝ

document.domain์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์•ฝ๊ฐ„์˜ ์ œํ•œ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ณด์•ˆ์ ์ธ ์ด์œ ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ“Ž Cross-origin ์ ‘๊ทผ ์ฒ˜๋ฆฌ

SOP๋Š” ๊ต์ฐจ์ ‘๊ทผ(Cross-origin)์— ๋Œ€ํ•ด 3๊ฐ€์ง€ ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ๊ฐ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • ์“ฐ๊ธฐ: ์ผ๋ฐ˜์ ์œผ๋กœ ํ—ˆ์šฉํ•œ๋‹ค. ์ผ๋ถ€ HTTP์š”์ฒญ์€ CORS์˜ preflight๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
    • ๋งํฌ, ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ, ํผ ์ œ์ถœ
    • <a>
    • <form>์œผ๋กœ ๋‹ค๋ฅธ origin์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋Š” ์ž‘์—…
  • ์ž„๋ฒ ๋”ฉ: ์ผ๋ฐ˜์ ์œผ๋กœ ํ—ˆ์šฉํ•œ๋‹ค.
    • <script src="..."></script>
    • <link rel="stylesheet" href="โ€ฆ">
    • <img>, <video>, <audio>, <object>, <embed>
    • @font-free
    • <iframe>
  • ์ฝ๊ธฐ: ์ผ๋ฐ˜์ ์œผ๋กœ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • ๋ณดํ†ต JavaScript์ฝ”๋“œ๋กœ ์ ‘๊ทผํ•˜๋Š” ํ–‰์œ„๋“ค์ด ํ•ด๋‹น๋œ๋‹ค.
    • JavaScript๋กœ iframe๋‚ด์˜ document์— ์ ‘๊ทผ
    • JavaScript๋กœ canvas๋‚ด์— ๋‹ค๋ฅธ origin์˜ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ž‘์—…
    • JavaScript๋กœ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋ฅผ fetchํ•˜๋Š” ์ž‘์—…


๐Ÿ“Œ 2. CORS(Cross-Origin Resource Sharing)๋ž€?


๐Ÿ“Ž CORS๋ž€?

๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Cross-origin Resource Sharing)๋Š” HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ด๋‹ค.

๐Ÿ“Ž CORS ๋™์ž‘ ์ข…๋ฅ˜

CORS์˜ ๋™์ž‘ ๋ฐฉ์‹์€ Simple Request(๋‹จ์ˆœ ์š”์ฒญ ๋ฐฉ๋ฒ•)๊ณผ Preflight Request(์˜ˆ๋น„ ์š”์ฒญ)์„ ๋จผ์ € ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ• 2๊ฐ€์ง€๊ฐ€ ๋Œ€ํ‘œ์ ์œผ๋กœ ์กด์žฌํ•œ๋‹ค.

๐Ÿ‘‰ Simple Request(๋‹จ์ˆœ ์š”์ฒญ)

๋‹จ์ˆœ ์š”์ฒญ ๋ฐฉ๋ฒ•์€ ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญ์„ ๋ฐ”๋กœ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • Simple Request ๋™์ž‘ ๋ฐฉ๋ฒ•: ๋‹จ์ˆœ ์š”์ฒญ์€ ์„œ๋ฒ„์— API๋ฅผ ์š”์ฒญํ•˜๊ณ , ์„œ๋ฒ„๋Š” Access-control-Allow-Origin ํ—ค๋”๋ฅผ ํฌํ•จํ•œ ์‘๋‹ต์„ ๋ธŒ๋ผ์šฐ์ €์— ๋ณด๋‚ธ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ํ™•์ธํ•ด์„œ CORS ๋™์ž‘์„ ์ˆ˜ํ–‰ํ• ์ง€ ํŒ๋‹จํ•œ๋‹ค.

  • Simple Request ์กฐ๊ฑด: ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ์ด 3๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ์ด ๋‹จ์ˆœ ์š”์ฒญ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

    • ์š”์ฒญ ๋ฉ”์†Œ๋“œ๋Š” GET, HEAD, POST ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.
    • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width๋ฅผ ์ œ์™ธํ•œ ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
    • Content-Type ํ—ค๋”๋Š” application/x-www-form-urlencoded, multipart/form-data, text/plain ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰ Preflight Request(์˜ˆ๋น„ ์š”์ฒญ)

Preflight ์š”์ฒญ์€ ์„œ๋ฒ„์— ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ด์„œ ์•ˆ์ „ํ•œ์ง€ ํŒ๋‹จํ•œ ํ›„ ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • OPTIONS๋ฉ”์†Œ๋“œ๋กœ ์„œ๋ฒ„์— ์˜ˆ๋น„ ์š”์ฒญ์„ ๋จผ์ € ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„๋Š” ์ด ์˜ˆ๋น„ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ Access-control-Allow-Origin ํ—ค๋”๋ฅผ ํฌํ•จํ•œ ์‘๋‹ต์„ ๋ธŒ๋ผ์šฐ์ €์— ๋ณด๋‚ธ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹จ์ˆœ ์š”์ฒญ๊ณผ ๋™์ผํ•˜๊ฒŒ Access-control-Allow-Origin ํ—ค๋”๋ฅผ ํ™•์ธํ•ด์„œ CORS ๋™์ž‘์„ ์ˆ˜ํ–‰ํ• ์ง€ ํŒ๋‹จํ•œ๋‹ค.
  • 2๋ฒˆ์ด๋‚˜ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์„œ๋ฒ„์— ๋ถ€๋‹ด์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ์„ธ์ƒ์— ์žˆ๋Š” ๋ชจ๋“  ์„œ๋ฒ„๊ฐ€ CORS๋ฅผ ์ธ์ง€ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. CORS๋ฅผ ๋ชจ๋ฅด๋Š” ์„œ๋ฒ„์— ๋‹จ์ˆœ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ค„ ์ˆ˜ ์—†๋‹ค๊ณ  ํ•˜๋”๋ผ๋„ ์š”์ฒญ์ด ์ง„ํ–‰๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์˜ˆ๋น„ ์š”์ฒญ์„ ํ†ตํ•ด ์–ด๋– ํ•œ ์„œ๋ฒ„๋“  ์•ˆ์ „ํ•œ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์˜ˆ๋น„ ์‘๋‹ต ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•œ ๊ฒƒ์ด๋‹ค.

๐Ÿ“Ž CORS์˜ Credentials์— ๋”ฐ๋ฅธ ๋ถ„๋ฅ˜

CORS๋Š” ๋™์ž‘ ๋ฐฉ์‹์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง€๊ธฐ๋„ ํ•˜์ง€๋งŒ, ์ธ์ฆ ์ •๋ณด ๋ฐ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•˜๋Š” ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‚˜๋ˆ„์–ด์ง€๊ธฐ๋„ ํ•œ๋‹ค.

๐Ÿ‘‰ Credential

  • HTTP Cookie์™€ HTTP Authentication ์ •๋ณด๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์š”์ฒญ
  • xhr.withCredentials=true

๐Ÿ‘‰ Non-credential

  • HTTP Cookie์™€ HTTP Authentication ์ •๋ณด๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์—†๋Š” ์š”์ฒญ
  • xhr.withCredentials=false

๐Ÿ“Ž Credentials์˜ 3๊ฐ€์ง€ ์˜ต์…˜

๋งŒ์•ฝ, ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ๋กœ์˜ ์š”์ฒญ์— ์ฟ ํ‚ค์™€ ๊ฐ™์€ ์ธ์ฆ์ •๋ณด๋ฅผ ํฌํ•จ์‹œํ‚ค๊ณ  ์‹ถ์œผ๋ฉด credentials: 'include'์„ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ์™ธ์—๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ์˜ต์…˜์ด ์กด์žฌํ•œ๋‹ค.

  1. Same-origin: ๊ฐ™์€ ์ถœ์ฒ˜ ๊ฐ„ ์š”์ฒญ์—๋งŒ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค.
  2. Include: ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค.
  3. Omit: ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ“Ž Credentials์˜ ๋™์ž‘ ์กฐ๊ฑด

  1. Access-Control-Allow-Origin: * ์ด๋ฉด ์•ˆ๋˜๋ฉฐ, ๋ช…์‹œ์ ์ธ URL์„ ์„ค์ •ํ•˜์—ฌํ– ํ•œ๋‹ค.
    ex) Access-Control-Allow-Origin: https://xxx.com
  2. ์‘๋‹ต ํ—ค๋”์—๋Š” ๋ฐ˜๋“œ์‹œ Access-Control-Allow-Credentials: true๊ฐ€ ์กด์žฌํ•ด์•ผํ•œ๋‹ค.


๐Ÿ“– ์ถœ์ฒ˜

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