Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Digging for SSRF in NextJS apps- 1408

AssetNotePosted 1 Year Ago
  • NextJS is an extremely popular 'static' site generator, which this website actually uses. So, finding configuration issues or straight up vulnerabilities in NextJS is awesome for bug hunting, since many things would be affected by it.
  • The _next/image component is a built in image optimiziation library that is enabled by default. This works by making a request to the endpoint _next/image under the hood, which implements caching. Now, the actual server makes a request to //localhost/duck.jpg with the provided URL. There is a remotePatterns configuration that restricts the protocols and hostnames set, which is commonly set to '*'.
  • When configured as such, this can lead to SSRF bugs with https://example.com/_next/image?url=https://localhost:2345/api/v1/x&w=256&q=75. Most of the time, this is a blind GET request but there was situations where the impact can be escalated. First, with an old version of NextJS or dangerouslyAllowSVG is set then this SSRF leads to an XSS via the image reflection on the domain. If the response doesn't have a Content-Type then the full response is leaked.
  • Even though NextJS is a client side library, there are many crazy server side features like Server Actions. This feature allows writing JS code that is executed on the server instead of the client side to interact with. When handling redirects within the server side code, it takes in the Host header to make the request. So, by providing the Host header, it's possible to force a localhost redirect leading to SSRF.
  • To exploit this, an action must be defined where the action redirects to some URL. To turn this into a full SSRF read, we can spoof the HEAD request to do some janky things.
    1. Set up a server that takes requests to any path.
    2. On a HEAD request return a 200 with a specific content-type to satisfy the constraints of the system.
    3. On the actual GET request, return a 302 to our victim IP.
    4. Data is returned on the request.
  • Overall, an interesting post on a bug within NextJS and a universal exploit method as well. This is the second issue found with this functionality - the first SSRF on the image stuff was found via Sam Curry.