using https sparingly in my GAEJ app - google-app-engine

I have a GAEJ application that until now hasn't had to deal with sensitive data. For that reason it's been happily running under http://
I am using GWT-RPC for my client server calls.
However I now want to start storing customer names and addresses, for which I'd like to start using https.
I understand the limitation that it has to use the https://www.xxxxx.appspot.com/ domain.
My question is how can I create a sub-section of my site that only deals with client-senstive data, leaving the rest of my site untouched?
For example if I put the following security constraint in my web.xml :
<security-constraint>
<web-resource-collection>
<url-pattern>/xxxxx/admin/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
how can I then tell the app to use https for only certain RPCs, and not all of them?
In other words, is it possible to leave it so that my users still access my site using http:
http://www.xxxxx.appspot.com/
and when they make an RPC sending or receiving sensitive data that is done over https ?
Should I use RequestBuilder to construct my GWT-RPC to be https? but if I do that how do I get round the Browser Same origin policy ?
Surely there must be a way of doing this, it must be quite a common problem?

The cross-domain policy for AJAX calls will not allow you to do an RPC to https://blah when you've served the page from http://blah
It's possible to overcome this using an iframe or a header like this:
Access-Control-Allow-Origin: https://www.mysite.com
but I don't know if that's possible on GWT.

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 properly enable HTTPS on App Engine flex environment and Go?

I am trying to enable HTTPS on my Go App deployed to GAE flex environment. I have my custom domain successfully mapped, and am using Google-managed SSL certificates. I have app.yaml configured to redirect HTTP to HTTPS as follows:
handlers:
- url: /.*
script: _go_app
secure: always
Now there are two problems that I haven't been able to resolve so far.
First, the above configuration is supposed to redirect HTTP traffic to HTTPS, but apparently it is not happening.
Second, when I add https:// in the url box, I see three different behavior on Firefox, Chrome, and Edge. Edge identifies the website as secure, Firefox marks the website as secure connection, but says that it "has blocked parts of this page that are not secure", and surprisingly Chrome marks the website as Not secure (though it says certificate is valid!).
With these symptoms I was wondering if I should take additional steps to make redirecting and SSL work for my website? Specifically, I would like to know with App Engine, and managed SSL enabled:
Should I continue serving pages on HTTP using http.ListenAndServe(..), or need to switch to http.ListenAndServeTLS(..)?
In my Go app should I redirect HTTP to HTTPS? or the above setting is expected to work just fine?
Thanks in advance for your help and advice.
PS:
Trying out with different suggestions, I added Strict-Transport-Security: max-age=31536000; includeSubDomains to handlers' response. Does not seem if this helped with redirection either.
EDIT/PARTIAL ANSWER:
According to this documentation, under Authentication changes, the secure and login handlers are deprecated. The documentation suggests using Strict-Transport-Security or X-Forwarded-Proto instead.
I am using Strict-Transport-Security on the server side to enrich my response header:
func (h *STLHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
h.nextHandler.ServeHTTP(w, req)
}
I was wondering if I am using this header in the right place?
For the second set of my problems I realized I have mixed content on my page. My mixed content was a http link to a set of fonts. When I fixed the mixed content, i.e. changed http to https, both Chrome and Firefox security warnings disappeared. You may also find this page Avoiding the Not Secure Warning in Chrome useful on this matter.
You need to check your app using:
http://[YOUR_PROJECT_ID].appspot.com
Or if you nedd HTTPS:
https://[YOUR_PROJECT_ID].appspot.com
If you want your own certificate you will need to upload it and then be available to use: https://your-domain.tld
From the docs:
For APIs that will be hosted on App Engine flexible environment, you must use the appspot.com domain, and the service name must be in the following format:
YOUR_PROJECT_ID.appspot.com
When you deploy your API to App Engine, a DNS entry with a name in the format YOUR_PROJECT_ID.appspot.com is created automatically.
For APIs that will be hosted on Compute Engine, Kubernetes Engine, or Kubernetes, you must use the cloud.goog domain, and the service name must be in the following format:
YOUR_API_NAME.endpoints.YOUR_PROJECT_ID.cloud.goog
Or you could just put a CDN in front like Cloudflare which will do all the SSL termination for you and if required redirect all HTTP to HTTPS

Using CORS to restrict who can send a post request

I'm currently trying to configure a route we can call it sub.domain.com/route and on domain.com I have a angular app that sends a post to that end point.
What I'm trying to figure out is do I have to add in CORS to sub.domain.com/route to only allow post requests from domain.com? Or do I have to create a tokening system on domain.comto prevent someone from being able to send curl requests and use that route or to use that route on their website/app without my consent?
I'm trying to limit people who can access that route to only people who are physically on domain.com using my application and clicking the button that sends the post request.
You will need to use some other form of authentication (e.g., tokening, password, etc...) as CORS will only affect whether or not resources such as scripts, served to a user's browser from one domain will be able to interact with services hosted on another. This will do nothing to help against CURL requests, proxies, etc...

App engine subdomain redirects on static files (HTTP 301)

I have a domain (let's say) example.com and I want to serve its content (mainly static files - client side app) from the naked domain. I also want to accept subdomains, so they will not end in error because of DNS or 404. It is common for users to put www in front of the domain (for whatever reason).
I did set up the custom domains in appengine console, the naked and also the * (wildcard). It shows what DNS records I need to have, so I set them up too... exactly the same, A/AAAA records pointing to appengine IPs and * CNAME to appengine alias (googlehosted).
I have read how it behaves by default on https://cloud.google.com/appengine/docs/domain?csw=1 and I would like to change it a bit. Now the page is accessible from all the domains example.com, www.example.com, blog.example.com etc.
What I would like is to redirect all request going to anything else than the naked domain to the naked domain without adding any script handler.
With Apache and modrewrite the solution is easy, as it has a RewriteCond %{HTTP_HOST} and RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]... but is it possible to do this with app.yaml? I couldn't find it at https://cloud.google.com/appengine/docs/python/config/appconfig.
I don't want to redirect in javascript (doesn't work for images, css, etc) and I don't like the idea of script handler for all the files, as it IMHO needs to have some performance penalty.
So, you seem to want to have any subdomains redirect to your naked domain, without needing to write a handler. While you could use a CNAME wildcard on subdomains in your zone file to direct to "#", the naked domain, this is inadvisable since not every provider supports it. You can read more about this strange edge case in an otherwise very standardized system like DNS here.
While you could use a dispatch file (python doc, but other languages have similar) to catch subdomain requests and send them to a special, simplified "3xx redirect to naked domain" module, short of hosting a GCE instance frontend running Apache, you won't be able to change the user's address bar with the CNAME method, although they will be directed to the IP addresses (A/AAAA records) specified at the apex level of your zonefile ("naked domain"), unless you implement such a module. Apache rewrite rules send exactly such HTTP 3xx responses which redirect the browser to change its URL and request the specified URL (in this case, your naked domain).

Is a single Cookie Based API for multiple frontends possible from a CORS perspective?

I originally wrote an REST API to work with a previously written mobile app. The mobile programmer requested from me to generate an auth_token on login that he will pass as a header on each request that needed authentication. This API runs at api.example.com.
Later on, I was commissioned to write an AngularJS app that communicates with this API, so I had to use Access-Control-Allow headers on the backend for OPTIONS requests to be CORS compatible CORS so my browser allows the connection (looks like iOS does not look for this headers). This app runs at one.example.com.
Now, I have to write a second AngularJS app that will run at two.example.com and there's a third being planned for the near future at three.example.com.
My problem is that my Access-Control-Allow-Origin header looks like this:
Access-Control-Allow-Origin: http://one.example.com:80
* is not allowed, nor I'm able to set this header to more than one origin. So as far as I can see I have two solutions:
Implement token-based authentication in parallel to the current cookie-based one. I'm thinking on this. This will of course take some time I'm willing to save.
Send the requester a header or param to the API endpoint identifying the app on the OPTIONS request and server-side, produce the CORS headers accordingly. I don't even know if it's possible and this looks nasty for even thinking it.
Any better ideas?
If they have the same origin, example the same domain (example.com) or the same subdomain (1.ex.example.com and 2.ex.example.com) they can share the same cookie. Because cookie is based on the domain itself.

Resources