Relative Path Overwrite (RPO)
Relative Path Overwrite (RPO)๋ ์๋ ๊ฒฝ๋ก์ URL์ ๋ฎ์ด์จ์ ์๋ํ์ง ์์ ๋์์ ์ํํ๋ ๊ณต๊ฒฉ ๋ฐฉ๋ฒ์ด๋ค.
์๋ฒ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ ๊ฒฝ๋ก๋ฅผ ํด์ํ๋ ๊ณผ์ ์์ ๋ฐ์ํ๋ ์ฐจ์ด์ ์ ์ด์ฉํ๋ ๊ฒ์ด๋ค.
Relative Path Confusion์ด๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค.
RPO๋ฅผ ์น์์ ์ด์ผ๊ธฐํ ๋ link, script ๋ฑ resource๋ฅผ ์ฝ์ด์ค๋ ๊ณผ์ ์์ Host๊ฐ ํฌํจ๋์ง ์์ URL์ Relative URL์ด๋ผ๊ณ ํ๊ณ , ์ด๋ฅผ Overwriteํ ์ ์๋ ๊ฒฝ์ฐ์ resource์ ์ฃผ์ ๋ฑ์ ์กฐ์ํ์ฌ ๊ณต๊ฒฉ์๊ฐ ์ํ๋ ์ก์
์ผ๋ก ์ ๋ํ ์ ์๊ฒ ๋๋ค. (๋ํ์ ์ผ๋ก XSS)
Path Description Example
Absolute URL | Host๊ฐ ํฌํจ๋ URL | <script src = "https://www.hahwul.com/file.js”> |
Relative URL | Host๊ฐ ํฌํจ๋์ง ์์ URL | <src=”/file.js”> |
์ ๋ ๊ฒฝ๋ก / ์๋ ๊ฒฝ๋ก
- ์ ๋ ๊ฒฝ๋ก (Absolute Path): URL์ด๋ ํ์ผ ์์คํ ์์ ์ต์์ ์์์ (๋ฃจํธ)์ผ๋ก๋ถํฐ์ ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ๋ช ์ํฉ๋๋ค. ์น์์ ์ด๋ ๋๋ฉ์ธ ์ด๋ฆ ๋ค์ ์ต์์ ๊ฒฝ๋ก์ธ '/' (์ฌ๋์)๋ก ์์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, <script src="/app/main.js"></script>์์ src ์์ฑ์ ๋๋ฉ์ธ์ ๋ฃจํธ ๊ฒฝ๋ก๋ก๋ถํฐ ์์ํ๋ ์ ๋ ๊ฒฝ๋ก๋ฅผ ๋ํ๋ด๊ณ , ์ด๋ ์น ์๋ฒ์ ์ต์์ ๋๋ ํ ๋ฆฌ์์ /app/main.js ํ์ผ์ ์ฐพ๋๋ก ํฉ๋๋ค.
- ์๋ ๊ฒฝ๋ก (Relative Path): ํ์ฌ ๋ฌธ์์ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค. ๋ง์ฝ ํ์ฌ ๋ฌธ์๊ฐ http://example.com/docs/article.html์ผ ๋, ์๋ ๊ฒฝ๋ก app/main.js๋ http://example.com/docs/app/main.js๋ฅผ ์ฐธ์กฐํ๊ฒ ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ์๋ <script src="app/main.js"></script>์ฒ๋ผ ๋งจ ์์ ์ฌ๋์๊ฐ ์์ต๋๋ค. ํ์ฌ ๋ฌธ์์ ์์น(์ด ๊ฒฝ์ฐ๋ /docs/)์์ app/main.js๋ฅผ ์ฐพ๊ฒ ๋ฉ๋๋ค.
url rewrite ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์น ์ดํ๋ฆฌ์ผ์ด์ ์คํฌ๋ฆฝํธ๋ช ์ดํ์ ๊ฒฝ๋ก๋ฅผ ๋ณ๋๋ก ์ง์ ํด๋ ๊ฐ์ ํ์ด์ง๊ฐ ์กฐํ๋๋ ๊ฒฝ์ฐ๊ฐ ์กด์ฌํ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์น ์๋ฒ์ URL์ ์์ฒญํ ๋, URL ๋ด์ ๊ฒฝ๋ก๋ ์น ์๋ฒ๊ฐ ํด๋น ๋ฆฌ์์ค๋ฅผ ์ฐพ๊ธฐ ์ํ ์ง์นจ์ผ๋ก ์ฌ์ฉ๋๋ค. ์ด๋, ์น ์๋ฒ๋ URL rewrite ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ํน์ ํจํด์ ๊ฒฝ๋ก๋ฅผ ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ฌ์ง์ ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, /index.php/somepath์ ์์ฒญ์ ๋ฐ์์ ๋, ์น ์๋ฒ๋ URL์ /index.php ๋ถ๋ถ๋ง์ ์ฒ๋ฆฌํ์ฌ ํด๋น ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์์ผ๋ฉฐ, /somepath๋ ๋ฌด์ํ ์ ์๋ค.
๊ทธ๋ฌ๋ ์ด ๋ ๋ง์ฝ ์น ํ์ด์ง ๋ด๋ถ์์ ๋ค๋ฅธ ์์์ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ, ์๋ก์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์คํฌ๋ฆฝํธ๋ฅผ ๋ก๋ํ๋ ํ๊ทธ๊ฐ ๋ ๊ฐ ์์ ๋,
์ฒซ ๋ฒ์งธ ์ค๊ณผ ๋ ๋ฒ์งธ ์ค์ ์ฐจ์ด๋ src ์์ฑ ๋งจ ์์ ์กด์ฌํ๋ /์ ์ฐจ์ด๊ฐ ์๋ค.
<script src="/app/main.js"></script>
<script src="app/main.js"></script>
์ฒซ ๋ฒ์งธ ์ค์ ์์ ์กด์ฌํ๋ /์ ์ํด ์คํฌ๋ฆฝํธ ๋ก๋ ์ ์ต์์ ๊ฒฝ๋ก๋ถํฐ ์์ํ์ฌ ํ์ (์ ๋ ๊ฒฝ๋ก)ํ๊ณ ๋ก๋ํ๋ค.
๋ฐ๋ฉด์ ๋ ๋ฒ์งธ ์ค์ ์คํฌ๋ฆฝํธ๋ ํ์ฌ ๊ฒฝ๋ก์์ ์์ํ์ฌ ํ์ (์๋ ๊ฒฝ๋ก)ํ๊ณ ๋ก๋ํ๋ค.
- http://host/rpo.php์ ์์ฒญํ ๊ฒฝ์ฐ (์ฆ, ํ์ฌ ์์น๊ฐ ์ต์์ ๊ฒฝ๋ก์ ์ผ์นํ ๋)
rpo.php์ ์ ๋ ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ์์ฑํ ํ http://host/app/main.js ์ ๊ฐ์ด ์ ๊ทผ ์ ๊ฐ์ ๊ฒฝ๋ก์ ์กด์ฌํ๋ /app/main.js๋ฅผ ๋ก๋ํ๋ค.
- http://host/rpo.php/์ ์์ฒญํ ๊ฒฝ์ฐ (์ฆ, ํ์ฌ ์์น์ ์ต์์ ๊ฒฝ๋ก๊ฐ ๋ค๋ฅผ ๋)
๊ทธ๋ฌ๋ URL์ ์ถ๊ฐ๋ก ์ฌ๋์(/)๊ฐ ํฌํจ๋์ด http://host/rpo.php/์ ๊ฐ์ด ์์ฒญ๋ ๊ฒฝ์ฐ, ์๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๋ ๋ ๋ฒ์งธ <script> ํ๊ทธ๊ฐ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
์ด ๊ฒฝ์ฐ, ๋ธ๋ผ์ฐ์ ๋ /rpo.php/๋ฅผ ํ์ฌ ๋๋ ํ ๋ฆฌ๋ก ๊ฐ์ฃผํ๊ณ , /rpo.php/app/main.js ๊ฒฝ๋ก๋ก ์์์ ์์ฒญํ๊ฒ ๋๋ค.
์ฆ, index.php์ ํ์ด์ง ๋ด์ฉ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ด์ฉ์ผ๋ก์จ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
Relative Path Overwrite (RPO) ๊ณต๊ฒฉ ๋ฐฉ๋ฒ
RPO๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ๋ ์คํ์ผ์ํธ ์ฝ๋๋ฅผ ๋ก๋ํ๋ ๊ณผ์ ์์ ๊ฒฝ๋ก ํด์์ ๋ฌธ์ ๋ก ์ธํด ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ์ํฌํธํ๋ ํ์ด์ง์ ๋ด์ฉ์ ์กฐ์์ํฌ ์ ์๋ค๋ฉด ๊ณต๊ฒฉ์๊ฐ ์๋ํ ์๋ฐ์คํฌ๋ฆฝํธ, ์คํ์ผ์ํธ ์ฝ๋๋ฅผ ๋ก๋์ํฌ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ์ฐ๊ณ
๋ง์ฝ RPO ์ทจ์ฝ์ ์ผ๋ก ๋ก๋ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์ ์ ๋ถ๋ถ์ ๊ณต๊ฒฉ์๊ฐ ์กฐ์ํ ์ ์๋ค๋ฉด, XSS ๊ณต๊ฒฉ์ผ๋ก์ ์ฐ๊ณ๊ฐ ๊ฐ๋ฅํ๋ค. ์๋ฅผ ๋ค์ด ๊ณต๊ฒฉ์๊ฐ RPO ์ทจ์ฝ์ ์ ํตํด ์๋ /static/script.js๋ก ๋ก๋๋์ด์ผ ํ ํ์ผ์ /USER_INPUT/static/script.js์ ํํ๋ก ๋ก๋ํ ์ ์์ ๋ ์๋ฒ์์ /USER_INPUT/static/script.js๊ฐ ํฌํจ๋ ์ฑ๋ก ๋ฐํํ๋ค๋ฉด XSS ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํ๋ค.
์ด ๊ฒฝ์ฐ ๊ณต๊ฒฉ์๋ USER_INPUT ๋ถ๋ถ์ ์กฐ์ํ์ฌ index.php/;alert(1);//static/script.js์ ๊ฐ์ ํํ๋ก ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ฑํ๋ค๋ฉด ํด๋น ๋ด์ฉ์ด script ํ๊ทธ์ src๋ก ๋ค์ด๊ฐ alert(1); ์ด๋ผ๋ ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค. ์ฌ๊ธฐ์ ;๋ฅผ ์ฌ์ฉํ์ฌ statement๊ฐ ๋์ด๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๊ณ //๋ฅผ ์ด์ฉํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ์์ ํด์ํ ์ ์๋ ๋จ์ ๋ฌธ์์ด์ ์ฃผ์ ์ฒ๋ฆฌํ๋ค. ์ด์ฒ๋ผ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ก๋ํ๋ ์ฝ๋ ๋ด์์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ, ์ ์ฒด ์ฝ๋๋ฅผ ์คํํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฌธ๋ฒ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ์ ๊ฒฝ์จ์ผ ํ๋ค.
CSS์ ์ฐ๊ณ
์คํ์ผ์ํธ์ ํน์ง ์ค ํ๋๋ก ์ฌ๋ฐ๋ฅด์ง ์์ ๋ฌธ๋ฒ์ ๋ง๋๋ฉด ๋ฌด์ํ๊ณ ์ฌ๋ฐ๋ฅธ ๋ฌธ๋ฒ์ด ๋์ฌ ๋๊น์ง ๋ค์ ๋ฌธ๋ฒ์ผ๋ก ๋์ด๊ฐ๋ค๋ ํน์ง์ด ์กด์ฌํ๋ค.
์ฆ, RPO ์ทจ์ฝ์ ์ ์ด์ฉํด ์ฌ๋ฐ๋ฅด์ง ์์ ์คํ์ผ์ํธ ํ์ด์ง๋ฅผ ์ํฌํธํ๋๋ก ํ๊ณ , ํด๋น ํ์ด์ง ๋ด ์ผ๋ถ๋ถ์ ์ ํจํ CSS ๋ฌธ๋ฒ์ ์ฝ์
ํ ์ ์๋ค๋ฉด ์ด๋ฅผ CSS Injection์ผ๋ก ์ฐ๊ณํ ์ ์๋ค.
์คํ์ผ์ํธ๋ฅผ ์ด์ฉํ ๊ณต๊ฒฉ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ค๋ฅด๊ฒ ๋ฌธ๋ฒ์ ๋ง์ง ์๋ ์ฝ๋๊ฐ ๋์๋ ์ ์์ ์ผ๋ก ๋๋จธ์ง ์ฝ๋๋ฅผ ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ XSS ๊ณต๊ฒฉ๋ณด๋ค ์ข ๋ ์ ์ฝ์กฐ๊ฑด์ด ์ค์ด๋ ๋ค. ๋ง์ฝ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ XSS ๊ณต๊ฒฉ์ด ๊น๋ค๋กญ๋ค๋ฉด, CSS Injection์ผ๋ก ๊ณต๊ฒฉํ๋ ๊ฒ๋ ์ข์ ์์์ด๋ค.
์ค์ ๋ก ๊ณผ๊ฑฐ ๊ตฌ๊ธ์์ RPO ์ทจ์ฝ์ ์ ์ด์ฉํด CSS Injection์ผ๋ก ์ฐ๊ณํ์ฌ ๊ตฌ๊ธ ๋ฒ๊ทธ๋ฐ์ดํฐ ํฌ์์ ์ ๊ณตํ ์ด๋ ฅ๋ ์กด์ฌํ๋ค.
base-uri ๋ฏธ์ง์
๋ง์ฝ ์์์ ํ๊ทธ๋ฅผ ์ฝ์ ํ ์ ์๊ณ , ํ์ด์ง ๋ด์ RPO ์ทจ์ฝ์ ์ด ์กด์ฌํ๋ค๋ฉด, ๊ณต๊ฒฉ์๊ฐ ์ํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ก๋ํ ์ ์๋ค. ๊ณต๊ฒฉ์๋ ์์ ์ ์๋ฒ๋ฅผ base ์ฃผ์๋ก ์ค์ ํ๊ณ ๋ก๋๋๋ ์คํฌ๋ฆฝํธ ํ์ผ๊ณผ ๊ฐ์ ์ด๋ฆ์ ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ฌ ์คํ์ํฌ ์ ์๋ค.
[์ฐธ๊ณ ]
https://learn.dreamhack.io/575
https://www.hahwul.com/cullinan/rpo