How to enforce only Https only request to identityserver4 - identityserver4

I have IdentityServer4 configured and deployed on Azure App Service, I have used the custom SSL certificate to sign tokens. Everything is working fine, however I want to enforce identity server to receive request from https clients only and throw error otherwise.
I read this part of the documentation on identityserver4(http://docs.identityserver.io/en/latest/topics/crypto.html?highlight=HTTPS) where they say:
"We don’t enforce the use of HTTPS, but for production it is mandatory for every interaction with IdentityServer."
Just was wondering is it possible to enforce only https client request.
Any help or pointers is greatly appreciated

That'd typically something you'd configure at web server/traffic manager level rather then at application level (although you can ofcourse have application logic to enforce it too).
This should be of use: https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-ssl
Also check out the HSTS header: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet
And also consider the use of a robust Content Security Policy that blocks or upgrades insecure resource requests. e.g. Content-Security-Policy: upgrade-insecure-requests; block-all-mixed-content; Check out https://report-uri.com/home/generate and https://scotthelme.co.uk/csp-cheat-sheet/

You can enforce the HSTS header and HTTPS redirection with the following calls in the Configure method in the Startup class.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseHsts();
app.UseHttpsRedirection();
//...
}
For all the configuration options and best practices refer to this link:
https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

Related

Kubernetes and AAD authentication

On configured AKS there is docker container with application that is using AAD authentication.
Based on this article there is also configured ingress. API is working well.
When I add to Azure Active Directory application registration reply URL with https prefix I receive error "The reply url specified in the request does not match the reply urls configured for the application". And I see that in browser address line redirect_uri is starting with http.
When I add reply URL that is starting with http, then I receive "Exception: Correlation failed".
What I have tried: Add to ingress.yaml setting ingress.kubernetes.io/force-ssl-redirect: "true"
May be there is some way to force ingress run https instead of http, or there might be some AAD redirect configuration? Any ideas?
UPDATE 2: Probably http redirect is because of ADAL.
PS: Was able to find similar topic without an answer
UPDATE3:
I have decided not to use nginx as ingress. Instead I am using now Load balancer. Soon it would be possible to use Azure Application Gateway Ingress Controller
Have you tried this?
By default the controller redirects HTTP clients to the HTTPS port 443 using a 308 Permanent Redirect response if TLS is enabled for that Ingress.
This can be disabled globally using ssl-redirect: "false" in the NGINX config map, or per-Ingress with the nginx.ingress.kubernetes.io/ssl-redirect: "false" annotation in the particular resource.
More information on this on the Ingress documentation link.
You have to make a decision whether to use HTTPS or not. If this is just the start of a development cycle, start without it and get auth to work - but implement HTTPS as soon as possible.
AAD supports both http and https, but of course, the reply urls must be added to the application registration respectively.
As #mihail-stancescu says, ssl-redirect must be set to false, if you choose not to use HTTPS. In addition to this, you also have to ensure that your app does not make the redirect from HTTP to HTTPS.
Using curl with -L -k and -v options will give you a lot of information on what is actually happening with your requests.
When the http/https thing is solved, you have to remove any rewrite annotations you have in your ingress. (e.g. ingress.kubernetes.io/rewrite-target: / should be removed).
Now, if your ingress path to the service in question is e.g. /myservice, then the reply-url should also have that part of the path added ([host]/myservice/signin-oidc) - both in the AAD application registration and in the configuration of your app. (The path in the config should not contain the host)
If you are using https, then you must also have a proper certificate. You can use the free LetsEncrypt (https://letsencrypt.org/) in conjunction with KubeLego (https://github.com/jetstack/kube-lego), where you can find some nice examples on how to implement it.

How to handle CORS preflight requests in a SiteMinder protected environment?

I'm building an AngularJS application that will interact with RESTful services running on a different host. Since requests are going across origins, CORS is getting into the picture. Since requests specify JSON as expected content type, CORS preflight requests are triggered by the browser. Straightforward so far.
According to W3 spec, CORS preflight requests should exclude user credentials. The RESTful web services application is protected by SiteMinder, which is configured to enforce authentication based on URL. Web services depend on SiteMinder for authentication and handle authorization only. That's why SiteMinder cannot be removed. As a result, CORS preflight requests come back with HTTP 401 Authorization Required. It prevents browser from moving forward with the actual request.
Any ideas about how to enable CORS preflight requests in a SiteMinder protected environment? Thanks a lot in advance!
You can try to ignore OPTIONS method by setting autoauthorizeoptions = yes in ACO parameters for the agent
++++++++++++++++++++++++++++
Allow Automatic Access to Resources that use the OPTIONS Method The SiteMinder Web Agent still challenges authenticated users who attempt to access resources that use the OPTIONS method. Some examples of resources that use the OPTIONS method include (but are not necessarily limited to) the following:
Microsoft® Word documents
Microsoft® Excel® spreadsheet documents This challenge occurs because the application associated with the resource sends a request using the OPTIONS method to the web server. Because this request does not include a SiteMinder cookie, the Web Agent issues a challenge.
To prevent users from being challenged for these resources
Set the value of the following parameter to yes:
autoauthorizeoptions
Automatically authorizes any requests for resources which use the HTTP OPTIONS method.
If you set the value of this parameter to yes, also set the value of the PersistentCookies parameter to no.
Limits: yes, no
Set the value of the PersistentCookies parameter to no.
++++++++++++++++++++++++

How to store an auth token in an Angular app

I have an Angular application (SPA) that communicates with a REST API server and I'm interested in finding out the best method to store an access token that is returned from an API server so that the Angular client can use it to authenticate future requests to the API. For security reasons, I would like to store it as a browser session variable so that the token is not persisted after the browser is closed.
I'm implementing a slightly customized version of OAuth 2.0 using the Resource Owner Password grant. The Angular application provides a form for the user to enter their username and password. These credentials are then sent to the API in exchange for an access token which must then be sent as a header (Authorization: Bearer %Token%) for all outbound requests to the API so that it can authorize requests to other routes.
I'm fairly new to the realm of Angular, but the workflow I would like to implement as far as handling these tokens is summarized as follows.
1) The client makes a request to the API providing it with user credentials.
2) If this request is successful, the token is stored somewhere (where is the question)
3) Intercept HTTP requests. If token is set, pass it along as a header to API
4) Token is destroyed when the browser/tab is closed.
I know Angular offers $window.sessionStorage, which appears to be what I am looking for, but I am concerned by the potential for it not to work on all browsers according to various resources I've read. This is an enterprise grade application and must be compatible across a broad range of browsers (IE, Chrome, Firefox). Can I safely use this with the confidence that it will be stable?
The alternatives, from what I understand, are either $window.localStorage or cookies ($cookies, $cookieStore). This would not be an ideal solution for me since I don't want this data to persist, but if this is more reliable I'll have to sacrifice efficiency for compatibility. I was also thinking it might be possible to simply set it as a value on the $rootScope and reference it this way, but I'm not sure if this is feasible.
I hope that all made sense. Any help / suggestions would be greatly appreciated.
Thanks!
If you are looking for something that will definitely not persist then I would simply keep the token in memory and not rely on the browser for storage. However storing inside rootScope would not be best practice.
I would recommend that you wrap your server access code in an Angular Service if you have not done so already. You can then encapsulate your token within that Service at runtime (e.g. as a property) without worrying about having to access it when calling from other parts of your application.
Angular Services are singleton so your "server service" will be a global instance that can be accessed using normal dependency injection.
$window.sessionStorage is the way to go unless you're targeting very old browsers.
According to www.w3schools.com sessionStorage is supported from IE 8.0, Chrome 4.0, Firefox 3.5, and Safari 4.0.

Prevent CSRF (or Cross-Site Request Forgery/XSRF) for silverlight enabled WCF Service

The silverlight enabled WCF Service communication is secured using a USB token/smartcard. The first access has to be confirmed by entering a PIN. Once authenticated, a malicious website could start CSRF requests to the WCF service using IMG-Tags and/or JavaScript. According to the Security Guidance for Writing and
Deploying Silverlight Applications, a usual technique here is to use (session-)tokens or a so called "nonce", while checking the HTTP Referrer header has proven to be insecure.
I understand the idea behind this, to my understanding it works well if you have a single form (i.e. contact form) and a single service where you can ensure that a user has to see and fill out the form before sending. In a Silverlight application, I'm not able to predefine such kind of sequence, many requests (like requesting a price update for a product) can be started in an arbitrary order.
Do you have some advices how I should secure the Silverlight to WCF communication to prevent CSRF attacks, ensuring that an already authenticated caller requests from a trusted site?
One option could be:
Provide a service that when called, created a nonce and stores it on the users session on the server, and returns it to the calling application
On every request after this one, include the nonce as a URL parameter or in the POSTed body of the request (or within any other type of message you use)
Check for this nonce for every request to the server
An attacker could not trick this, because if he called the mentioned service he would get a different token for their own session. And as long as this nonce is not stored in a cookie, it will not be automatically submitted by the browser upon requests to the server. So as long as the attacker cannot guess the nonce (use a cryptographically secure random to generate it), this should work.

URL fetch service - is https secure or not?

I'd like to use the URL fetch service for app engine (java). I'm just sending a POST to one of my own servers from a servlet.
AppEngine -> post-to: https://www.myotherserver.com/scripts/log.php
I'm reading the url fetch doc:
Secure Connections and HTTPS
An app can fetch a URL with the HTTPS method to connect to secure servers. Request and response data are transmitted over the network in encrypted form.
The proxy the URL Fetch service uses cannot authenticate the host it is contacting. Because there is no certificate trust chain, the proxy accepts all certificates, including self-signed certificates. The proxy server cannot detect "man in the middle" attacks between App Engine and the remote host when using HTTPS.
I don't understand - the first paragraph makesit sound like everything that goes from the servlet on app engine, to my php script is going to be secure if I use https. The second paragraph makes it sound like the opposite, that it won't actually be secure. Which is it?
Thanks
There are two things HTTPS does for you. One is to encrypt your data so that as it travels over the internet, through various routers and switches, no one can peek at it. The second thing HTTPS does is authenticate that you are actually talking to a certain server. This is the part App Engine can't do. If you were trying to connect to www.myotherserver.com, it is possible that some bad guy named bob could intercept your connection, and pretend to be www.myotherserver.com. Everything you sent to bob would be encrypted on it's way to bob, but bob himself would be able to get the unencrypted data.
In your case, it sounds like you control both the sending server and the destination server, so you could encrypt your data with a shared secret to protect against this possibility.
The UrlFetch through https has been fixed allowing certificate server validation.
validate_certificate
A value of True instructs the application to send a request to the
server only if the certificate is
valid and signed by a trusted CA, and
also includes a hostname that matches
the certificate. A value of False
instructs the application to perform
no certificate validation. A value of
None defaults to the underlying
implementation of URL Fetch. The
underlying implementation currently
defaults to False, but will default to
True in the near future.

Resources