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

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

Related

Is Public Key encryption acceptable for protecting last leg of this OpenId Connect workflow

Desktop Client
Protected Resource Server
Authorization Server (Google)
User-Agent (Browser)
The Desktop Client generates Pub/Priv key pair, and directs the user agent with webbrowser.open_new() to Protected Resource Server OAuth initiation page, which stores the Public Key in the State parameter field of the Auth_URI redirect.
User-Agent successfully auths with the Authorization Server and is redirected back to Protected Resource Sever with Auth_Code and Public Key in state parameter field.
Protected Resource Server exchanges Auth_Code using confidential client secret and validates id_token.
If id_token is valid, (server side processing happens), it then redirects on loopback to listening Desktop Client with query parameter containing an encrypted value that is only accessible by the initiating app.
It's a very similar process to PKCE, but I'm having the Client Secret remain confidential on the sever rather than embedding it in the Desktop Client.
My concern is about a malicious 3rd party app that is able to intercept the initial OAuth_URI redirect and modify its values. Is this a mitigable threat once the device/browser is compromised? PKCE would suffer from the same issue and I've seen no explanations that mention my concern as a particular issue so I am under the assumption it is fine.
REDIRECT TAMPERING
The standard protection against malicious redirect tampering is in these emerging standards:
PAR
JAR
JARM
In high security scenarios you may need to follow profiles that mandate some of these - and some profiles may include financial-grade recommendations such as FAPI 2.0 Client Requirements, which includes PAR.
DESKTOP APPS
One known issue for desktop apps is that a malicious app could send the same client ID and use the same redirect URI to trigger a complete flow. I don't think you can fully protect against that, and any efforts may just be obfuscation.
Your concern is perhaps this issue, and it is not currently solvable, since any code your app runs could also be run by a malicious app, including use of PAR / DPop or other advanced options.
CLIENT ATTESTATION
The behaviour you are after is client attestation, where a malicious party cannot attempt authentication without proving its identity cryptographically. Eg an iOS app can send proof of ownership of its App Store signing key.
Mobile and web apps can achieve a reasonable amount of client attestation by owning the domain for an HTTPS based redirect URI, but these cannot be used for desktop apps. It would be good to see improved client attestation options for desktop apps some time soon.
WHAT TO DO?
Generally I would say keep your code based on standards that have been vetted by experts. This should mean that you use libraries in places but that your code remains simple.
Also your desktop app will be as secure as other desktop apps without trying to solve this problem. Also, users are socialised to not run arbitrary EXEs these days, and only run proper signed apps, whose code signing certificate identifies them and chains up to an authority that has approved the app (we hope).

Are Oauth2 client apps required to have SSL connection?

Which parties of Oauth 2.0 are required to have an SSL connection?
Auth server: SSL required
Resource server: SSL required
Client apps: Is it really necessary, as long as it uses SSL for the resource server communication?
The Authorization server is required to use SSL/TLS as per the specification, for example:
Since requests to the authorization endpoint result in user
authentication and the transmission of clear-text credentials (in the
HTTP response), the authorization server MUST require the use of TLS
as described in Section 1.6 when sending requests to the
authorization endpoint.
Since requests to the token endpoint result in the transmission of
clear-text credentials (in the HTTP request and response), the
authorization server MUST require the use of TLS as described in
Section 1.6 when sending requests to the token endpoint.
That same specification does not require it for the client application, but heavily recommends it:
The redirection endpoint SHOULD require the use of TLS as described
in Section 1.6 when the requested response type is "code" or "token",
or when the redirection request will result in the transmission of
sensitive credentials over an open network. This specification does
not mandate the use of TLS because at the time of this writing,
requiring clients to deploy TLS is a significant hurdle for many
client developers. If TLS is not available, the authorization server
SHOULD warn the resource owner about the insecure endpoint prior to
redirection (e.g., display a message during the authorization
request).
Lack of transport-layer security can have a severe impact on the
security of the client and the protected resources it is authorized
to access. The use of transport-layer security is particularly
critical when the authorization process is used as a form of
delegated end-user authentication by the client (e.g., third-party
sign-in service).
Calls to the resource server contain the access token and require SSL/TLS:
Access token credentials (as well as any confidential access token
attributes) MUST be kept confidential in transit and storage, and
only shared among the authorization server, the resource servers the
access token is valid for, and the client to whom the access token is
issued. Access token credentials MUST only be transmitted using TLS
as described in Section 1.6 with server authentication as defined by
[RFC2818].
The reasons should be pretty obvious: In any of these does not use secure transport, the token can be intercepted and the solution is not secure.
You question specifically calls out the client application.
Client apps: Is it really necessary, as long as it uses SSL for the resource server communication?
I am assuming that you client is a web application, and you are talking about the communication between the browser and the server after authentication has happened. I am furthermore assuming that you ask the question, because (in your implementation), this communication is not authenticated with access tokens, but through some other means.
And there you have your answer: that communication is authenticated in some way or another. How else would the server know who is making the call? Most web sites use a session cookie they set at the beginning of the session, and use that to identify the session and therefor the user. Anyone who can grab that session cookie can hijack the session and impersonate the user. If you don't want that (and you really should not want that), you must use SSL/TLS to secure the communication between the browser and the server.
In some cases, the browser part of the client talks to the resource server directly; and the server part only serves static content, such as HTML, CSS, images and last but not least, JavaScript. Maybe your client is built like this, and you are wondering whether the static content must be downloaded over SSL/TLS? Well, if it isn't, a man in the middle can insert their own evil JavaScript, that steals you user's access tokens. You do want to secure the download of static content.
Last but not least, your question is based on a hidden assumption, that there might be valid reasons not to use SSL/TLS. Often people claim the cost of the certificate is too high, or the encryption requires too much CPU power, hence requiring more hardware to run the application. I do not believe these costs to be significant in virtually all cases. They are very low, compared to the total cost of building and running the solution. They are also very low compared to the risks of not using encryption. Don't spend time (and money) debating this, just use SSL/TLS all the way through.

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

How to design API with no SSL support?

I am developing Restful API layer my app. The app would be used in premises where HTTPS support is not available. We need to support both web apps and mobile apps. We are using Node/Expressjs at the server side. My two concerns are:
Is there a way we could setup secure authentication without HTTPS?
Is there a way we could reuse the same authentication layer on both web app (backbonejs) and native mobile app (iOS)?
I think you are confusing authenticity and confidentiality. It's totally possible to create an API that securely validates the caller is who they say they are using a MAC; most often an HMAC. The assumption, though, is that you've securely established a shared secret—which you could do in person, but that's pretty inconvenient.
Amazon S3 is an example of an API that authenticates its requests without SSL/TLS. It does so by dictating a specific way in which the caller creates an HMAC based on the parts of the HTTP request. It then verifies that the requester is actually a person allowed to ask for that object. Amazon relies on SSL to initially establish your shared secret at registration time, but SSL is not needed to correctly perform an API call that can be securely authenticated as originating from an authorized individual—that can be plain old HTTP.
Now the downside to that approach is that all data passing in both directions is visible to anyone. While the authorization data sent will not allow an attacker to impersonate a valid user, the attacker can see anything that you transmit—thus the need for confidentiality in many cases.
One use case for publicly transmitted API responses with S3 includes websites whose code is hosted on one server, while its images and such are hosted in S3. Websites often use S3's Query String Authentication to allow browsers to request the images directly from S3 for a small window of time, while also ensuring that the website code is the only one that can authorize a browser to retrieve that image (and thus charge the owner for bandwidth).
Another example of an API authentication mechanism that allows the use of non-SSL requests is OAuth. It's obsolete 1.0 family used it exclusively (even if you used SSL), and OAuth 2.0 specification defines several access token types, including the OAuth2 HTTP MAC type whose main purpose is to simplify and improve HTTP authentication for services that are unwilling or unable to employ TLS for every request (though it does require SSL for initially establishing the secret). While the OAuth2 Bearer type requires SSL, and keeps things simpler (no normalization; the bane of all developers using all request signing APIs without well established & tested libraries).
To sum it up, if all you care about is securely establishing the authenticity of a request, that's possible. If you care about confidentiality during the transport of the response, you'll need some kind of transport security, and TLS is easier to get right in your app code (though other options may be feasible).
Is there a way we could setup secure authentication without HTTPS?
If you mean SSL, No. Whatever you send through your browser to the web server will be unencrypted, so third parties can listen. HTTPS is not authentication, its encyrption of the traffic between the client and server.
Is there a way we could reuse the same authentication layer on both web app (backbonejs) and native mobile app (iOS)?
Yes, as you say, it is layer, so it's interface will be independent from client, it will be HTTP and if the web-app is on same-origin with that layer, there will be no problem. (e.g. api.myapp.com accessed from myapp.com). Your native mobile can make HTTP requests, too.
In either case of SSL or not SSL, you can be secure if you use a private/public key scenario where you require the user to sign each request prior to sending. Once you receive the request, you then decrypt it with their private key (not sent over the wire) and match what was signed and what operation the user was requesting and make sure those two match. You base this on a timestamp of UTC and this also requires that all servers using this model be very accurate in their clock settings.
Amazon Web Services in particular uses this security method and it is secure enough to use without SSL although they do not recommend it.
I would seriously invest some small change to support SSL as it gives you more credibility in doing so. I personally would not think you to be a credible organization without one.

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

Resources