Site wide CSRF on a popular program



I found this bug in the same program that I explained in this post "Authorization bug every bug hunter missed"

I was moving through another target on this program when I noticed that there was no CSRF protection like there were no tokens etc so I wondered what they were using to prevent CSRF, I noticed some high entropy strings in headers but request worked without those headers as well so that wasn't protecting the website from CSRF. Request body consisted of JSON objects basically {key: "value"} pairs the assumption behind using it was that in a typical CSRF attack attackers don't send JSON payloads, so using JSON will naturally protect the application against CSRF.

Here's where the trick comes in, It's actually more of check that you should perform while trying to find CSRF bugs, I spotted it on Twitter first you may or may not be familiar with it, here's how it works.

It's very simple assume that server side framework is expecting some JSON input by default in the HTTP Request body so if it detects JSON object it will automatically parse it.

But even if you send regular Content-Type that is application/x-www-form-urlencoded then also it will automatically parse that and start using it, problem is caused by not checking the Content-Type, it should be strictly application/json if you're expecting JSON input.

So in this case to trigger CSRF I just sent regular CSRF payload but due to their negligence of not validating Content-Type header to be strictly JSON server accepted the regular HTTP parameters and triggered the CSRF.
<html>
    <form id="csrf" enctype="application/x-www-form-urlencoded" method="POST" action="https://www.example.com/api/REDACTED/PATH">
        <table>
            <tr><td>primaryPhoneType</td><td><input type="text" value="0101101101" name="primaryPhoneType"></td></tr>
            <tr><td>firstName</td><td><input type="text" value="YOUREcsrfedCongratsbtw" name="firstName"></td></tr>
        </table>
        <input type="submit" value="https://www.example.com/api/REDACTED/PATH">
    </form>
<script type="text/javascript">
    document.getElementById('csrf').submit()
</script>
</html>
This could have been prevented by validating Content-Type header to be application/json

In my case the server was accepting regular HTTP Post parameters along with expected JSON, so I reported the bug, but my report was marked as duplicate 😩 against someone who reported site wide CSRF using Flash.

If you find JSON objects without CSRF protection being passed around in HTTP body try to change it to regular HTTP parameters and see if it works, if the server side application is accepting non JSON parameters then it'll process the input and you maybe able to get a CSRF.

Happy bug hunting.

Comments

Post a Comment

Popular posts from this blog

Releasing Flumberbuckets: S3 Bucket Enumeration Tool for Bug Hunters

Installing XFCE & other things on Arch Linux