๐ก๏ธ Same Origin Policy (SOP)๋?
SOP(๋์ผ ์ถ์ฒ ์ ์ฑ )๋ ์น ๋ธ๋ผ์ฐ์ ์์ ๋ณด์ ๊ฐํ๋ฅผ ์ํด ์ ์ฉํ๋ ์ ์ฑ ์ผ๋ก, ๋ค๋ฅธ ์ถ์ฒ(Origin)์์ ๋ถ๋ฌ์จ ๋ฆฌ์์ค๊ฐ ํ์ฌ ์น ํ์ด์ง์ ๋ฐ์ดํฐ์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ์ ํํ๋ ์ญํ ์ ํฉ๋๋ค.
๐น Origin(์ถ์ฒ) ์ ์
Origin์ ๋ค์ ์ธ ๊ฐ์ง ์์๊ฐ ์์ ํ ์ผ์นํด์ผ ๋์ผํ ์ถ์ฒ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ ์์
ํ๋กํ ์ฝ (Protocol / Scheme) | http:// vs. https:// |
ํธ์คํธ (Host / Domain) | example.com vs. api.example.com |
ํฌํธ (Port) | http://example.com:80 vs. http://example.com:8080 |
โ ๊ฐ์ Origin์ ์์
https://www.example.com:443
https://www.example.com:443/somepage
โ ๋ค๋ฅธ Origin์ ์์
https://www.example.com:443 โ http://www.example.com:443 (ํ๋กํ ์ฝ ๋ค๋ฆ)
https://www.example.com:443 โ https://api.example.com:443 (ํธ์คํธ ๋ค๋ฆ)
https://www.example.com:443 โ https://www.example.com:8080 (ํฌํธ ๋ค๋ฆ)
๐ SOP ์์ธ: ์ํฅ์ ๋ฐ์ง ์๋ ์์
์น ํ์ด์ง์์ ์ธ๋ถ ์์์ ๋ถ๋ฌ์ฌ ๋ SOP๊ฐ ์ ์ฉ๋์ง ์๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
<img>, <script>, <link>์ ๊ฐ์ ํ๊ทธ๋ค์ ์ธ๋ถ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒ๋ง ๊ฐ๋ฅํ ๋ฟ, JS์์ ์ง์ ์ ๊ทผํ ์๋ ์์ต๋๋ค.
→ ์ด๋ฐ ๋ฆฌ์์ค๋ค์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ๋ก๋ํ๊ธฐ ๋๋ฌธ์ SOP ์ ํ ์์ด ๋์ํฉ๋๋ค.
๐ SOP ์์ธ: Cross-Origin Resource Sharing (CORS)
์น ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ณด์ ์ ์ฑ
์ ์ํํด ๋ค๋ฅธ ์ถ์ฒ์ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํด์ผ ํ ๊ฒฝ์ฐ,
CORS (๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ ) ๋ผ๋ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํฉ๋๋ค.
๐น CORS ์๋ ๋ฐฉ์
1๏ธโฃ ํด๋ผ์ด์ธํธ(์น ๋ธ๋ผ์ฐ์ ) ๊ฐ https://api.example.com์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํจ.
2๏ธโฃ ์๋ฒ(api.example.com) ๊ฐ ํน์ ์ถ์ฒ์ ์์ฒญ์ ํ์ฉํ๋ฉด ์๋ต ํค๋์ Access-Control-Allow-Origin์ ํฌํจ์ํด.
Access-Control-Allow-Origin: https://www.example.com
3๏ธโฃ ํ์ฉ๋ Origin์์ ์จ ์์ฒญ์ด๋ผ๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํจ.
โ CORS ํ์ฉ ์์
GET /data HTTP/1.1
Host: api.example.com
Origin: https://www.example.com
---
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
โ ๏ธ CORS Preflight (์ฌ์ ์์ฒญ)
POST, PUT, DELETE ๋ฑ์ ๋ฏผ๊ฐํ ์์ฒญ์ ๋ณด๋ด๊ฑฐ๋, ํน์ ํค๋๋ฅผ ์ถ๊ฐํ ๊ฒฝ์ฐ
๋ธ๋ผ์ฐ์ ๋ OPTIONS ์์ฒญ์ ๋จผ์ ๋ณด๋ด์ ์๋ฒ๊ฐ ํ์ฉํ๋์ง ํ์ธํ๋ ๊ณผ์ (CORS Preflight)์ ๊ฑฐ์นฉ๋๋ค.
โ Preflight ์์ฒญ ์์
OPTIONS /data HTTP/1.1
Origin: https://www.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
โ ์๋ฒ ์๋ต ์์
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: Content-Type
โ๏ธ ์๋ฒ๊ฐ POST ๋ฉ์๋์ Content-Type ํค๋๋ฅผ ํ์ฉํ๋ค๊ณ ์๋ตํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ๋ณธ ์์ฒญ์ ์งํํจ.
โ๏ธ JSONP (JSON with Padding)
๐ก JSONP๋ CORS๊ฐ ์๋ ์์ ์ฌ์ฉ๋๋ ์ฐํ ๋ฐฉ๋ฒ์ผ๋ก, <script> ํ๊ทธ๊ฐ SOP์ ์ํฅ์ ๋ฐ์ง ์๋ ์ ์ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฐฉ์์ ๋๋ค.
โ JSONP ์์ฒญ ๋ฐฉ์
<script src="https://other.com/data?callback=myCallback"></script>
- ์๋ฒ๊ฐ callback์ ํด๋นํ๋ ํจ์๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ธ์ ๋ฐํํจ. ์ฆ, ์๋ฒ์๊ฒ "myCallback์ด๋ผ๋ ํจ์๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ธ์ ๋ณด๋ด๋ฌ๋ผ" ๋ผ๊ณ ์์ฒญํ๋ ๊ฒ.
โ ์๋ฒ ์๋ต ์์
myCallback({"name": "Alice", "age": 25});
- ์ผ๋ฐ์ ์ธ JSON ์๋ต์ด ์๋๋ผ, myCallback() ํจ์ ํธ์ถ ํํ๋ก ๊ฐ์ธ์ ธ ์์
โ ํด๋ผ์ด์ธํธ์์ ์ฒ๋ฆฌํ๋ ์ฝ๋
function myCallback(data) {
console.log(data.name); // "Alice"
}
โ๏ธ ๋ธ๋ผ์ฐ์ ๋ <script> ํ๊ทธ์ ์๋ต์ ์คํํ๋ฉด์ myCallback({name: "Alice"})์ ์คํํจ.
โ๏ธ ๊ฒฐ๊ณผ์ ์ผ๋ก, myCallback ํจ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋จ.
โ ํ์ง๋ง JSONP๋ ๋ณด์ ์ทจ์ฝ์ (XSS ๊ณต๊ฒฉ ๋ฑ)์ด ์์ด ํ์ฌ๋ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์์ผ๋ฉฐ, CORS๊ฐ ๋์ฒดํ๊ณ ์์.
โ ์ ๋ฆฌ
SOP (Same Origin Policy) | ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์ ํํ๋ ๋ณด์ ์ ์ฑ |
CORS (Cross-Origin Resource Sharing) | ์๋ฒ์์ Access-Control-Allow-Origin ํค๋๋ฅผ ์ถ๊ฐํ์ฌ ๋ค๋ฅธ ์ถ์ฒ์ ์์ฒญ์ ํ์ฉ |
CORS Preflight ์์ฒญ | OPTIONS ์์ฒญ์ ํตํด ์๋ฒ๊ฐ ํ์ฉํ๋ ๋ฉ์๋์ ํค๋๋ฅผ ํ์ธํ๋ ๊ณผ์ |
JSONP (JSON with Padding) | <script> ํ๊ทธ๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์๋ ๋ฐฉ์ (ํ์ฌ ๊ฑฐ์ ์ฌ์ฉ ์ ํจ) |
CORS๋ ์๋ฒ ์ค์ ์ด ํ์ํ๊ณ , JSONP๋ ๋ณด์ ๋ฌธ์ ๋๋ฌธ์ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์์ผ๋ฏ๋ก
์ค์ ๊ฐ๋ฐ์์๋ CORS๋ฅผ ์ค์ ํ์ฌ ๊ต์ฐจ ์ถ์ฒ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.
'๐ธ๏ธ ์น ํดํน' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[wargame] ๋๋ฆผํต xss-1 ๋ฌธ์ ํ์ด (0) | 2025.03.06 |
---|---|
Cross-Site Scripting (XSS) ๊ฐ๋ ์ ๋ฆฌ (0) | 2025.03.05 |
[wargame] Dreamhack ๋ฌธ์ ํ์ด: session-basic (0) | 2025.03.05 |
[wargame] ๋๋ฆผํต beginner cookie ๋ฌธ์ ํ์ด (0) | 2025.03.03 |
[wargame] Dreamhack beginners devtools-sources ๋ฌธ์ ํ์ด (0) | 2025.03.02 |