Fall back to normal Http after WIF STS Authentication - ws-security

I have an MVC3 web app that does auth to a customization of StarterSTS. I require the realm to be known and the authentication to require SSL.
It works, great.
The problem is when the user lands back onto my website they are browsing with https. This isn't really the experience I want. My site is not a bank or anything of the like. I feel the authentication conversation should be secure (I think) and the token encrypted (I'm sure). But if I manually change the url from https to http on my replying party web app after authenticating it says I'm not authorized.
1) why?
2) Is it possible to fall back to http ? or ... Should I not require https for the authentication, but leave the token encrypted?

Well - what's wrong with SSL?`
The token should be always transmitted using SSL - even when it is encrypted, it could be replayed etc.
Also the resulting session token needs to be protected. So I would go for SSL (easy to setup) and not worry about possible attacks that result from not using it (hard to implement).
That all said - you can turn off the SSL requirement on the wsFederation (requireHttps="false") and nested cookieHandler (requireSsl="false") configuration element.

Related

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.

Authentication with Akka-Http

We're developing an iOS app, where the user needs to authenticate using email+password (or mobile number). Our backend is made of a couple of microservices using Akka-Http. It needs to be fast, scalable, concurrent, and the authentication+authorization should work across our multiple services.
I'm trying to figure out which authentication method to use.
Akka-HTTP currently offers Basic Auth and a partial implementation of OAuth2.
So at first we were considering Basic authentication (too simple and not enough functionality), Oauth1 (too complex), so we moved towards OAuth-2.0 because it is sort of a standard.
Then we considered AWS Cognito because it combines Oauth-2.0 and OpenID Connect which gives the authentication mechanism that OAuth2 lacks.
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html
Then we realised that OAuth2 is just for authentication using a third party - when in fact we don't need a third party authentication provider - maybe we need to do it ourselves, and using Cognito is an overkill that would create extra api calls outside our microservices...
So I read a little bit about creating our own custom auth provider, using WSSE specs:
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
And I also found this example using Spray, but I'm sure it's not that different from Akka-Http:
http://danielasfregola.com/2015/06/29/how-to-create-a-spray-custom-authenticator/
It looks too simplified and doesn't have token expiration...
So my question is, am I missing something? What method should I chose and where can I find examples for it?
I feel like I'm going in circles, we're gonna have to write our own custom authentication provider from scratch, which kinda doesn't make sense. After all almost everybody needs authentication and it should be a standard.
I've recently been using SoftwareMill's akka-http-session library and found it simple and easy to integrate. It has support for case class based sessions, JWTs, refresh tokens with pluggable storage, using headers and CSRF tokens as well as some nice simple directives for use in routes.
My solution for user registration has been to use Keycloak, an open source server which can handle user registration and do OIDC, OAuth2 style login. It reduces the amount of code I have to write, and the code is more secure than if it rolled it myself.
I then write my application as Scala backend that's purely a JSON API and a React/Javascript rich frontend in front of that API. In this configuration the authentication is handled completely on the front-end (and can be done in your iOS client). The front-end app redirects the user to Keycloak and when the user comes back they have a signed "JWT" token you can keep in a cookie.
That JWT token is attached to all API calls made the JSON backend as an Authorization Bearer token HTTP header. The token itself contains the users email address and is cryptographically signed by the Keycloak server.
The backend gets the JWT token in the HTTP header, extracts the email address and verifies the token is cryptographically signed by the keycloak server.
It's performing a certificate check on the keycloak server and can cache it's certificate. So it doesn't need to have roundtrips like OAuth, or any upstream calls to make.
This gives us simple, low-chance-of-failure, high speed authorisation in our JSON backend API and means we aren't putting secrets in the iOS client, or rolling too much of our own code.

OAuth2 security considerations for client_id

When using User-agent flow with OAuth2 for mobile platform, there is no way for Authorization server to authenticate the client_id of the application.
So, anyone can impersonate my app by copying the client_id (and so get all access tokens on my behalf), and this is applicable to Facebook, Foursquare,...
This is not managed by OAuth2 ? Or I missed something ?
For Web applications (Web server flow), access token is stored on the server side, and the client is authenticated using secret key.
There's no good answer. Native app callbacks typically happen via custom registered URI schemes (e.g.: callback redirection URI is something like: myapp://oauth?code=xyz123). Unfortunately, any app can claim ownership of a given protocol scheme and receive the callback.
This problem is very synonymous with trying to lock down any protocol with "trusted clients". Think of the IM networks battle to lock out 3rd party clients (in early 2000's). Eventually they gave up - since whatever client & protocol endpoints are deployed could be reverse engineered by 3rd party developers.
Note: There is also some active discussion on this topic on the OAuth WG mailing list: http://www.ietf.org/mail-archive/web/oauth/current/msg08177.html
Normally client_id is associated with site's URL - OAuth responses/redirects will be sent only to the registrated Url. So attacker will not be able to receive results of the request on own site (unless somehow your and attacker pages are on the same domain).

Use Plone to authenticate users from mobile devices

I'm starting to create an iPhone/Android app that will need to use Plone users (i.e. register on the website and then enjoy the app on your mobile).
What's the best approach on doing this? I've seen some apps using OAuth or other techniques, which ones currently supports Plone4 (4.0.3 exactly).
I have the users on a LDAP server (OpenLDAP) but even that I still have to log them on Plone to be able to send and retrieve data from there to the mobile phone.
You have 3 options, and what you choose is dependent on what your skills are and how much time you are willing to invest:
Basic auth
Have your user enter a username and password into the app, and just use HTTP BasicAuth headers to access the site. Plone supports Basic auth authentication out of the box.
This is not the most secure method; passwords are basically sent base64-encoded, so you may want to use HTTPS to communicate with the server. A good idea in any case for authentication anyway.
Cookie authentication
Send a POST request with __ac_name and __ac_password items to '/login_form' on your Plone site, and capture the Set-Cookie header on the response, containing the __ac cookie. That's a tk-auth authentication token you can use on any subsequent request. This is a secure cookie, but any attacker sniffing the HTTP communication stream could re-use this, so again HTTPS is the secure way to communicate.
OAuth
Plone does not (yet) support OAuth out of the box, but integrating with python-oauth should be trivial. This would most likely require a PluggableAuthSystem (PAS) plugin to be written.

Security of REST authentication schemes

Background:
I'm designing the authentication scheme for a REST web service. This doesn't "really" need to be secure (it's more of a personal project) but I want to make it as secure as possible as an exercise/learning experience. I don't want to use SSL since I don't want the hassle and, mostly, the expense of setting it up.
These SO questions were especially useful to get me started:
RESTful Authentication
Best Practices for securing a REST API / web service
Examples of the best SOAP/REST/RPC web APIs? And why do you like them? And what’s wrong with them?
I'm thinking of using a simplified version of Amazon S3's authentication (I like OAuth but it seems too complicated for my needs). I'm adding a randomly generated nonce, supplied by the server, to the request, to prevent replay attacks.
To get to the question:
Both S3 and OAuth rely on signing the request URL along with a few selected headers. Neither of them sign the request body for POST or PUT requests. Isn't this vulnerable to a man-in-the-middle attack, which keeps the url and headers and replaces the request body with any data the attacker wants?
It seems like I can guard against this by including a hash of the request body in the string that gets signed. Is this secure?
A previous answer only mentioned SSL in the context of data transfer and didn't actually cover authentication.
You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs because you really want to authenticate the client.
If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth 1.0a or even HTTP Basic authentication (but over SSL only).
These schemes authenticate that the request was sent by someone expected. TLS (SSL) (without client authentication) ensures that the data sent over the wire remains untampered. They are separate - but complementary - concerns.
For those interested, I've expanded on an SO question about HTTP Authentication Schemes and how they work.
REST means working with the standards of the web, and the standard for "secure" transfer on the web is SSL. Anything else is going to be kind of funky and require extra deployment effort for clients, which will have to have encryption libraries available.
Once you commit to SSL, there's really nothing fancy required for authentication in principle. You can again go with web standards and use HTTP Basic auth (username and secret token sent along with each request) as it's much simpler than an elaborate signing protocol, and still effective in the context of a secure connection. You just need to be sure the password never goes over plain text; so if the password is ever received over a plain text connection, you might even disable the password and mail the developer. You should also ensure the credentials aren't logged anywhere upon receipt, just as you wouldn't log a regular password.
HTTP Digest is a safer approach as it prevents the secret token being passed along; instead, it's a hash the server can verify on the other end. Though it may be overkill for less sensitive applications if you've taken the precautions mentioned above. After all, the user's password is already transmitted in plain-text when they log in (unless you're doing some fancy JavaScript encryption in the browser), and likewise their cookies on each request.
Note that with APIs, it's better for the client to be passing tokens - randomly generated strings - instead of the password the developer logs into the website with. So the developer should be able to log into your site and generate new tokens that can be used for API verification.
The main reason to use a token is that it can be replaced if it's compromised, whereas if the password is compromised, the owner could log into the developer's account and do anything they want with it. A further advantage of tokens is you can issue multiple tokens to the same developers. Perhaps because they have multiple apps or because they want tokens with different access levels.
(Updated to cover implications of making the connection SSL-only.)
Or you could use the known solution to this problem and use SSL. Self-signed certs are free and its a personal project right?
If you require the hash of the body as one of the parameters in the URL and that URL is signed via a private key, then a man-in-the-middle attack would only be able to replace the body with content that would generate the same hash. Easy to do with MD5 hash values now at least and when SHA-1 is broken, well, you get the picture.
To secure the body from tampering, you would need to require a signature of the body, which a man-in-the-middle attack would be less likely to be able to break since they wouldn't know the private key that generates the signature.
In fact, the original S3 auth does allow for the content to be signed, albeit with a weak MD5 signature. You can simply enforce their optional practice of including a Content-MD5 header in the HMAC (string to be signed).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Their new v4 authentication scheme is more secure.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
Remember that your suggestions makes it difficult for clients to communicate with the server. They need to understand your innovative solution and encrypt the data accordingly, this model is not so good for public API (unless you are amazon\yahoo\google..).
Anyways, if you must encrypt the body content I would suggest you to check out existing standards and solutions like:
XML encryption (W3C standard)
XML Security