OpenID Security - Bogus OpenID Redirect - security

I'm trying to figure out how a site that accepts OpenID logins couldn't be hacked by a simple hosts file update to point to a bogus OpenID provider.
Lets say for instance I want to hack into Joe Smith's account and for this example, lets pretend his OpenID provider is http://jsmith.myopenid.com. What would prevent me from creating an entry in my hosts file, pointing jsmith.myopenid.com to an IP that I control. I would then fake the authentication and return a response saying that the user successfully logged in.
I know there would be an SSL mismatch warning in the browser, but since it's my browser I could easily ignore it. How does the requesting website know that the response it receives is actually from the site that was requested?
This seems like a basic attack, and I'm sure the people behind have included a solution for this, I just must not be searching on the correct terms to find the answer.

The relying party contacts the OpenID provider directly, either before authentication (to establish a shared secret key used to put an HMAC on the OpenID provider's response) or after authentication (to ask it to confirm the response actually came from the OpenID provider).
For your attack to work, you would also need to be able to control DNS lookups of the relying party, not just your own.

Related

Securing a https connection

I have exposed some rest services in spring, using spring mvc, I have secured the webapp using spring security, that uses bcrypt on the server to encode the password and store it in the datbase.
The user will send the password in the url in plain text under https, And i have written a custom basic_auth_filter to check the uername and passowrd - basically authenticate. I also have set up a firewall that only allows one ip to connect.
Im no security expert, is there anything else i need to, should i encode the username/password in the url.. even though it will be coming via https?
regards
ps. this was a requirement to use username on the url?
Passwords, and all other non-ephemeral credentials, should never be sent in the URL, if for no other reason then because the browsers and other HTTP tools and servers will remember this in history, various logs etc, HTTPS or not, making it trivial to steal by anyone with local access, or even by someone just looking over your shoulder. This is why Spring by default rejects authentication via GET requests.
For this reason, you should move the sensitive parameters to the body of the request (thus requiring a POST).
If your login flow is based on username/passwords, I recommend you use UsernamePasswordAuthenticationFilter as it already encapsulates the logic and best practices for this type of flow.
In general your scheme is secure.
Consider pinning the server, that is validating the server certificate, to ensure the connection is to your server.
The password should not be used other than to authenticate using (in your case) bcrypt.
Re question update: "HTTPS encrypts the query string, only the actual server address portion is un-encrypted. But, the full URL including query string will probably be logged by the server so that has security implication. It is best to send confidential information in a POST.

Does HTTPS prevent a valid user from tampering with the payload?

We have 2 web applications, both secured using HTTPS (server-side certificates only) and a single sign-on authentication system. In App1, a user will click a link which then needs to “drill down” into a page in App2. They share the same domain and SSL certificate, but are physically not the same app. When App1 forwards or redirects the request to App2, it includes an authentication token in the request so App2 can verify the user’s identity.
App1 knows what information the user is authorized to see, call it a list of accounts; App2 does not have access to this information (at least not at this time). It has been proposed that App1 may pass the list of authorized accounts to App2 as well, in the request.
My question is whether HTTPS protects the payload and guarantees that it was generated only by the App1/App2 servers? More specifically, my concern is whether a valid user, with a valid authentication token, might be able to build his own form with additional accounts and submit it as a valid HTTPS POST request to the App2 server and thereby gain access to unauthorized accounts?
No, HTTPS alone does not provide you with the security you're looking for. For an indication of how others have tackled the problem you're facing, take a look at this link:
SSO with SAML
It is about accomplishing SSO with the SAML protocol. In general if security is a serious concern of yours, you'll want to use a peer-reviewed solution (like SAML) instead of a DIY approach to single sign-on. You don't need to use SAML, but you should try to use an existing SSO solution available for your environment.
In order to "guarantee it was generated by the App1/App2 servers" -- you could digitally sign the payload. This would prevent tampering but may not prevent replay attacks -- SSL would help some with that as the transmission would be encrypted but replay attacks would still be possible (via perhaps a man in the middle attack)
HTTPS provides a secure communication channel.
But you could have a secure communication with the devil himself
:-)

REST service through SSL and HTTP Basic Authentication

In Securing an API: SSL & HTTP Basic Authentication vs Signature HTTP Basic Authentication is cited as an adequate way to secure REST web service calls if the REST calls are made through SSL.
But it seems this method will still not work for an unsecured client page that uses Ajax to make calls to the REST service that is protected behind SSL & Basic Auth.
I am trying to design an application that performs password reset using the usual way:
user enters username and requests "reset password" email
user receives email with a password reset link that includes a verifiable token
user clicks on the link and (after the token is verified) types in their updated password
By definition these pages do not require login. Can this UI be implemented using Ajax that calls REST services to do things like validate token, send email, etc.? Even if those REST services are protected behind SSL & Basic Auth, the information that you need to call the service (i.e. the application's "username" and password) will be at best in cookies which would be accessible through the browser.
I know I am missing something. I just don't know what :-)
As long as 1 - 3 happen under SSL, the data will be safe over the wire to the server (assuming you trust the certificate authority)
During that process, the browser will hold those credentials in memory. You have no choice but to trust that if the user is going to enter the data.
It is the web sites code that determines whether to store info in cookies.
I think you should be OK if 1 - 3 are under SSL.
I've no idea what you're protecting so I'l just toss some thoughts out.
SSL and TLS are not meaningful if you (or someone else who gives a hoot) aren't in control of the root list of the relying party. I say this because I expect that if you don't trust the guy with the key to the lock then you won't put your money in his vault. So if the users loading the login pages are in the wild so to speak then user/pass through TLS is a low bar, definitely good enough for protecting my favorite movies list.
Carby praises to the all being FSM

OpenID authentication on AppEngine and non-AppEngine subdomains

I have a main website running on AppEngine. It's on a subdomain like main.example.com. This main application is a content portal for our customers. It offers an Ajax application built on YUI. Customers can upload data to it. Users authenticate using Federated Login.
The Ajax application on it allows users to process the data previously uploaded. To do it it should use an webservice running on other subdomain like service.example.com. The webservice does not run on AppEngine but on our services - it's CPU heavy and built on other set of technologies. It would need to download the data on main application - but the downloading service - like everything on the main application - is behind the authentication wall.
I could programatically always allow the service to download wharever it wishes but I think this can turn into a major security problem.
How can I reuse the OpenID authentication "token" to allow it (the service) to appears to the main application as the authenticated user so it can download data? Or If I can do this what would be the best way to accomplish what I intend to do?
You can't really reuse the authentication token. What you should use is something akin to OAuth, though since you control both ends you can make it somewhat simpler:
Generate a shared secret, accessible by both main.example.com and service.example.com
When a user accesses service.example.com for the first time (no authentication cookie), redirect them to main.example.com/auth?continue=original_url (where original_url is the URL they attempted to access)
When you receive a request to main.example.com/auth, first log the user in the regular way (if they're not already). Then, take their user ID or other relevant credentials, and generate an HMAC from them, using the shared secret you established in step 1. Redirect the user to service.example.com/finish_auth, passing the computed HMAC, the authentication details such as user ID, and any parameters you were passed in such as the continue URL.
When you receive a request to service.example.com/finish_auth, compute the HMAC as above, and check it matches the passed in one. If it does, you know the request is a legitimate one. Set an authentication cookie on service.example.com containing any relevant details, and redirect the user back to their original URL.
This sounds complicated, but it's fairly straightforward in implementation. This is a standard way to 'pass' credentials between mutually trusting systems, and it's not unlike what a lot of SSO systems use.

Pre-validating website users via a remote site

I need to work out a way to setup the validation of the users of a web application before they've actually arrived at the site. That is, someone browses to a url, enters a username and password which is then validated against a db or whatever. They are then automatically redirected to the real web application, on a different domain out across the internet, which is passed the details of the user and which then lets them through to the site without asking for the credentials again. And this must be done as securely as possible.
What are the options available for this sort of problem?
Thanks,
What you are describing is a typical use case of intern-domain web authentication. There are multiple ways to do it,
If both domains belong to the same application/company, you can just do your authentication and then pass some token/secret to the other domain in your redirect. The other domain can drop another cookie to maintain the session. This is practically how it's done between different domains all popular websites. For example, flickr.com uses yahoo.com to login.
You can use Identity Federation if the domains are closely related (partners). Most popular mechanism to achieve this is through SAML.
OpenID can also be used (That's how you arrived at this site) if the sites are loosely connected. OpenID uses arcane login URL so it only makes sense for tech-savvy users. The regular user may easily get confused by its complicated login process and consent page.
OAuth is an authorization scheme. It's not designed for federated login but you might be able to use it.
Look up OAuth or OpenID.

Resources