REST service through SSL and HTTP Basic Authentication - security

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

Related

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
:-)

Will Integrated Windows Authentication ever fall back to plain text username & password?

I'm trying to learn more about Integrated Windows Authentication but everything I read introduces me to three new acronyms, many of which incorporate other acronyms, and I don't feel I know anything about the mechanics.
I understand that if an HTTP client doesn't support Integrated Windows Authentication there is a chain of fallbacks that can identify the client and might involve prompting for a username and password. Is there ever a case where it will fallback to HTTP Basic Authentication or any other plain text username / password communication?
I'm trying to determine if I need to provide SSL to protect user credentials and I'm hoping that all authentication is secured in some way.
There is no plain-text credential for the SSPs available to IWA in a default installation (NTLM and Kerberos). In principle you could deploy some other SSP and make it available to IWA via NegoEx, and that SSP might implement password checking in the clear, but that's pretty unlikely.
Of course there is nothing stopping a web application from returning a response requesting HTTP Basic Authentication or Forms Authentication, independently of IWA, so you would have to check no applications were doing that.
I'm trying to determine if I need to provide SSL to protect user credentials and I'm hoping that all authentication is secured in some way.
If you're only interested in complying with a corporate policy against cleartext passwords, then IWA should be enough.
If you have a real threat model and it includes a snooper on the network, then you have much more to worry about - such an attacker can just as easily do active man-in-the-middle attacks and make the web application appear to do something like create a bogus NTLM login box that leaks passwords. That's why you might want SSL.

server-to-server REST API security

We're building a REST API that will only be accessed from a known set of servers. My question is, if there is no access directly from any browser based clients, what security mechanisms are required.
Currently Have:
Obviously over HTTPS
Have HTTP auth enabled, API consumers have a Key & password
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed for the request and validated at the endpoint?
Use OAuth (2-legged authentication)?
Doesn't matter - from browser or not.
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed
for the request and validated at the endpoint?
Use oauth (2-legged authorization)?
Use OAuth, it solves both these questions. And OAuth usage is good because:
You aren't reinventing wheel
There are already a lot of libraries and approaches depending on technology stack
You can also use JWT token to pass some security context with custom claims from service to service.
Also as reference you can look how different providers solve the problem. For example Azure Active Directory has on behalf flow for this purpose
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow
Use of OAuth2/OpenID Connect is not mandatory between your services, there are other protocols and alternatives and even custom. All depends in which relationships are services and either they both are in full trust environment.
You can use anything you like but main idea not to share sensitive information between services like service account credentials or user credentials.
If REST API security is main requirement - OAuth2/OpenID Connect is maybe the best choice, if you need just secure (in a sense of authentication) calls in full trust environment in a simplest way - Kerberos, if you need encrypted custom tunnel between them for data in transit encryption - other options like VPN. It does not make sense to implement somthing custom because if you have Service A and Service B, and would like to make sure call between them is authenticated, then to avoid coupling and sharing senstive information you will always need some central service C as Identity provider. So if you think from tis pov, OAuth2/OIDC is not overkill
Whether the consumers of your API are web browsers or servers you don't control doesn't change the security picture.
If you are using HTTPs and clients already have a key/password then it isn't clear what kind of attack any other mechanism would protect against.
Any compromise on the client side will expose everything anyway.
Firstly - it matters whether a user agent (such as a browser) is involved in call.
If there are only S2S calls then 1 way SSL HTTPS (for network encryption) and some kind of signature mechanism (SHA-256) should be enough for your security.
However if you return sensitive information in your api response, its always better to accept 2 way ssl HTTPS connections (in order to validate the client).
OAuth2 doesn't add any value in a server to server call (that takes place without user consent and without any user agent present).
For authentication between servers:
Authentication
Known servers:
use TLS with X.509 client certificates (TLS with mutual authentication).
issue the client certificates with a common CA (certificate authority). That way, the servers need only have the CA certificate or public key in the truststore, and new client certificates for additional clients/servers can be issued without having to update the truststores.
Open set of servers:
use API keys, issued by a central authority. The servers need to validate these keys on each request (and may cache the hashes of the keys along with the validation result for some short time).
Identity propagation
if the requests are executed in the context of a non-technical user, use JWT (or SAML) for identity propagation of the user principal and claims (authorize at security proxy/WAF/IAM, and issue JWT signed by authentication server).
otherwise the user principal refers to the technical user and can can be extracted from the client certificate (X.509 DName) or be returned with a successful authentication response (API key case).

Does https make this any more secure?

I'm reading the API for a web service, and all methods involve sending an HTTP request to
https://example.com/api/APIVER/METHOD?apikey=APIKEY&user=USERNAME&password=PASSWORD
To be clear, both the API key and user password are sent in plain text via the URL. But is this OK because "all HTTPS traffic is encrypted" or not because they're still in plain text or because the URL is somehow different?
If this isn't secure, what is the minimum change the API maintainer needs to do?
Yes, HTTPS makes this more secure.
HTTPS makes this more secure.
You should also send sensitive parameters as POST parameters instead (HTTP BODY) of GET query string ones. Typically the query string will be logged by Web server logs (server side) in plaintext, so it will be accessible to system administrators that perhaps shouldn't be able to see it.
HTTPS will encode the URL in each request, so if you are worried about network sniffing then you're OK. HTTPS also adds a nonce value, so you aren't exposed to reply attacks.
It would be possible, depending on infrastructure to insert a fake SSL certificate that's trusted by the user device and route requests through a proxy using that certificate. However this would require admin/root access to the client machines to make such a certificate trusted (barring breach of a normally trusted CA), and once something needs admin access all bets are off anyway.
It's still not a wonderful idea though, I'd be concerned about developers forgetting to configure it for HTTPS. You have an API key, so why not take the password and hash it using the APIKEY as the salt. Now for the API calls the salt is a password equivalent but it would mean that the username and password couldn't be used for logging into elsewhere with those credentials, for example the web site that the API is running off (assuming you let users log in there of course.)
Even better would be to use a shared secret that doesn't go over the wire at all, and use that as the salt.

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.

Resources