And frustratingly for me--trying to implement this in the course of a SASL method as a client--there's not even anything hooked up in SASL that might have hinted at the client what to do. Which is insane because the entire point of SASL is to bridge the gap of "how to request authorization given username, hostname, protocol." It makes me want to retreat back into Kerberos as a better way of supporting SSO than anything invented in the decades after it.
RFC6749 The OAuth 2.0 Authorization _Framework_
I threw out that first implementation and just got the 3 most popular servers and made it work with them.
Random example: I'd like to present directories and files differently so users can chdir to a directory. There was no single method for detecting a symlink to a directory that worked on any 2 of the 3 servers I targeted for support (other than issuing a CHDIR and checking for success, and I wasn't going to issue a CHDIR for every item found when listing a directory for performance reasons; I did have to issue a CHDIR for every symlink on one of the 3 though).
SAML is a way for exchanging 'security assertions' - for example, if a Alice logs into the AWS Console with her employer's single-sign-on service, the SSO service gives Alice a signed document saying "The bearer of this document can log into AWS as Alice within the next 60 seconds and access accounts B and C" which she hands to AWS. The digital signature on the document is very important.
Unfortunately, SAML uses the 'XML Signature' standard [1]
The people who wrote the XML signature standard didn't just take an XML document and whack a PGP signature around the whole thing! They thought about use cases like 'what if you wanted to only sign part of a document' and 'what if, after signing, the document was processed by something that reordered the attributes' and 'what if you have signatures from multiple sources and want to collate them into the same document'. They decided they wanted to support all of them.
As such, it's entirely legal for a document to contain a valid set of properly signed security assertions and a load of different security assertions that aren't signed.
So SAML documents have to be parsed very carefully - if you naively check the document has a valid signature then read the assertions, an attacker can add extra assertions outside of the signed part of the document, granting them broader permissions than they ought to have.
(I like PASETO instead of JWT, but nobody else in the world does, it seems, so we're stuck with the broken thing forever. Client libraries at least special-case "none" now and make it auto-fail, which has probably saved a few people that didn't actually read the spec.)
The big problem here is that none of this matters. People do abuse OIDC as a general-purpose token for individual applications, but almost nobody does that with SAML. The point of these schemes is to federate authentication. In other words: it only matters what Okta and Google will agree to do. Your options are OIDC or SAML.
If you had to pick between the two, I guess you should pick OIDC, and think about what Ryan Sleevi said downthread about certificate verification; you'll want some kind of pinning scheme (pinning is a mess in client-server situations, but still sane in server-server applications; in fact, server-server pinning long predates browser public key pinning).
If you're not federating authentication, I don't think you should use JSON tokens of any sort.
You forgot to add the part - what if someone wants to add comments randomly without it changing the signature, even when those comments (mildly) change how the xml doc is parsed!
This is what we use in the military to provide provenance assurance, classification markings, and authorize dissemination destinations for digital intelligence products, and also what we use for manifests to enable trusted data transfers from unclassified to classified networks.
It's pretty interesting to be on a network where everyone has a PKI identity. Your client certificate gets sent to your sponsoring agency's personnel database, which returns the exact set of clearances you have, that gets sent to the server you're requesting information from, and you get back a web page with exactly what you're authorized to see and everything else redacted. No need to login and you can access any page you know the name or address for. You just may not see anything on it.
[1] https://www.dni.gov/index.php/who-we-are/organizations/ic-ci...
Those use cases are valid. The second one is actually the reason why JSON can't be used for a similarly usage (there is not canonization standard, and reading then writing a file could reorder the elements order).
You can defend DSIG in a lot of different ways. I'll disagree with all of them and feel like I could probably win the argument; DSIG is a cursed standard. But that's not the bar you have to clear in this discussion; here you have to establish that DSIG is good for SAML. It clearly isn't.
The former might be important for something? But generally also very nearly impossible to do correctly. When that is the case, one should contemplate whether the actual business requirements can be fulfilled another way, instead of making things broken by design.
² "canonicalize-encode-sign" as opposed to the correct way of "sign blob, parse blob".
I think it's funny because engineers are always portrayed as being grumpy and that they hate everything, but if you look at how they handle errors or security, they seem like the type of people that like everything and always imagine the happy path ;)
But I also think that latter part should be just given more weight in software engineering in general. A simple example is regex: most people tend to think about writing regexes that positively match expected input, but this generally results in expressions that match things it shouldn't. Writing them is generally easier and more straightforward when you think about not matching what they shouldn't!
Isn't this Postel's law in practice? https://en.wikipedia.org/wiki/Robustness_principle
There's a competitive advantage in handling bad input, right? I'm not saying it should always be the primary consideration and certainly not in security situations, but I think that competitive pressures are how we arrived at this situation.
A clawback of bonuses for security vulnerabilities might be an interesting idea? Or better yet bigger bonuses if there are no breaches.
Agency problem. Those who decide budgets and project timelines get the upside in such a bonus scheme, while whose who implement get the downside. Clawback bonuses, and the engineers not only get blamed, they get laid off to make the quarterly numbers for the management who want to make up for lost bonuses.
I suspect the solution lays in the spec complexity. Haven’t thought of this much, so my wrongthink knee jerk reaction is make a set of reference test harnesses part of the SOT of the spec, and that is the first step towards more robust implementations. Would like to hear how others have approached this problem space.
Yup, and its complexity leads to something of a shortage of libraries in the first place so there's not much choice.
There's still no good modern maintained OSS .NET 5 library for doing SAML. There are some commercial offerings (ComponentSpace have a neat product and they weren't affected by VU#475445 either) but my worry is that folks will end up using whatever free libraries they can find without thinking too much about the consequences.
It checks that you get a signed assertion back, which is valid, and lets you pull out attributes. That's great, but there are a gajillion tags that can be set within an assertion that have genuine, important security implications and zero of them are handled by this library.
If your IdP sends those tags along with the assertion, this library will happily ignore them unless you implement support yourself. And I would bet heavily that approximating zero of this library's users write that support.
One trivial example, there's a `<saml:Conditions>` tag. This tag can have all sorts of attributes like `NotBefore` or `NotOnOrAfter` that specify a time period for which the assertion is valid. This library does not do anything to implement support for `<saml:Conditions>` tags at all, so every consumer of this library will happily process assertions as valid even if they're outside of the duration for which the IdP is claiming it's valid. If I get my hands on an assertion at some point in time, I can hold onto it and replay it forever to unsuspecting users of this library. There are other attributes that can set conditions, and there are other tags with implications on whether or not an assertion should be considered valid. None of them are handled.
Further, only minimal document validation is performed. The signature is checked, but the Issuer is not. Multiple Issuers can share a signing key, though I suspect actual cases of this are rare. At any rate, there's a billion ways users of this library can blithely chug along with an assertion that isn't valid and shouldn't be trusted, but nobody notices or cares because the happy path works.
With authentication, yes it's important that legitimate users are able to sign in. But it's as important that illegitimate authentication attempts are disallowed. And this half is completely forgotten about in literally 100% of the common SAML service provider libraries I've seen in the wild (which is admittedly not 100% of the ones available, just the ones I've looked at).
Edit: As @tptacek points out, every user of this library is trivially susceptible to AudienceRestriction authz vulnerabilities. An IdP can include a statement in an assertion that limits it to one intended service provider (e.g., "this document authenticates user FOO for Google service BAR"). Users of this library will simply see "this document authenticates user FOO" and authenticate that user, even though this document was never intended for them. Again it's been awhile so I might be mischaracterizing it a bit but that should be the gist.
FWIW, yep. It has no knowledge of AudienceRestriction:
$ grep -i AudienceRestriction Saml.cs
$(note that I don't know anything about SAML except how to configure certain applications for it).
Clients can be much harder because you can any number of combinations of instructions thrown your way and you have to respect their intent. This is much harder to deal with.
Edit: I know the article talks about this, but my point is that his description of the round-trip instability isn't quite right. You can't change the bytes arbitrarily.
Use few shot prompts with well put together examples, then iterating over every item in the specs, and finally running the generated code through a human review process - seems like you could shift a lot of effort towards validation, and in doubt so, devise a process subject to further automation.
Crawling the resulting codebase with various prompts like "this part of the specification could be improved by..." and then review a set of 20 completions for any real value.
This might work for xml,html, and so forth, but even if you only have a system that generates a baseline library for one standard, it could be powerful.
I can't personally fathom how throwing GPT at the problem will improve things, but I can trivially see how it could result in code that looks correct to the author but isn't to anyone who read the spec. Maybe that's a failure of imagination on my part.
Then again, I suppose that's the situation we're already in where well-meaning authors don't think to actually read the specs and so don't actually comprehend any of the details.
And as sibling comment alludes to, security implications are very frequently areas that require very deep knowledge both of the standard and of how breaks in security protocols usually end up happening. How many commenters on this article were aware of the potential for canonicalization attacks in security before reading the article or the comments here? I'd wager relatively few.
[1] If you're wondering how almost all binary searches could be wrong, the answer is they fail to account for overflow in calculating the midpoint.
I don't know how GPT could help with that. If anything I would expect it to bias toward things it has already seen, which is the opposite of what you want when writing a new spec/library aiming to avoid past mistakes.
And somehow still manages not to include any helpful description of SAML.
Multiple exceedingly obvious vulnerabilities have been the result. One fun one was: looking at an XML signature in the document, verifying it, then ignoring the assertion it was claiming to sign and just trusting the assertion at the document root.
I tried to write a standards-based implementation and gave up. The standard is enormous, and consists of three parts:
Half the problem comes from the fact that it's meant to do anything and everything, and so you can theoretically just mix and match all the above parts to get what you want. But that also means that it's exceedingly simple to mix and match stuff in ways that are subtly (or not so subtly) insecure. The other half comes from the fact that the standard is so damned complicaed in order to handle everything under the sun that it's damn near impossible to wrap your head around it all. So people just glance at the spec occasionally and just write something that handles documents they see in the wild and hope for the best, with predictable outcomes.The whole thing is a tire fire.
Note, I last worked with it about a decade ago so I may have gotten some of the characterizations wrong.