Security

SAML attack lab

Does your application accept what it should refuse? ID-Kit plays the IdP and sends booby-trapped responses: you check that every trap is refused.

How it works

  1. Create a test identity provider and link it to your application.
  2. Start a sign-in. At the “Who do you want to simulate?” step, pick a scenario below.
  3. Your application must react as described. If it accepts a trap, that is a flaw to fix.

Classic attacks

"Signature wrapping" attack

Your application must refuse or read only the signed assertion. If it logs in "admin@evil.example", it is vulnerable.

XML comment injection in the NameID

Your application must read the FULL NameID (alice@example.test.evil.example) or reject. If it understands "alice@example.test", it is vulnerable to the 2018 attack: an attacker could impersonate someone else.

No signature

Your application must refuse: nothing proves the response comes from the IdP.

Content modified after signing

Your application must refuse: the identity was changed after signing.

Signed with another key

Your application must refuse: the signature is not from the trusted certificate.

Two assertions with the same ID

Your application must refuse: an assertion ID must be unique, otherwise the signature can be hijacked.

Two audience restrictions, one of them wrong

Your application must reject: all AudienceRestrictions must be satisfied (it is a logical AND).

Hostile attributes (HTML, quotes, Unicode)

Your application must display these values without executing them: no script, no interpreted HTML, no crash on quotes or emojis.

One-time-use assertion (OneTimeUse)

Your application must reject a second submission of the same assertion (replay). Try sending the same response twice.

InResponseTo missing

For a sign-in started by your application, it must reject a response that answers no request (unless it accepts IdP-initiated sign-ins).

Response content

Expired assertion

Your application must refuse: the validity period is already over.

Assertion not yet valid

Your application must refuse: the validity period has not started (useful to test clock tolerance).

IdP clock 5 min ahead

An application with a clock tolerance of 2 min refuses; with 5 min or more, it accepts. Lets you find out its tolerance.

IdP clock 5 min behind

The assertion expired 5 minutes ago: refused if the tolerance is below 5 min.

Session already expired (SessionNotOnOrAfter)

Your application must consider the IdP session as ended: it must not open a session longer than this one.

Wrong audience

Your application must refuse: the assertion is meant for another application.

No audience restriction

Your strict application must refuse: nothing says which application the assertion is for.

Wrong recipient (Recipient)

Your application must refuse: the confirmation names another ACS address.

Wrong destination (Destination)

Your application must refuse: the response is addressed to another URL.

Response to a different request (InResponseTo)

Your application must refuse: this response matches none of its requests.

Wrong issuer (Issuer)

Your application must refuse: the response claims to come from a different IdP than the one it configured.

Identifier (NameID) missing

Your application must refuse or show a clear error: it does not know who is logging in.

No attribute sent

Login may succeed, but the application must handle a missing name, email or groups without crashing or granting default rights.

Weaker authentication level than requested

If your application asked for strong authentication (RequestedAuthnContext), it must reject: the IdP only states a simple password.

Rotation: the IdP changed certificate

If the application has BOTH certificates (old + new, option "publish the next certificate"), it accepts; if it kept only the old one, it refuses. Reveals whether a certificate rotation will cause an outage.

Assertion encrypted for another certificate

Your application must refuse: it cannot decrypt the assertion and must say so clearly (without crashing).

IdP refusals

Login refused by the IdP

Your application must show a clear error and log nobody in.

Refusal: NoPassive (silent sign-in impossible)

Your application, if it asked for IsPassive, must redirect to a normal sign-in screen instead of showing a raw error.

Refusal: RequestDenied

Your application must display a clear error (the IdP refuses to process the request), without crashing or looping.

Requester error: InvalidNameIDPolicy

Your application must report that its request (NameID format) is not accepted by the IdP.

Refusal: VersionMismatch

Your application must display a clean protocol error, without crashing.

Never send real secrets there: these are fictitious identities.