Why is digital signature part of SAML assertion file? - oauth-2.0

I need to conduct the SAML Bearer Assertion Flow from OAuth 2 manually via Postman to proof that it works with our backend. Therefore I created my own SAML assertion file using [1] as reference (scroll down a bit to see the sample SAML assertion).
I wonder why the digital signature (value of XML element ds:SignatureValue) is part of the file that contains the SAML assertion. Of course I cannot include the signature inside the thing that is being signed. So I wonder what/which part of the assertion is being signed.
[1] https://help.salesforce.com/articleView?id=remoteaccess_oauth_SAML_bearer_flow.htm&language=en&type=0

ds:SignatureValue is required in the Assertion to verify that the Assertion part is not modified and intended to be sent by the Identity Provider (IdP) to the Service Provider (SP) only and no one else modified during the transit.
Typically the Assertion part (excluding ds:Signature element) is signed, set at ds:SignatureValue element, related signature details are appended to ds:Signature element and sent to SP by IdP.

Related

Does Proof Key for Code Exchange (PKCE) work without TLS?

Below I have tried to justify my question, "Does Proof Key for Code Exchange (PKCE) work without TLS? I believe I am missing understanding part of the spec and was hoping for some direction. I also have a second question, Does PKCE only relate to using Cookies to store the auth token (not mentioned in spec).Please help me identify the misinformation or lack of information in my comments below.
rfc7636's introduction section describes an attack authorization code interception attack on public clients. It states,
the attacker intercepts the authorization code returned from the
authorization endpoint within a communication path not protected by
Transport Layer Security (TLS) ...
The Introductions PreCondition section item 4 indicates that TLS not protecting the response .
The Introductions "To mitigate this attack" paragraph the states
This works as the mitigation since the attacker would not know this
one-time key, since it is sent over TLS and cannot be intercepted.
and
this extension utilizes a dynamically created cryptographically random
key called "code verifier".
RFC6949 mentions attacks around the use of cookies; however, rfc7636 does not specify pertaining only to cookies or local storage of the Auth token. Therefore is seems it would resolve an attack on the request if the auth token was also stored dynamically. Is this the case?
PKCE is used as a proof that the party which initiated authentication (via a browser redirect) is the same party completing it (via an HTTP POST).
It works without TLS, as in steps 4 and 8 of my blog post, where the code verifier in step 8 must match the code challenge in step 4.
Cookies are not directly related to PKCE. However, in a browser based app without PKCE or a client secret, malicious browser code only needs to send the authorization code to get tokens. If tokens are stored in cookies then the malicious code can only perform session hijacking.
PKCE was originally introduced for public clients that cannot use a client secret. These days, it is recommended for all clients that use the code flow, including those with a client secret. And of course TLS should also be used.

Do I Pass the Identity Token in a Header or Body of a Post Request?

The access token and refresh token being in the header makes sense to me (from this answer), but I'm wondering the same thing for ID or Identity Tokens. Should those be:
Passed into the body of a post request?
Passed into some header (Authorization header is used by the access token)
Something else (I'm misunderstanding the purpose of the identity token)
A little more context, through SSO, I would like to take the claims of a user (present only in the Identity Token) and sign them up in my system. I can confirm I can do this easily by throwing the identity token into the body of the initial POST request (and validate the signature on the server), but wanted to check if I'm breaking some standard.
Thanks!
In principle you can pass the ID token assuming that:
the software that consumes and validates the ID token (Relying Party, RP) is part of the same application and security domain as the target system
the link between the RP and the target system is secure i.e. authentication of both parties and confidentiality of the communication is established
the target system indeed requires all of the information in the ID token, otherwise it would be better to apply minimal disclosure and pass only a subset of the information
Passing the ID token (or the subset of claims) in headers may work if the amount of data is relatively small, otherwise you may run into HTTP header length limitations. Using POST though has the downside of having to modify the application request in flight which may be harder and have side effects.
For completeness, the refresh token is never passed in a header and only sent to the Authorization Server / Provider by the RP in a POST request.

In OpenID Connect with PKCE, how does the client know which code_verifier to send with which authorization code after user redirect?

I'm taking a ASP.NET security course on OpenID Connect authorization code workflow with PKCE protection against code replay attack. There is one aspect of this process that I don't understand.
The process:
Relying client generates PKCE code_verifier, hash it into code_challenge, and send the user to the authorization server with the code_challenge as a query parameter.
The authorization server stores the code_challenge, issues authorization code, and redirects user back to client with the authorization code.
The client sends the authorization code along with the original code_verifier to exchange for tokens. The authorization server verifies that the code_verifier indeed hashes into code_challenge before issuing the token.
My question is step #3: since HTTP is stateless, how does the client know which code_verifier to send along with the authorization code? Is this code_verifier stored in a cookie on the user agent?
Using a cookie to store the "code verifier" appears to violate the spirit of the OpenId specification and just appears to be a big security hole.
In brief, the spec expects you to use S256 to hash the code verifier and the code verifier to be kept secret from eavesdropping or being guessed.
PKCE RFC Section 7.1 says the "The security model relies on the fact that the code verifier is not learned or guessed by the attacker. It is vitally important to adhere to this principle. As such, the code verifier has to be created in such a manner that it is cryptographically random and has high entropy that it is not practical for the attacker to guess."
... "The use of "S256" protects against disclosure of the "code_verifier" value to an attacker."
Now it does give an opening to using a cookie if you encrypt the "code verifier". Here is the what the spec says in
Section 7.2: "If the code challenge method is "plain" and the code challenge is to be returned inside authorization "code" to achieve a stateless server, it MUST be encrypted in such a manner that only the server can decrypt and extract it."
Well, OpenId specification has a solution and Microsoft has provided an implementation to follow. Refer to the "state" parameter in the OpenId specification when calling the "authorization" endpoint. The Identity Providers will return the value back to the caller.
The way it is done in .NET Core is using the "state" query string parameter whereby the value is a dictionary but protected (encrypted). For help look through the .NET core code and look at the method "BuildChallengeUrl" in "Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler"
Also, this Site has a great idea that works. It's a valid option.
PKCE was originally intended for mobile clients, which typically make only a single authorization request. But it is now recommended for all clients using the authorization code flow.
You're correct that if the client is a web application serving many users, the client application needs to associate the correct code_verifier with the authorization request.
As you say, the client could store the code_verifier in a cookie, so it will be sent to the client together with the authorization code.
Or it could store it server side on the client and stick the key in the state parameter to the authorization request. The state will be part of the call to the redirect_uri if passed along with the authorization request.

Is OAuth signature credible?

I am looking at OAuth1.0A documentation to implement similar protocol. Doing this, I'm trying to find justification for every element in the request.
I wonder what's signature for. So far I understand that signature can be used to guarantee of data integrity. But, what if a hacker crafts the signature using oauth_signature_method stated in oauth request?
I have known that we can guarantee the sender identity by appending shared secret to base string before encoding. Then, the signature is worth only when shared secret is appended. Right?

SAML Request - Declare Multiple Protocol Bindings

I have implemented a SAML Service Provider to support Single Sign On for an ASP.Net web portal, which is a shrink-wrap software configured on clients' sites and must be able to interact with any SAML-compliant Identity Provider.
My Assertion Consumer Service (ACS) page will accept the SAML Response through both GET and POST methods.
As I understand the SAML protocol, the SAML Request ProtocolBinding property specifies which protocols are supported for the response. Currently, my request specifies the HTTP-Redirect binding. However, I would like to declare that I support both HTTP-Redirect (GET) and HTTP-POST (POST). After searching through more SAML documentation than I care to reiterate, I am unable to find the syntax for declaring multiple supported protocol bindings (or whether it is even valid to do so).
While I could make this declaration configurable, my preference would be to declare both bindings so that the Identity Provider will work without additional configuration of my portal.
Below is a sample of my Authentication Request. Please, if anyone knows a way to declare both HTTP-Redirect AND HTTP-POST for the ProtocolBinding, I would greatly appreciate your input!
<?xml version="1.0" encoding="utf-8"?>
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="[AUTHN_ID]"
Version="2.0"
IssueInstant="[ISSUE_INSTANT]"
ProtocolBinding="urn:oasis:names.tc:SAML:2.0:bindings:HTTP-Redirect"
ProviderName="[PROVIDER_NAME]"
AssertionConsumerServiceURL="[ACS_URL]">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
PortalEntityID
</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />
</samlp:AuthnRequest>
Thanks in advance to anyone who can help!
The ProtocolBinding attribute on AuthnRequest is used to specify the expected binding to be used by the IdP when sending their SAML Response XML. HTTP-Redirect isn't a valid option to use here, because of the possible length restriction on the URL querystring; a SAML Response, especially if it's signed, can be pretty lengthy. I'll quote from the SAML spec [SAMLProf]:
...the identity provider issues a <Response> message to be delivered by the user agent to the service provider. Either the HTTP POST or HTTP Artifact binding can be used to transfer the message to the service provider through the user agent. The message may indicate an error or will include (at least) an authentication assertion. The HTTP Redirect binding MUST NOT be used, as the response will typically exceed the URL length permitted by most user agents.
After considerable research, it seems that you can only declare one Protocol Binding in a single SAML request.

Resources