๐ ํฌ๋กฌ ๋ธ๋ผ์ฐ์ PNA ๊ถํ๊ณผ CORS ํด๊ฒฐํ๊ธฐ
Chrome PNA (Private Network Access)
์ฌ์ค๋ง ์ ๊ทผ(private network access) ์ด๋, ๋น์ธ์ฆ๋ ๊ณต์ธ(public) ์น์ฌ์ดํธ์์, ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํ ์ฌ์ฉ์์ ์ ๊ฐ์ ์ฌ์ค ๋คํธ์ํฌ๋ง(localhost(127.0.0.1) or 192.168.0.* ์์ดํผ) ์๋ํฌ์ธํธ์ ์์ธ์คํ๋ ค ํ ๋, ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฒญ์ ์ ํํ๋ ์๋ก์ด ๋ณด์ ํฅ์ WSC ์ฌ์์ ๋งํ๋ค.
PNA ๋์ ๋ฉ์ปค๋์ฆ์ CORS(Cross-Origin Resource Sharing) ์ ์ฑ ์ ํ์ฅํ ๊ฐ๋ ์ผ๋ก ์ ์ฉ๋๋ค. ๊ทธ๋์ ์ฌ์ดํธ์์ ์ฌ์ค ๋คํธ์ํฌ ์๋ฒ์ ํ๊ฐ๋ฅผ ์ฐ์ ์๋น ์์ฒญ(Preflight) ํ๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฒญ์ ์น์ธํ ๊ฒฝ์ฐ์๋ง, ๊ณต๊ณต ์น์ฌ์ดํธ์์ ์ฌ์ค ๋คํธ์ํฌ ์๋ฒ์ ๋ฆฌ์์ค์ ์์ธ์ค๊ฐ ๊ฐ๋ฅํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด CORS ์๋ฌ๊ฐ ๋จ๊ฒ ๋๋ค.
์ฆ, ์์ผ๋ก ๊ณต๊ณต ์ธํฐ๋ท ์น์ฌ์ดํธ์์ ๋ด๋ถ ๋คํธ์ํฌ ์์์ ์ ๊ทผํ๋ ค๋ฉด ๋ธ๋ผ์ฐ์ ์ ํ๋ฝ์ ๋ฐ์์ผ๋ง ํ๋ ๊ฒ์ด๋ค.
PNA ํ์ ๋ฐฐ๊ฒฝ
๋ธ๋ผ์ฐ์ ๋ฅผ ํตํ ๋คํธ์ํฌ ์นจ์
์ด ์ฌ์์ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์นจํฌํ๋ ๋ฐฉ์์ ํดํน ๊ณต๊ฒฉ์ ๋ณด๋ค ์ด๋ ต๊ฒ ๋ง๋ค๊ฒ ๋ค๋ ์ทจ์ง๋ก ํ์ ๋์๋ค. ๋ธ๋ผ์ฐ์ ๋ ๋ง์ ์๋น์ค์ ์ํธ ์์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์, ๊ธฐ๋ณธ์ ์ผ๋ก ๋ก์ปฌ ๋คํธ์ํฌ ๋ด๋ถ์ ๊ฑฐ์ ๋ชจ๋ ๋ฆฌ์์ค์ ์ฐ๊ฒฐํ ์ ์๋ค๋ ํน์ง์ ์ ์ฉํ์ฌ, ๋ธ๋ผ์ฐ์ ๋ ๋ก์ปฌ ๋คํธ์ํฌ์ ๋ํ ๊ณต๊ฒฉ์ ์ํ ๊ต๋๋ณด๋ก ํ๋ก์๋ก์ ์ด์ฉ๋์์๋ค.
์๋ฅผ๋ค์ด ์ ์ฑ ์น์ฌ์ดํธ๋ฅผ ๊ฐ์คํด ๋๊ณ ํผํด์๋ฅผ ์ฌ์ดํธ ์ ์์ ์ ๋ํจ์ผ๋ก์จ ํผํด์์ ๋คํธ์ํฌ์ ๋ค์ด๊ฐ ์๋ํฌ์ธํธ๋ฅผ ๊ฐ์ผ์ํค๋ ๊ฒ ๊ฐ๋ฅํ๋ค. ์ฌ์ฉ์๊ฐ ์ ์ฑ ์น์ฌ์ดํธ์ ์ก์ธ์คํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ์ฌ์ฉ์ ๋ชจ๋ฅด๊ฒ ๋ผ์ฐํฐ์ ์๋ ์์ฒญ์ ๋ณด๋ด ๋ผ์ฐํฐ์ ์ธ์ฆ์ ์ฐํํ ์ ์๊ธฐ ๋๋ฌธ์, ์ ์์ ์ธ ์น์ฌ์ดํธ์์ ๋ผ์ฐํฐ ์ค์ ์ ์์ ํ ์ ์๋ ์ ์ฑ ์ฝ๋๋ฅผ ๋ณด๋ด ๋ผ์ฐํฐ๋ฅผ ์กฐ์ํ๋ ์์ผ๋ก ๊ฐ์ผ์ํจ๋ค.
์ค์ ๋ก ํด์ปค๊ฐ CSRF ๊ณต๊ฒฉ์ ํตํด 300,000๊ฐ ์ด์์ ๋ฌด์ ๋ผ์ฐํฐ์ ๋ํ DNS ์๋ฒ ์ค์ ์ ๋ณ๊ฒฝํ์ฌ ์ ๋ณด๋ฅผ ํ์ทจํ ์ฌ๋ก๋ ์๋ค.
- ์ฌ์ค ๋ด๋ถ๋ง์ ์ฌ์ฉํ๊ณ ์๋ ์ฌ์ฉ์๊ฐ ์ ์์ ์ธ ์ฌ์ดํธ์ ์ ์ํ๋ค.
- ์ ์ฑ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ก์ปฌ ๋คํธ์ํฌ ๋ด๋ถ์ ์ปดํจํฐ์์ ๋ก๋๋์ด ๋ก์ปฌ ์ปดํจํฐ๊ฐ ๋ผ์ฐํฐ์ DNS ์ค์ ์ ์๋์ผ๋ก ๋ณ๊ฒฝํ๋๋ก ํ๋ค.
- ๋ผ์ฐํฐ๋ ๋คํธ์ํฌ์ ๋ชจ๋ ๋๋ฐ์ด์ค์ ๋ํด ์ ์ฑ ๋ค์์๋ฒ(DNS)๋ฅผ ์ฌ์ฉํ๋๋ก ์ค์ ๋จ์ ๋ฐ๋ผ, ํด๋น ๋ง์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ์ฌ์ฉ์๋ค์ ๋ผ์ฐํ ์์ฒญ์ ์ค์ผ์ํจ๋ค.
- ๊ธ์ต(๋๋ ๊ธฐํ) ์ฌ์ดํธ์ ์ฐ๊ฒฐ์ ์๋ํ๋ ๋๋ฐ์ด์ค๋ ์ด์ ๋ก๊ทธ์ธ ์๊ฒฉ ์ฆ๋ช ์ ์บก์ฒํ ์ ์๋ ๊ฐ์ง ์น์ฌ์ดํธ๋ก ๋ฆฌ๋ค์ด๋ ์ ๋ ์ ์๋ค.
์ด๋ฌํ ๋ณด์์ ์ธ ์ทจ์ฝ์ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ ์ด์ ์ฌ์ค๋ง์ ๋ํด์ ๊ฒ์ฌ๋ฅผ ์ฒ ์ ํ ํ๋ค๋ ๊ฐ๋ ์ผ๋ก PNA ์ฌ์์ด ํ์ํ๊ฒ ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด ๊ฐ์ข ์๋ํฌ์ธํธ ์ฅ๋น๋ค์ ๋ ธ๋ฆฌ๋ CSRF(๊ต์ฐจ ์ฌ์ดํธ ์์ฒญ ์กฐ์) ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋น๊ต์ ์์ ํด์ง๊ฒ ๋๋ค.
Chrome PNA ์ ์ฑ ์ ์ฉ ์๊ธฐ
Google์ ๋ฐ๋ฅด๋ฉด Chrome 94 ๋ฒ์ ๋ถํฐ PNA๊ฐ ๋ฑ์ฅํ์ผ๋ฉฐ ํ์ฌ๊น์ง ์๋ฒ์ ์ผ๋ก ์ด์ฉ๋๋ค๊ฐ, 2023๋ 5์์ ์ถ์๋ Chrome 113 ๋ฒ์ ์์ ์ ์์ผ๋ก ๋ฆด๋ฆฌ์ฆ ๋ ์์ ์ด๋ผ๊ณ ํ๋ค. ๊ฐ์ ํฌ๋ก๋ฏธ์ ๊ณ์ด์ธ Edge ๋ธ๋ผ์ฐ์ ์ญ์ ๋ฒ ํ ์ฑ๋์ ๋์ ๋ ์ํ์ด๋ค. ๋ฐ๋ผ์ ๋ธ๋ผ์ฐ์ ์์ฒด์์ ๋น๊ณต๊ฐ ๋คํธ์ํฌ ์์ฒญ์ ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ค๋ฉด ์ด์ ๋ง๊ฒ ๋์ฒ๋ฅผ ํด์ผ ํ ๊ฒ์ด๋ค.
PNA CORS ์๋ฌ ํ์
CORS ์ ๋ฉ์ธ์ง ์ข ๋ฅ
์ผ๋ฐ์ ์ธ CORS ๋ฉ์ธ์ง
๋จผ์ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ํ๋ CORS ์๋ฌ๋ ๋ค์๊ณผ ๊ฐ๋ค. ์๋ฌ ๋ฉ์ธ์ง์์ ์๋ดํ๋ฏ์ด ์ด ๋ถ๋ถ์ ๋ฐฑ์๋์ชฝ์์ CORS ๊ด๋ จ ํค๋์ธ Access-Control-Allow-* ์๋ต๋ง ์ ํด์ฃผ๋ฉด ๋ณ๋ค๋ฅธ ๋ฌธ์ ์์ด ํด๊ฒฐ์ด ๋๋ค.
Access to XMLHttpRequest at 'http://xxxx' from origin 'http://xxxxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
PNA CORS ๋ฉ์ธ์ง
๊ทธ๋ฐ๋ฐ ์๋ฒ์์ CORS ๊ด๋ จ ํค๋ ์์ฒญ ์๋ต์ ๋ชจ๋ ์ฒ๋ฆฌํด์คฌ๋๋ฐ, ์ด๋ฒ์ ๋ค์๊ณผ ๊ฐ์ ๋๋ค๋ฅธ CORS ์๋ฌ๊ฐ ๋ฐ์ํด์ ๋นํฉํ ๊ฒฝํ์ด ์์ ๊ฒ์ด๋ค.
Access to XMLHttpRequest at 'http://10.x.x.x/xxxx' from origin 'http://xxxx.xxx.com' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `private`
์ ์๋ฌ ๋ฉ์ธ์ง ๋ด์ฉ ๋ถ๋ถ์ ํด์ํ์๋ฉด, ์์ฒญ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด์ ์ปจํ ์คํธ๊ฐ ์๋๋ฉฐ ๋ฆฌ์์ค๊ฐ ๋น๊ณต๊ฐ ์ฃผ์ ๊ณต๊ฐ ๋ก์ปฌ์ ์๋ค๋ ๋ง์ด๋ค. ์ฆ, ์์์ ๋ค๋ฃจ์๋ PNA(Priavte Network Address) ๊ด๋ จ ์ฌ์์ด๋ค.
PNA CORS ๋ฐ์ ์ํฉ
์์ฒญ ๋จ๊ณ ๋ฐฉํฅ
ํฌ์คํ ์ด๋ฐ์ ์ ๊น ์๊ฐํ๋ฏ์ด, PNA CORS ๋ฐ์ ์ํฉ์ ๊ณต์ธ IP์์ ์ฌ์ค/๋ก์ปฌ IP๋ก์ ๋ฎ์ ์์ค์ผ๋ก ๊ฐ๋ ์์ฒญ์ ํ ๋ ๋ฐ์๋๋ค. ์๋ฅผ ๋ค์ด ์๋ ๊ทธ๋ฆผ์์ Public ๋คํธ์ํฌ(http://example.com)์์ Private ๋คํธ์ํฌ(http://router.local) ๋ก์ ์์ฒญ์ ํ๊ฑฐ๋, ๋๋ Private ๋คํธ์ํฌ์์ Local ํธ์คํธ์ ์์ฒญ์ด ์ด์ ํด๋น๋๋ค.
- public ๋คํธ์ํฌ ์ฌ์ดํธ → private ๋คํธ์ํฌ ์ฌ์ดํธ (CORS !!)
- public ๋คํธ์ํฌ ์ฌ์ดํธ → ๋ก์ปฌ ํธ์คํธ (CORS !!)
- private ๋คํธ์ํฌ ์ฌ์ดํธ → ๋ก์ปฌ ํธ์คํธ (CORS !!)
insecure public website
๋ค๋ง ๋ฌด์กฐ๊ฑด ๊ณต์ธ ์น์ฌ์ดํธ์์ ์์ฒญํ๋ฉด PNA CORS์ ๊ฑธ๋ฆฌ๋๊ฒ ์๋๋ผ, ์ ํํ ๋งํ์๋ฉด ๋น์ธ์ฆ๋* ๊ณต์ธ ์น์ฌ์ดํธ์์ ์์ฒญํ๋ฉด ๊ฑธ๋ฆฌ๋ ๊ฒ์ด๋ค. ์ฆ, https ๋ wss ์ ๊ฐ์ ssl์ ๋จน์ธ ์ฌ์ดํธ๋ผ๋ฉด PNA CORS๋ ๋ฐ์ํ์ง ์๊ฒ ๋๋ค.
๋๋ฉ์ธ ์ฌ๋ถ
๋ง์ง๋ง์ผ๋ก ์์ฒญ์ ๋ณด๋ธ ๊ณต์ธ ์น์ฌ์ดํธ๊ฐ ์์ดํผ ํํ๊ฐ ์๋ ๋๋ฉ์ธ์ด ์์์ ธ ์์ ๊ฒฝ์ฐ์๋ง ๋ฐ์ํ๋ค. ์๋ฌด๋ฆฌ insecure public website ์ด๋ผ๋ ๋๋ฉ์ธ ํํ๊ฐ ์๋๊ฒฝ์ฐ PNA CORS ์๋ฌ๋ ๋ฐ์ํ์ง ์๋๋ค.
PNA CORS ๊ด๋ จ ํค๋
์ผ๋ฐ์ ์ธ CORS ํ์์ ํด๊ฒฐํ๊ธฐ ์ํด Access-Control-Allow-Origin ํค๋๋ฅผ ์ค์ ํ์ฌ ํด๊ฒฐ ํ์ ๋ฏ์ด, PNA CORS ์ญ์ ๊ด๋ จ ํค๋์ธ Access-Control-Allow-Private-Network ํค๋๋ฅผ ์ค์ ํ๋ฉด ๋๋ค. ์ด๋ฅผ ๋์์ผ๋ก ํํํ์๋ฉด ์๋์ ๊ฐ์ด ๋๋ค.
- ํ์ ์์์ ๋ํ ์์ฒญ์ ์ฌ์ค๋ง์ ๋ณด๋ด๊ธฐ ์ ์, ์์ ์๋น ์์ฒญ(Preflight)์ ๋ณด๋ธ๋ค.
- ์ด๋ ์์ฒญ ํค๋์
Access-Control-Request-Private-Network: true๋ฅผ ์ค์ด ์๋ฒ์ ๋ณด๋ธ๋ค - ์์ฒญ ์ ๋ฌ์ ๋ฐ์ ์๋ฒ์์
Access-Control-Allow-Private-Network: true๋ฅผ ํตํด ํ๋ฝ์ด๋ ๋ถํ๋ฅผ ์๋ตํ๋ค. - ์์ธ์ค ํ๋ฝ์ด ๋๋ฉด ๋ณธ์์ฒญ ํต์ ์ด ์ด๋ฃจ์ด์ง๊ฒ ๋๋ค.
PNA CORS ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ์์ฒญ ์ฃผ์ฒด๋ฅผ ๋ณ๊ฒฝ
์์ ๋งํ๋ฏ์ด ๊ณต์ธ IP๋ผ๊ณ ํด๋ insecure์ผ ๊ฒฝ์ฐ์๋ง PNA CORS๊ฐ ๋ฐ์ํ๋ค๊ณ ํ์์ผ๋, ํธ์ถํ๋ ์ฃผ์ฒด์ scheme๋ฅผ HTTPS๋ก ์ค์ ํ๋ฉด ๊ฐ์ ธ์ค๋ ค๋ ๋ฆฌ์์ค๊ฐ HTTP์ฌ๋ ๋ฌธ์ ์์ด ํธ์ถ์ด ๊ฐ๋ฅํด์ง๋ค.
ํน์ ์์ฒญํ๋ ค๋ ๋ฆฌ์์ค๋ฅผ ์ฌ์ค/๋ก์ปฌ ๋คํธ์ํฌ๊ฐ ์๋ ๊ณต์ธ ๋คํธ์ํฌ๋ก ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ๋ ๊ฐ๋ฅํ๋ค.
2. ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ต์ ๋ณ๊ฒฝ
ํฌ๋กฌ ํน์ ์ฃ์ง ๋ธ๋ผ์ฐ์ ๊ฒ์์ฐฝ์ ๋ค์ URL๋ก ์ด๋ํ๋ค.
- chrome://flags
- edge://flags
๊ทธ๋ฆฌ๊ณ Block insecure private network requests ํญ๋ชฉ๊ณผ Send Private Network Access preflights ํญ๋ชฉ์ ์ค์ ๊ฐ์ Disabled๋ก ์ค์ ํ๋ฉด ๋๋ค.
3. Chrome Origin Trials ์ด์ฉ
๊ฐ๋ฐ์ ์ง์ ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๋ก์ปฌ ๋คํธ์ํฌ ์ ๊ทผ์ ํ์ฉํ ์ ์๋ค.
https://developer.chrome.com/origintrials/#/trials/active ๋ก ์ ์ํด์, Private Network Access from non-secure contexts ํญ๋ชฉ์ REGISTER ๋ฅผ ํด๋ฆญํ๋ค. ๋จ, ์ด ๋ฐฉ๋ฒ์ PNA๋ฅผ ํ์ฉํ ์น์ฌ์ดํธ์ API ํค๋ฅผ ๋ฐ๊ธ๋ฐ์ ์ฌ์ฉํ๋ ํํ์ด๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๊ฐ์ด ์ ํด์ ธ ์๋ค.
4. Access-Control-Allow-Private-Network ํค๋ ์ค์
์ง๊ธ๊น์ง ์๊ฐํ ์์ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๊ฒ ์ค์ ๋ง์ผ๋ก ํด๊ฒฐ์ด ๊ฐ๋ฅํ๊ฒ ์ง๋ง, ์ด๋ ๋ณด์์ ์ผ๋ก ์์ ํ์ง ์์ผ๋ฉฐ, CORS๋ ์๋ฒ๊ฐ ์๋ ๋ธ๋ผ์ฐ์ ์์ ์ฐจ๋จํ๋ ๋ฉ์ปค๋์ฆ ์ด๊ธฐ ๋๋ฌธ์, ์๋น์ค ์ด์ฉ์๋ค์ด ์ง์ ์๊ธฐ๊ฐ ์ฐ๋ ์ปดํจํฐ์ ๋ธ๋ผ์ฐ์ ์ค์ ์ ์ผ์ผํ ์กฐ์ํด์ผ ํ๋ค๋ ๋ฒ๊ฑฐ๋กญ๋ค๋ ์น๋ช ์ ์ธ ๋จ์ ์ด ์กด์ฌํ๋ค.
๋ฐ๋ผ์ ๊ฐ์ฅ ์ด์์ ์ธ ํด๊ฒฐ์ฑ
์ ๋ฐฑ์๋์ชฝ์์ Access-Control-Allow-Private-Network ํค๋ ์ค์ ์ ํ๋ฉด ๋๋ ๊ฒ์ด๋ค.
HTTP/1.1 OPTIONS localhost:8080/cat.gif
Origin: https://foo.example
Access-Control-Request-Private-Network: true
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Private-Network: true
# ์ฐธ๊ณ ์๋ฃ
https://www.boannews.com/media/view.asp?idx=104187
https://developer.chrome.com/blog/private-network-access-update/
https://arstechnica.com/information-technology/2022/01/new-chrome-security-measure-aims-to-curtail-an-entire-class-of-web-attack/