OAuth redirect URL validation - redirect

I am working on an existing OAuth system in my office.
The previous engineer left and I am not really experienced in this OAuth system.
So I read a few documents about OAuth. I see that my office, as the OAuth server
is getting a redirect URL upon getting auth code from the client.
Then I see a validation which preventing a single character in the redirect URL.
Example:
https://m.clientname.us/oauth/redirect
https://pre.m.clientname.us/oauth/redirect
Number 1 would pass, but 2 does not
Do you guys think there is a reason the previous engineer making this validation? Is there a standard about it not to put a single character like sample number 2? Thank you

I'm not sure what you mean by "single character", but the redirect URLs that your authorization server allows should absolutely be whitelisted to only registered redirect URLs. Any added subdomains or paths should cause the request to be rejected. Otherwise, an attacker can craft an OAuth request that looks valid to the end-user, but actually redirects them (with the authorization code) to their server.

Related

Create redirect url in facebook using php

I want to create a facebook redirect url like /fblogin?packgeid=1 in my Codeigniter application
where packgeid is a dynamic value like (1,2,3)
I tried https://localhost/project/fblogin?packgeid={} in facebook Valid OAuth Redirect URIs, but receive an error in facebook response like:
URL Blocked: This redirect failed because the redirect URI is not
whitelisted in the app’s Client OAuth Settings. Make sure Client and
Web OAuth Login are on and add all your app domains as Valid OAuth
Redirect URIs.
You can not use any placeholders or anything like that. If you need to transport any info in your redirect URI via GET parameters, then you would need to enter each any every specific URL explicitly.
The only parameter that is except from this, is the state value. Its main purpose is CSRF protection - but you can use it to transport your own values as well. It should not be a purely static or easily guessable value though (that would stop it from being effective as CSRF protection measure) - so maybe combine a random value and your parameter value, encoding it as JSON, or something like that - that would help you to easily take it apart on the receiving end again.
But do you even need to actually transport this via the redirect URI? Can you not just put packgeid=1 into your session, and then have the script decide what it needs to do after the user is redirect back, based on that?

What is the real purpose of Redirect_Uri in OpenIdConnect?

I am trying to setup OpenID Connect Authentication (Single-tenanted) for my web application. I understand how Reply Url in AAD is supposed to work. AAD admin registers a web application with SignInUrl, ReplyUri, AppIdUri,.. Microsoft AAD handles the complete user experience to prompt & validate the credentials. An attacker may not be able to pose legitimate site attack (since it is *.microsoftonline.com page).
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
Please suggest me how to view Redirect Uri. I would like to harness the real benefit.
What is the real purpose of Redirect_Uri in OpenIdConnect?
From the OpenID Connect, 3.1.2.1 Authentication Request:
redirect_uri
REQUIRED. Redirection URI to which the response will be sent.
This URI MUST exactly match one of the Redirection URI values
for the Client pre-registered at the OpenID Provider [...]
So, the purpose of redirect_uri is to tell the OpenID Provider (Azure AD, in your case) where the response to the request should be sent, after the user signs in.
Does it fight Redirect_Uri Attack?
The parameter itself offer the functionality described above, it doesn't mitigate any attack. It is the responsibility of the client (i.e. your app) and the OpenID Provider (i.e. Azure AD) to ensure they are doing the right thing to prevent exposing the risk of an attack (including an attack related to redirections).
For example, if an OpenID Provider did not validate that the redirect_uri from the request exactly matches a redirection URI configured for the client, then an attacker might be able to construct an authorization request with a redirect_uri pointing to a URL controlled by the attacker, and then trick a user into triggering the request. The response to the request would then be sent to the attacker, rather than to the relying party the user thinks they're signing in to.
There are other attacks related to redirect_uri which could happen if the relying party (i.e. your app, in this case) exposed a vulnerability (for example, by enabling an open redirection attack, or by authorizing a reply URL which is not actually in your control).
Many of these (and other) attacks, as well as the current best practices to mitigate or prevent them, are described in OAuth 2.0 Security Best Current Practice.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
This seems like there is an issue in your application. When Azure AD detects that the requested redirect_uri does not exactly match an authorized reply URI for the client, Azure AD does not redirect back to the client with an authorization code or any tokens.
It is possible that your app had already established a session previously, or is incorrectly processing the OpenID Connect flow. It's impossible to say without knowing the specific details of how the app is implemented.
Now I think I found the mystery behind the signin-redirect_uri anomalies.
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
[OP] Yes, it does. If redirect_uri domain differs from AAD server Registration and web client, it invalidates the sign-in attempt.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
[OP] Redirect_Uri does not behave when I hosted my application in localhost even on different ports or same domain. So, it ignores Redirect_Uri validation, if I click on Sign-In despite the first Reply-Uri-Mismatch error.
Please note that Redirect_Uri does handle Open redirect attack if an attacker wants to redirect the victim to illegitimate page for re-entering the credentials.

Okta is returning an invalid redirect uri when connected to IdentityServer 3 and performing sign out

I'm trying to integrate Okta as a third party Identity Provider for a system I am working on that is using the IdentityServer 3 framework to support my customers that use Okta. I have everything working great except log out. When a user logs out of my system, it initiates the end session call back to Okta to log the user out. My problem is that the Identity Server is sending a session id along with the post logout redirect uri for context, but Okta refuses to accept the redirect uri because it is not known. I've tried multiple variations in the setup in Okta for this url but because the id value is dynamic, i'm not able to specify an exact url. Is there a way to have it support any urls that are going to a specific hostname or even up to the page path? I've tried adding my host into the API security area for trusted origins but it did not work either. I've also tried overriding the postback url for my system to be a static page, but then the IdentityServer Signout message cookie is never cleaned up correctly. This same code works without any problems when running for Azure as the IDP. Has anyone run into this before and have any thoughts? Any help is appreciated.
An example of the post to Okta at signout with the postback url is something like this,
https://dev-xx.oktapreview.com/oauth2/default/v1/logout?post_logout_redirect_uri=https%3a%2f%2fmyurl.com%2fidp%2flogout%2f%3fid%3d83617adbc6769e5d4d0fbca4dced3991&max_age=5&id_token_hint=eyJraWQiOiJ1aXJYc1RYTkTVVGenBXU1JfMWt6WndNSXBQQUVqT0dndWhjbloxR3pNIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHU4eTlrajNyT2NreW11cTBoNyIsIm5hbWUiOiJKYW1lcyBSZWFtZXMiLCJsb2NhbGUiOiJlbi1VUyIsImVtYWlsIjoiamFtZXMucmVhbWVzQHJlYWxwYWdlLmNvbSIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9kZXYtNDg5MDgyLm9rdGFwcmV2aWV3LmNvbS9vYXV0aDIvZGVmYXVsdCIsImF1ZCI6IjBvYWVvdXMycWFJTWJ3U0dhMGg3IiwiaWF0IjoxNTM2MjQ5NzY2LCJleHAiOjE1MzYyNTMzNjYsImp0aSI6IklELlVUem5sTC1FRUY0aHFoZlNSbG5wV1cyUGRxQzlBRk1PcDZiOTh6UERRUUEiLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwbzh5OWZycXVmOFlpaG50MGg3Iiwibm9uY2UiOiI2MzY3MTg0NjU0NTA1NzI4ODQuWldOaVlqZG1aamt0Wm1Fd01TMDBNVGc1TFRreE4yTXRaR1kzTWpreVl6ZGpOekprTm1GbU16WTJaRFl0TURBeE15MDBNMkUwTFdJM01ERXRNek5oWTJOaU1qZ3daamd4IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamFtZXMucmVhbWVzQHJlYWxwYWdlLmNvbSIsImdpdmVuX25hbWUiOiJKYW1lcyIsImZhbWlseV9uYW1lIjoiUmVhbWVzIiwiem9uZWluZm8iOiJBbWVyaWNhL0xvc19BbmdlbGVzIiwidXBkYXRlZF9hdCI6MTUyMzYyNjUzMiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1dGhfdGltZSI6MTUzNjI0OTc2NiwiY19oYXNoIjoiMWoxa1JTSGhObGRGWGNmSDdCQXRBUSJ9.gvG_8dnlAMr9XI-atCjIKVF04L4oMzerXmeT0BAG76RLle-q2pgb8PDvV4cTicLH16QLzboSgocC6t6WoegbUeJLLuzZHd2rQkm8Y4iRheoV05uKhd2mpLA9LyexlJ9oVJ8Xi_D4BqN_bygphAv79B4L8-Ezz3YgGDmSkK3WutB55_r_7XM0OCCCetvNu4S8KXbKHUxgg5cpQ6y7o-d5eIH6I8bpoOoA0gy7Liwsm7IyQUe5_jdorObgBHIEfDx4mjNRENJUQ7InASwbL7eND7COZYyXRwzn7vHU0_XkBaUW9wsY-VJUaihOwEcgVS1MPbGLoSUY9k0TmcUVN3-Q&state=83617adbc6769e5d4d0fbca4dced3991&x-client-SKU=ID_NET&x-client-ver=1.0.40306.1554
the id=83617... is what is tripping up Okta from trusting the redirect url. I've tried adding all of these combinations of urls into the logout redirect uri setup and none let it accept it,
https://myurl.com/idp/logout/
https://myurl.com/idp/logout/?id=
https://myurl.com/idp/logout?id=
https://myurl.com
https://myurl.com/
https://myurl.com/idp
https://myurl.com/idp/
https://myurl.com/idp/logout
None seem to work.

Optional SPNEGO Kerberos authentication

Is it possible to do optional kerberos authentication?
What I want is: if the client (browser) is not on the domain it is redirected to a username/password web login. Otherwise it will do SPNEGO do Kerberos authentication.
If I just send the WWW-Authenticate: Negotiate header to a non domain browser it just does nothing further.
Is there some option to tell the browser to try something different if it doesn't know how to authenticate? Or do I have to determine if user is part of the domain before sending the "WWW-Authenticate" header?
I haven't found anynone who has solved this publicly and in a standard way. Yes, as mentioned, one could fall back to Basic but that doesn't work for authentication schemes which involve requesting a username and password from a CGI form where, as far as the browser sees things, you're falling back to no authentication if Negotiate fails. Maybe that is suggestive that the authentication scheme is broken? I don't know.
I'll tell you what I know, first. Our site is, effectively, Cosign-protected, so we have a similar problem to you: only specially-configured machines respond to the WWW-Authenticate header, so by default we must send all users to our Cosign login page. The trick is that the Cosign server also allows authenticated GSSAPI/Kerberos hosts to complete the authentication process without entering login details, but only on certain browsers, by means of a workaround.
This workaround consists simply of a block of JavaScript within the login page which attempts a HEAD of an SPNEGO-protected resource; if successful, the script redirects the browser to an SPNEGO-protected version of the same page, which grants appropriate Cosign cookies and completes the process without password entry. If the browser lacks any one of JavaScript, Kerberos support or adequate credentials, then the user will see the cosign login page as usual.
So, the above alone might count as an answer to your question; personally though I don't think this goes far enough and what follows is more of a discussion...
The above seems unsatisfactory as it insists that any connecting user agent supports either JavaScript (unlikely to be the case for text-based browsers and HTTP client libraries) or knowledge of the arbitrary path to which we redirect Kerberos-capable users (useless to anything which has not been hard-coded for our site). I've come to the conclusion that there might be a better workaround, or if not, a gap where a standard should be. The best practical suggestion I have is this:
A normal part of the SPNEGO process is that the client attempt to retrieve a page whose initial response is an HTTP 401 but with the header WWW-Authenticate: Negotiate. This is the cue for a GSSAPI/Kerberised client to respond appropriately; a "regular" client will simply display the error page. Perhaps the solution is simply to modify the Cosign server to deliver the human-friendly login page as part of this error response?
It might be technically difficult with off-the-shelf Apache and modules, and might go against various standards (or at least principles). I'm no expert on the systems involved, so can only speculate unless (or until) I get a chance to try it out...
Send additionally WWW-Authenticate: Basic for username/password challenge.
It depends on the application server, for example in JBoss you can set <auth-method>SPNEGO,FORM</auth-method> in web.xml and it should fall back to a login form "in cases where Kerberos/SPNEGO tokens are not present":
See https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.2/html/how_to_set_up_sso_with_kerberos/additional_features

Submitting a form to a secure url from a non-secure page

Suppose I have a form on a page at this location...
http://mydomain.com/myform.htm
And the form looks like this...
<form method="post" action="https://secure.otherdomain.com/handleform.php">
....
</form>
Assuming that there is a valid SSL cert installed on the server which receives this form submission will the contents of that form submission be encrypted?
The POST request will be transmitted over HTTPS (so encrypted if configured properly). Submitting a form from a page obtained over plain HTTP to an HTTPS page is bad practice. The initial page should also be served over HTTPS. The reason for this is that a MITM attacker could intercept the response that loads the page with the form and replace the link to point to another target.
See the first rule here (of course, not specific to login pages):
https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Use_TLS_for_All_Login_Pages_and_All_Authenticated_Pages
Rule - Use TLS for All Login Pages and All Authenticated Pages
The login page and all subsequent authenticated pages must be
exclusively accessed over TLS. The initial login page, referred to as
the "login landing page", must be served over TLS. Failure to utilize
TLS for the login landing page allows an attacker to modify the login
form action, causing the user's credentials to be posted to an
arbitrary location. Failure to utilize TLS for authenticated pages
after the login enables an attacker to view the unencrypted session ID
and compromise the user's authenticated session.
Assuming a valid SSL/TLS session can be negotiated between the server and the client, then yes. This means that the client must be willing to trust whatever certificate the server presents and that the two parties can negotiate a mutually-agreeable cipher set (what algorithms to use, etc). There are plenty of configuration options you can set to alter what is allowed, but in a "normal" implementation where you don't go messing around with requiring a specific, non-normal, algorithm, requiring client-side certificate authentication, etc, everything should work just fine and you'll have a protected session...and if it fails for some reason, you'll know as your client will receive an error about what went wrong.
Note that, in general, while you can do this, and the transmission would be encrypted, you generally should not. Having an unencrypted/protected page submit to one leaves you vulnerable to a couple types of Man in the Middle attacks. You can see the OWASP article on this, and why it's bad, here.
Yes. It will be transmitted securely.