I am serving an App Engine Standard Java 11 runtime behind a GCP API Gateway. The application uses Spring Security to set security headers. I want to enable Strict-Transport-Security header in my responses but even tough the header is enabled by Spring Security by default the responses from API GW doesn't include the header. Is there any way to enable Strict-Transport-Security on API GW?
The HTTP strict transport security (HSTS) web security policy mechanism helps to protect websites against attacks by forcing users to communicate with servers through HTTPS only. When users send HTTP requests to the server, it responds with a Strict-Transport-Security response header for a length of time specified in seconds. In the response header this length of time is depicted as the max-age attribute.
The standard way to set the Strict-Transport-Security header in your responses use:
Strict-Transport-Security: max-age=31536000; includeSubDomains
In addition, when enabling the Cloud API Gateway, the openAPI YAML file must be uploaded.
At this point, there can be two possible scenarios:
The Strict-Transport-Security header is not not configured successfully. In this case, it would be helpful to double check the App Engine direct response (When not using the Cloud API Gateway). This would make sure the App Engine is properly configured for outputting the header.
As in the GitHub link, there are no settings that might strip the Strict-Transport-Security header from the requests. But it would be worth double checking the YAML file to determine if there are any settings that might be modifying this header flag.
If the above two troubleshooting steps do not work, try opening a bug.
Related
The setup:
Service A (frontend): GAE serving static site, all calls made from A are happening on client side.
Service B (api): GAE instance hosting REST API.
Without Identity Aware Proxy, I am able to make requests from the clientside of the frontend to the api on a different hostname by setting CORS to allow calls from the service A hostname.
I would like to be able to do the same thing while both services are behind Identity Aware Proxy.
Following the instructions in IAP docs I have:
Set my app to respond the OPTIONS requests
Changed the setting access_settings.cors_settings.allow_http_options to true using gcloud CLI.
Here is the error I'm facing:
Access to XMLHttpRequest at 'https://api-dot-my-app-dev.appspot.com/api/123' from origin 'https://frontend-dot-my-app-dev.appspot.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
When I make the same requests from localhost to localhost or from service A (client side) to localhost api the requests succeed.
This leads me to believe that the issue is related to Identity Aware Proxy. My only guess is that it's related to the preflight request, which I don't see anything about in the network requests in the browser console.
I would really like to be able to keep both apps behind IAP with their own hostnames while still communicating. Unfortunately, I have about exhausted ideas for how to do this.
In the meantime I have it working using alternative #2 below for now.
Alternatives:
Have the API serve the static site so they are on the same hostname
Use dispatch.yaml to serve both sites from the same hostname
Any ideas if this is possible or what might be going wrong?
Edit: Here is a repo to demonstrate my problem.
Edit 2: According to this article, this functionality used to work and Google said it would be a good idea to support it but offered not timeline.
Not sure if that can be applied on your use case but I have seen this kind of issue being resolved by allowing CORS preflight request to be passed through IAP by changing the access_settings.cors_settings.allow_http_options to true.
I am trying to force https for all traffic to an app hosted on Google Cloud AppEngine. https works, but despite following the instructions for rewriting http traffic to https, it's still possible to access the site with http, which causes problems.
I have added this to the app.yaml:
handlers:
- url: /.*
script: _go_app
secure: always
redirect_http_response_code: 301
but it doesn't seem to make any difference.
I am using the julienschmidt router and then this to handle all routes:
log.Fatal(fmt.Println(http.ListenAndServe(":8080", router)))
I have looked at using http.ListenAndServeTLS but this takes extra parameters and I can't work out what the values of those should be in the Google AppEngine context.
log.Fatal(fmt.Println(http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", router)))
Where are "cert.pem" and "key.pem"?
I've read that I don't need to explicitly serve TLS in my app, because AppEngine will handle it for me, so even if I knew what the parameters were, I'm not sure it would help in forcing https.
http://sapling.appspot.com
https://sapling.appspot.com
http://sapling.money
https://sapling.money
All of the above work, but I don't seem able to force either of the http versions to https.
If you are using the secure:always handler and the requests are not being automatically redirected, then you are probably using App Engine Flex?
App Engine Flex does not support handlers, you can see this in the Flexible app.yaml documentation.
Instead, you can check in your code if a request was sent via HTTP or HTTPs and redirect. This is done with the App Engine specific header X-Forwarded-Proto.
The implementation is configured on your end and there is a brief paragraph on the subject.
You can also view similar Stack posts with the same answers 1
I hope this helps!
You are correct for including the secure: always element in your app.yaml as this will force HTTPS for your app's handlers.
However, I believe the following App Engine Documentation for "Securing Your App" found here may be of some use to you. As indicated in that link, you can convert HTTP URLs to HTTPS by simply replacing the periods between each resource with a -dot- instead. You may see the example provided below.
http://[SERVICE_ID].[MY_PROJECT_ID].appspot.com
https://[SERVICE_ID]-dot-[MY_PROJECT_ID].appspot.com
For additional information about HTTPS URLs and resource targeting you may see how requests are routed here.
Hope this helps!
You can use the Strict-Transport-Security header to instruct the browser to prefer https over http for a given page or an entire domain as outlined in this document. In order to add HTTP Strict-Transport-Security headers (HSTS) to your app, you must implement the headers within your app's code, not within your app's config file (app.yaml or appengine-web.xml).
It is also a good idea to enable HSTS preloading if you register your application with Google's HSTS preload list. Firefox and Chrome will never load your site over a non-secure connection.
What is the correct way to map a custom domain to Google App Engine project?
I've added the custom domain, set up all the DNS records etc. and it is working! But how do I enforce HTTPS only? (Like the custom domain generated does)
From reading around many posts I have seen secure: always in a handler which I have tried, but doesn't seem to work (saw some comments that it doesn't work on flex environments?)
So how can I correctly map my domain to a flex php environment being HTTPS only?! Seems such a simple thing to want to be able to do!
While being somewhat related to a custom domain (for example the SSL certificate used by HTTPS being tied to the domain) the HTTPS-only behaviour is not really an attribute of the custom domain mapping operation, it's just a behaviour of the app itself (regardless of being mapped to a custom domain or not).
For standard environment GAE apps part of the HTTPS-only behaviour is an automatic http -> https redirection performed by the GAE infra on behalf of the app if secure: always is set in the app.yaml configuration file.
But that configuration has, indeed, been deprecated for the flexible environment GAE apps. The PHP-specific deprecation note can be found at app.yaml changes:
Secure handlers
The secure setting under handlers is now deprecated for the App
Engine flexible environment. If you need SSL redirection, you can
update your application code and use the X-Forwarded-Proto header to
redirect http traffic. You can also use the HTTP Strict Transport
Security response header.
You'll also note that there is no mentioning of secure (or handlers for that matter) in the app.yaml Configuration File doc.
So you need to take care of the http -> https redirection inside your app code (or the framework you use for it, if any and if it has such capability), possibly following the suggestions from the above quote. I can't really help with details on this as I'm not a PHP user.
I am running into an issue with my Reactjs app that interfaces with Web API 2 deployed to Azure with Microsoft Authentication where my initial GET request throws an error that says:
Fetch API cannot load https://login.live.com/oauth20_authorize.srf?
client_id=[...]&redirect_uri=[MY_REDIRECT_URL].
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin '[MY_AZURE_SITE]' is therefore not allowed access. If an opaque response serves
your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I am really new to Azure and using React so I am unsure where i went wrong here. The weird part about this issue is that if I turn of Microsoft Authentication for my app it works as expected.
I have been stuck on this issue for a little while now, and am not really sure where I am going wrong. I also am not sure what information would be useful to help troubleshooting this issue so please feel free to comment asking for code/information and I will to update my question.
You are trying to get content from a different URL then your site originally host.
For security reasons APIs set some rules for requests. To be able to make requests you need to set up CORS. There for you need to set up appropriate headers for your requests.
You can read more about CORS here
A resource makes a cross-origin HTTP request when it requests a
resource from a different domain, protocol, or port to its own. For
example, an HTML page served from http://domain-a.com makes an
src request for http://domain-b.com/image.jpg. Many pages on the web
today load resources like CSS stylesheets, images, and scripts from
separate domains.
For security reasons, browsers restrict cross-origin HTTP requests
initiated from within scripts. For example, XMLHttpRequest and Fetch
follow the same-origin policy. So, a web application using
XMLHttpRequest or Fetch could only make HTTP requests to its own
domain. To improve web applications, developers asked browser vendors
to allow cross-domain requests.
I'm not aware of a solution that allows you to do this using SSL on CloudFront simply because it cannot pull from S3 over SSL. Am I missing something?
Yes. You can require your CloudFront content to be served via HTTPS to your viewers, and separately have CloudFront pull from your origin via HTTP or HTTPS. See Using an HTTPS Connection to Access Your Objects
That document states:
For web distributions, you can use HTTPS requests to ensure that your
objects are encrypted when CloudFront serves them to viewers and,
optionally, when CloudFront gets the objects from your origin.
The viewer <== CloudFront is one connection, and the CloudFront <== Originis another separate connection.
Its up to you whether or not you need SSL end to end, but there is no limitation like the one you describe.