Show Notes

233 - Spoofing Emails, PandoraFMS, and Keycloak

Client-side traversals as a cool attack class I overlooked for quite awhile. The idea with these is that often an application might take some identifier from the user, and then use it in a further request for other data. It may be possible to include a path traversal in that identifier so that when that further request is made, the URL gets resolved to a different endpoint, take the following example:

  1. You make a request to
  2. JavaScript on the page loads a JSON blob from

If you sent the id as ../uploads/whatever vulnerable JavaScript may try to load the url: following that traversal and resolving a request to a different endpoint.

This is the sort of issue being exploited here in two different ways.

First, for an on-site request forgery. It starts of with a request to the page–36d825aa8ca0&name=Nightbloodz&invitationId=e04cd1f5-e876–4d12-a4e8–9d7e05db0b0b

This page contains an Accept Invitation button, that once clicked will issue a POST request to–4d12-a4e8–9d7e05db0b0b/accept. The problem is that the invitationId could have a traversal in it. Allowing the attacker to trick a victim into making a legitimate POST request to the endpoint of their choice. As the POST body isn’t controlled this isn’t always very useful, but in this case several endpoints had their important data as part of the URL, and just a simple POST with any body was sufficient.

For example an invitationId=blah/../../course/{courseID}/delete could make a post to /course/{courseID}/delete which would delete a course.

The second issue was a means of escalating a self-xss into a general stored XSS. The basic idea of the XSS is that you could create a story which contains a variety of object types which were just stored in a JSON file as an array of {"type":..., "url":...} JSON blobs. One type of object, iframe was only supported in the draft viewer, but the page used to view published stories didn’t support the iframe. However, if you did publish a story with an iframe type object, the JSON would still be there, it just wouldn’t be rendered on the sharable URL. However by using a client-side traversal in the draft viewer, the author could move from a request for a draft (which would need to belong to the same user) to a request for a globally published JSON file. Definitely a nice find to escalate the issue, and if you’re interested give the post a read. My explanation hardly does the attack justice.

Pretty simple issue, KeyCloak supported the DuoUniversalKeycloackAuthenticator plugin to add support for Duo multi-factor authentication to KeyCloak. To do so, on a successful authentication with KeyCloak the plugin would initiate a redirect to the configured Duo endpoint. The problem is that rather than issuing something like an HTTP 302 redirect, they issued an HTTP 307 redirect.

HTTP 307 Temporary Redirect is a special form of redirect that will preserve the request verb and body. So a POST request that gets a 307 in response, will read the new location and make the same POST request to that new location. Whereas the most standard 302 redirect would turn the request into a GET, this body-preserving 307 redirect meant that authentication credentials originally sent to KeyCloak, would be redirected to Duo’s servers also.

While you may not run into this exact issue, I wanted to highlight it as something to keep an eye out for (307 and 308 redirects) because they can result in potentially useful third-party information disclosures.

Take the idea of HTTP request smuggling, and apply it to SMTP and you’ve got an idea of what is going on with this awesome research out of

Kinda like HTTP where you often have a request passing through multiple servers before it reaches the actual backend server. With SMTP you have the idea of a outbound SMTP server. This is the server that would be connected to to send a message in the first place. You’ve connect to the outbound SMTP service for your mail provider. Your mail client gives it whatever SMTP commands to authenticate and send the mail. And then that provider will connect to the recipients inbound SMTP server passing along at least the data segment from your original message.

Also like HTTP, SMTP packets are split into two section, the SMTP commands first, followed by message data. Lets take a quick look at an example SMTP message:

ehlo sender.exmaple\r\n
mail FROM:<user@sender.example>\r\n
rcpt TO:<user@receiver.example>\r\n
From: user@sender.example\r\n
To: user@receiver.example\r\n
Subject: Example\r\n
lorem ipsum

Whats important here is that data segment, marked with the data\r\n at the start, and then the end-of-data sequence \r\n.\r\n. This is one way the message contents can be encoded and sent over SMTP. While the \r\n.\r\n sequence is how the end of the data is supposed to be indicated, not all servers are consistent in what they accept as an end-of-data sequence. If there were any sequences that an outbound server could be made to send, that an inbound server would accept as an end-of-data sequence. Then one could craft a message with more SMTP commands after the fake end-of-data sequence that will be read as SMTP commands instead of being part of the data.

As you might guess, such sequences were discovered. Namely, the research starts with the \n.\r\n sequence. Finding that many outbound servers would allow that in the data, and some inbound servers would treat it as the end-of-data sequence and start processing the rest of the message data as SMTP commands. Allowing a SMTP commands to be used to smuggle in a second email to be sent.

As these second smuggled message, would be coming from a legitimate mail server it would be able to spoof the email as having been sent legitimately, getting past SPF checks (checks the server sending the email is authorized to do so for a given domain). They also found other, more exotic end-of-data sequences (like \r.\r) would be accepted like Cisco mail servers (as used by Amazon, PayPal, the IRS and other big names) and could easily be sent through most outbound servers.

On a whole I think this is some really cool research, and given the number of SMTP implementations out there I’d be surprised if this is the end of parser differentials creating security issues in SMTP.