I got my weekly TL;DR Sec newsletter on Thursday morning. I regularly browse the headlines for fun things to check out whenever I might have some actual downtime. I noticed a post about XSS in Swagger UI at: Hacking Swagger-UI - from XSS to account takeovers
I did the usual perusal, noted down the concerns, and popped right on over to Sourcegraph to determine the future of my Thursday. To my general dismay,
I did have vulnerability tickets that needed filing. Oh well, part of the job, right? My quick investigation was based solely on what the post described
which is that
swagger-ui-dist provided as an NPM package
had a vulnerable range of versions. This meant that
I was focusing on
What struck me pretty quickly though was that I was already aware of projects that bundled the Swagger UI and were solely JVM-based (Java/Scala/Kotlin) projects. I needed to know how the heck those projects had the Swagger UI packaged with them, and boy, did I ever go down a rabbit-hole.
The deep-dive below is how my Thursday and subsequent days went sideways as I learned all the ways you can bundle, include, and/or just jam in the Swagger UI into your JVM-based project.
So, what’s the deal with Springfox?
Springfox plugs cleanly into Spring and allows for quick documentation via annotations and the like. It’s clear why people use it – writing documentation sucks, but making annotations in your code and having documentation autogenerate is sweet.
Immediate concern: Springfox bundles Swagger UI instead of embedding a link to the latest version of the software. And, I’m sure you guessed it, Springfox bundles a vulnerable version of Swagger UI that is susceptible to XSS.
Secondary concern: Springfox hasn’t been updated since July 13, 2020.
Summarizing that last bit…
If you are using Springfox and allowing the Swagger UI to be accessible, your app is vulnerable to a Reflected XSS attack.
Another challenger enters the ring… WebJars
You see, I was actually done writing this piece when I found WebJars. Let’s be clear. I’m not a Java/Kotlin/Scala developer, and hopefully that warning allows you to forgive my general ignorance for these things. I was blissfully unaware such a system existed that packaged up frontend code as a Jar and allowed you to manage backend dependencies alongside your frontend dependencies.
It’s actually quite neat, but it’s also a double edged sword. You see - when your frontend dependencies have vulnerabilities, they typically get reported up-the-chain and you get scary warnings in NPM and/or your dependency scanning tool of choice (eg. Snyk, SourceClear, XRay, etc).
So, how about you prove it, Sean?!
In the security community, there’s a phrase “PoC or GTFO”. It’s a little aggressive, but it’s a fair mantra. Don’t go spreading FUD (Fear, Uncertainty, and Doubt) without providing proof that something is actually an issue. So, without further ado, below are my example apps for both Springfox and WebJars. Each one shows how including the vulnerable package results in a rather simple reflected XSS issue.
Prefer to just try it yourself? Append the following to your service’s swagger URL:
The payload you are running is located at: seanmarpo/swagger-xss-payloads
The Fun Bits: What do we do now?
I have submitted all the evidence to Snyk to get a signature created as soon as possible for both issues. This will mean that Snyk will begin finding these issues soon ™️. I don’t have much of a timeframe though, so keep the fingers crossed.
Springfox Mitigation and Solutions
It’s pretty clear to me that it is unlikely for us to get a patched version of Springfox. The good news is that a replacement library exists and is actively maintained: SpringDoc
SpringDoc maintains a handy guide on migrating from Springfox located at: OpenAPI 3 Library for spring-boot which is currently the best path forward.
Since WebJars keep up with frontend packages, you just need to update your
org.webjars:swagger-ui package to anything higher than
Don’t expose your Swagger UI and/or stop bundling the Swagger UI with your software! Swagger has a public viewer at: https://editor.swagger.io/ which will gladly render your YAML/JSON OpenAPI spec without YOU needing to host the viewer yourself.
Basically, don’t add extra attack surface to your application, especially when it’s not your own code.