Skip to main content
  1. Blogposts/

Kringgå en sandboxad iframe: en lektion i csp-bypass och url-läckage ✨

·655 words·4 mins· loading · · ·
Rasmus
Author
Rasmus
Att dela en ide eller två kan vara bra för hjärnan
Table of Contents

Introduktion
#

Tänk dig att du är en digital inbrottstjuv som står framför ett säkerhetssystem med flera lager av skydd. Din uppgift? Ta dig igenom varje lager utan att trigga larmet. Det är precis den typen av utmaning vi ska tackla i den här artikeln. Vi ska utforska hur man kan kringgå en strikt Content Security Policy (CSP) och läcka känslig data från en sandboxad iframe – en teknik som kan vara ovärderlig både för säkerhetstestare och utvecklare som vill förstå sina systems svagheter.

Utmaningen
#

Utmaningen går ut på att manipulera en sida (https://sandbox-iframe-ctf.glitch.me) som accepterar godtycklig HTML-kod via en Base64-kodad sträng i sökparametern xss. Denna HTML placeras sedan inuti en sandboxad iframe på samma sida.

Målet? Att läcka fram en flagga som placeras i hash-delen av URL:en och visa dess värde i en alert-ruta.

// Exempel på hur flaggan lagras i URL:en
https://example.com/#FLAG{this_is_the_secret}

Steg 0: Uppsättning och Begränsningar
#

Låt oss först förstå de säkerhetsmekanismer vi har att göra med:

  1. Sandboxad iframe med attributen:

    • allow-scripts: Tillåter JavaScript-körning
    • allow-modals: Tillåter modala fönster som alerts
    • Saknar allow-same-origin: Förhindrar åtkomst till det överordnade fönstret
  2. Strikt CSP (Content Security Policy):

script-src 'self'
'nonce-ae692e51fd5d5528c59c78334c035454'
'unsafe-eval'
https://cdnjs.cloudflare.com/ajax/libs/Base64/1.3.0/base64.min.js;

Detta innebär att vi kan köra skript inuti iframen, men med strikta begränsningar på vilka externa resurser vi kan ladda.

Steg 1: Kringgå CSP
#

Här kommer det riktigt knepiga – men också det mest lärorika. CSP har en intressant egenskap när det gäller omdirigeringar:

När en resurs laddas via en URL som är tillåten av CSP, och denna URL returnerar en omdirigering, kommer webbläsaren endast att kontrollera basdomänen för den nya URL:en mot CSP-reglerna.

Detta är ingen bugg, utan ett medvetet designval för att förhindra informationsläckage (se CSP-specifikationen).

Praktisk tillämpning: Om sidan har en öppen omdirigering (t.ex. /redirect?url=https://evil.com), och denna endpoint är tillåten av CSP ('self'), kan vi använda detta för att ladda godtyckliga skript från CDN:er som redan är delvis tillåtna.

<script src="/redirect?url=https://cdnjs.cloudflare.com/ajax/libs/htmx/1.9.12/htmx.min.js"></script>
<img src=x hx-on:error="alert(1)">

Här använder vi HTMX-biblioteket (ett modernt alternativ till Angular) för att köra godtycklig kod genom dess händelsehanterare.

Steg 2: Komma Åt Föräldra-iFrame
#

Nu har vi kodkörning, men fortfarande problem:

  • Vi är fortfarande inneslutna i sandboxen
  • Origin är null
  • Ingen direkt åtkomst till parent-fönstret

Men här kommer ett genialiskt knep:

fetch("") // Notera den tomma strängen

Denna request kommer faktiskt att riktas mot föräldradokumentets URL (men misslyckas p.g.a. CORS). Hur fungerar denna magi?

Bakgrund: Relativa URLs och Base URI
#

När en webbläsare stöter på en relativ URL (utan domän eller protokoll), används dokumentets “base URI” för att lösa den fullständiga adressen. För about:srcdoc-dokument (vilket vår iframe är) är bas-URI:n faktiskt föräldradokumentets URL!

Vi kan utnyttja detta genom att komma åt baseURI-egenskapen på DOM-noder:

document.baseURI // Returnerar fullständig URL inklusive hash!

Steg 3: Sätta Ihop Allt
#

Nu har vi alla pusselbitar:

  1. Kringgå CSP via omdirigering
  2. Kodkörning via HTMX
  3. Åtkomst till flaggan via baseURI

Den slutliga payloaden blir:

<script src="/redirect?url=https://cdnjs.cloudflare.com/ajax/libs/htmx/1.9.12/htmx.min.js"></script>
<img src=x hx-on:error="alert(document.baseURI.split('#')[1])">

Implikationer och Lärdomar
#

Denna teknik är inte bara en cool hack utan belyser viktiga säkerhetsprinciper:

  1. CSP är inte en silverkula: Även strikta policyer har sina begränsningar
  2. Sandbox-attribut måste konfigureras noggrant: allow-scripts utan allow-same-origin kan fortfarande vara riskabelt
  3. URL-hantering är känslig: Relativa URLs kan bete sig oväntat i speciella kontexter

I verkliga scenarier kan liknande tekniker användas för att läcka OAuth-tokens eller andra känsliga data som lagras i URL-fragment.

Avslutande Tankar
#

Den här övningen visar hur säkerhet ofta handlar om att förstå systemens underliggande beteenden mer än att memorera specifika attacker. Nästa gång du implementerar säkerhetsmekanismer, fråga dig:

  • Vilka implicita antaganden gör jag om hur webbläsare fungerar?
  • Finns det några “design features” som skulle kunna vändas mot mig?
  • Har jag testat mina säkerhetskontroller mot kreativa angreppsvektorer?

Säkerhet är en ständig dans mellan skydd och angrepp, och ju bättre vi förstår båda sidorna, desto robustare system kan vi bygga.

Har du stött på liknande utmaningar? Eller kanske sett andra kreativa sätt att kringgå säkerhetsmekanismer? Dela gärna dina erfarenheter i kommentarerna! 🚀