How can I configure Azure Application Gateway to only accept client certificates with a specific subject - azure-application-gateway

I have configured mutual authentication on an Azure Application Gateway. Currently all client certificates issued by the intermediate CA (as configured on SSL profile) are accepted, but I only want a specific certificate to be granted access, ideally based on the subject of the client certificate. Making changes to the CA that issues the client certificate is not feasible in my case.
Options explored:
Use leaf certificate when configuring SSL profile: app gateway seems to ignore the leaf certificate; all client certificates issued by the intermediate CA are accepted.
Configure a rewrite rule action to pass a server variable (e.g. client_certificate_subject) to backend in a custom request header. This would require changing the backend to interpret the request header, which I’m trying to avoid.
Configure a rewrite rule condition to check server variable (e.g. client_certificate_subject) and conditionally take some action. Ideally the action should set the HTTP response code (without forwarding the request to backend) or rewrite to an error page generated by the app gateway (e.g. HTTP 401 unauthorized / 403 forbidden). Can this be done somehow?
WAF rules don’t seem like a viable option as they don’t have access to server variables
Hoping to find a way of configuring this requirement on the app gateway. Thanks.

I understand that you want to be able to allow specific certificates only based on their subject names etc., to be granted access by the Application Gateway.
You can't use a rewrite rule because in order to "get to" a rule in the first place you have to get through the listener and you can't get through the listener if you can't authenticate with mutual authentication.
At this point, the best way to avoid people from accessing App GW would be to not give the Leaf certificate so they cannot access the same.
Also please note that Application Gateway Mutual Authentication is in preview right now and therefore, it is intended for "Evaluation" and testing, and not production currently. Once it is GA, there will be options to have revocation lists and checks.
Hope this helps. Please do let us know if you have further questions. Thank you!

Related

In application gateway "Backend certificate is invalid", Do really require by app gateway to monitored the validity of backend server certificate?

In application gateway "Backend certificate is invalid", Do really require by app gateway to monitored the validity of backend server certificate?
As because we have seen due to this human error can be encounter, whereas application owner and Azure administrator should be aware of the working flow of the application. But although the certificate is invalid to-and-fro communication would be secure, hence its worthless of mentioning "HTTPS connection won't be secure unless the server's TLS/SSL certificate is valid" in Azure portal.
However now a days every organization looking for cost saving, whereas Administrators are working in shared model and if any production application missed to update certificate in-between, can cause the business loss.
Rather MS has to introduce server certificate profile in http setting, which accepts the default certificate no matter valid or invalid and monitoring only the secure connection for end-to-end encryption.
https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-backend-health-troubleshooting
Currently, for the TLS connection to work in Application gateway, you need to ensure that the TLS/SSL certificate meets the following conditions:
That the current date and time is within the "Valid from" and "Valid
to" date range on the certificate.
That the certificate's "Common Name" (CN) matches the host header in the request. For example, if the client is making a request to https://www.contoso.com/, then the CN must be www.contoso.com.
Refer : https://learn.microsoft.com/en-us/azure/application-gateway/ssl-overview
If the Trusted Root Certificate uploaded is expired or backend server certificate’s Common Name (CN) does not match with the Hostname entered in HTTP Settings, the probe (default or custom) will start marking the backend servers as Unhealthy so that the requests won’t be routed to them.
There is no other way available to get this working at the moment. If you wish you may leave your feedback in the below forum requesting the desired feature. All the feedback you share in these forums will be monitored and reviewed by the Microsoft engineering teams responsible for building Azure.
https://feedback.azure.com/d365community/forum/8ae9bf04-8326-ec11-b6e6-000d3a4f0789

How to validate new SAML certificate

I'm working on an app that acts as a SAML service provider. It's written in Rails and uses the omniauth-saml and ruby-saml gems.
Our certificate is about to expire, and we need to create a new one. I'm tasked with verifying that the new one is working. However, none of the IdPs that I've tested with seem to care which certificate I use. When I set them up with the old cert and then switch our app to using the new one they all allow SP-initiated login as if nothing changed.
The app needs to work with all IdPs, and I think that some of them do validate assertion signatures. I need to find an IdP that fails to accept an SP-initiated login assertion when the signature does not match the one that was set up. I've tried Okta, Jumpcloud, and Ping without any luck.
One question is: why don't these IdPs care about the signature for SP-initiated login. But the main question is: how do I find one that does care so that I can test the new cert?
Thanks!
There are two places where your SP's certificate is used: (1) the SP can digitally sign its authentication request to the IdP, and (2) the IdP can encrypt parts of its response with your SP's public key.
For situation (1), if your SP is signing its requests with the new certificate but the IdP responds as before, it could very well be that the IdP is simply ignoring the signature. The IdP might have to be configured to expect and require signed requests before it will fail on an unknown certificate. But note that it is up to the IdP whether it will verify signed requests; for example, according to this post Okta does not verify the signature of signed authentication requests.
For situation (2) use Firefox's SAML tracer or something similar to verify that part of the response from the IdP is encrypted. If not, that would explain why switching to a new certificate that the IdP does not know about continues to work.
It may also be that your SP needs only to know that the person authenticated successfully against the IdP and nothing else, in which case, your SP's certificate is superfluous.
In particular, the Shibboleth IdP can be configured to send back encrypted assertions.
For me, by far the easiest to use and configure IdP or SP test connectors can be found here: https://support.onelogin.com/hc/en-us/articles/202673944-How-to-Use-the-OneLogin-SAML-Test-Connector
There is a list of test connectors that will help you to test different kinds of connections.

How to protect JSON API from being accessed by anyone but my iOS client?

I have an iPhone app that uses a Rails server HTTP API. The API is public at this point - no authorisation is required to get the data.
Currently anyone can go to API's URL and download the data.
http://server.com/mydata
The data is not very sensitive. But I still want to prevent people from easily getting it. What are the ways of doing that? I do not want iOS app users to log in either.
Current solution I have
iPhone app adds a secret token to the HTTP header or query of the request. The data goes over HTTPS.
https://server.com/mydata?secret=my_secret
Is there a better approach?
You could try an approach where the client is only allowed X number of requests per time period (based on IP address or username)
HTTPS is extremely easy to man in the middle on a device you control. You can do SSL cert validation, but there is always someone out there with more time, so best off to handle it server side.
Distribute and use your own SSL certificate.
Apps that transfer sensitive customer data, like credit card and payment information, must be protected from man-in-the middle attacks. The best protection is a mutual authentication scheme, where certificates are exchanged to make sure the app is connected to a trusted server and to make sure the server is connected to a trusted app.
Then only individuals (who have presumably installed your application) have access. If someone digs through the code and gets the public certificate then they can impersonate the client; but at that point they win anyway and two-factor authentication should be explored.

How can a client app using HTTPS be tested for protection against a MITMA?

I have an iOS client app which connects to a server using HTTPS.
I've added code in the client to verify the identify of the server.
How can a tester testing this feature test that it is now secure, how can they for example create a MITM situation and check that the client rejects connects etc.?
I've tried googling for how to do this but haven't had much luck.
Can it be done using tools like Charles and proxies etc. or is messing around with a wireless router and having detailed knowledge necessary?
This might be over simplification for your solution, but concepts might help.
A web browsers extracts the name of hosts from embedded certificate and do a comparison of host name that we're trying to connect with. If validation fails, we usually see a security warning. For ex: we can connect with facebook by either typing https://www.facebook.com or by typing https://173.252.100.16/. When we choose second option, we get a security warning.
Your program must be using SSL client socket to connect with HTTPS server. The socket must be having capability to extract the hostname from the embedded certificate. Once you get that, compare that with valid HOST NAME that your program is trying to connect with. If it matches, let request proceed, If not, abandon that session.
To re-create MITM, your web server can use a self signed certificate that can be issue to whatever host name you want, but the IP of server could be 127.0.0.1 (for example). Since there is a mismatch between the host name and actual IP, we can probably simulate the MITM situation.
I'm assuming that digital certificate can't be forged in this case.

Custom domains in a Rails App

I want users of my service to be able to add their own custom domains. For example, www.[their domain].com should be able to access their application's index and show pages. My service is implemented in Rails 3.
I've seen apps like Tumblr offer this functionality for their front facing blogs. Although I have seen apps for Rails that implement sub domains in the way that Basecamp does, I have not found a resource for fully custom domains.
They'll need to create an A record in their DNS to point to your app servers IP. You'll need to know what domain they have pointed to your server and log it against their account, and also set your web servers config in such a way as to channel the requests from other domains to your app. You can then use the request object to look up their account in your application_controller.
I just answered a similar question so I decided to chime in here too.
#Codebeef gave a good answer but this won't work anymore in the world where HTTPS is a must in most modern browsers.
This is the full picture of how to handle custom domains for your app.
If your customers just CNAME to your domain or create the A record to your IP and you don't handle TLS termination for these custom domains, your app will not support HTTPS, and without it, your app won't work in modern browsers on these custom domains.
You need to set up a TLS termination reverse proxy in front of your webserver. This proxy can be run on a separate machine but you can run it on the same machine as the webserver.
CNAME vs A record
If your customers want to have your app on their subdomain, e.g. app.customer.com they can create a CNAME app.customer.com pointing to your proxy.
If they want to have your app on their root domain, e.g. customer.com then they'll have to create an A record on customer.com pointing to your proxy's IP. Make sure this IP doesn't change, ever!
How to handle TLS termination?
To make TLS termination work, you'll have to issue TLS certificates for these custom domains. You can use Let's Encrypt for that. Your proxy will see the Host header of the incoming request, e.g. app.customer1.com or customer2.com etc., and then it will decide which TLS certificate to use by checking the SNI.
The proxy can be set up to automatically issue and renew certificates for these custom domains. On the first request from a new custom domain, the proxy will see it doesn't have the appropriate certificate. It will ask Let's Encrypt for a new certificate. Let's Encrypt will first issue a challenge to see if you manage the domain, and since the customer already created a CNAME or A record pointing to your proxy, that tells Let's Encrypt you indeed manage the domain, and it will let you issue a certificate for it.
To issue and renew certificates automatically, I'd recommend using Caddyserver, greenlock.js, OpenResty (Nginx).
tl;dr on what happens here;
Caddyserver listens on 443 and 80, it receives requests, issues, and renews certificates automatically, proxies traffic to your backend.
How to handle it on my backend
Your proxy is terminating TLS and proxying requests to your backend. However, your backend doesn't know who is the original customer behind the request. This is why you need to tell your proxy to include additional headers in proxied requests to identify the customer. Just add X-Serve-For: app.customer.com or X-Serve-For: customer2.com or whatever the Host header is of the original request.
Now when you receive the proxied request on the backend, you can read this custom header and you know who is the customer behind the request. You can implement your logic based on that, show data belonging to this customer, etc.
More
Put a load balancer in front of your fleet of proxies for higher availability. You'll also have to use distributed storage for certificates and Let's Encrypt challenges. Use AWS ECS or EBS for automated recovery if something fails, otherwise, you may be waking up in the middle of the night restarting machines, or your proxy manually.
If you need more detail you can DM me on Twitter #dragocrnjac

Resources