How to force https on Google Cloud AppEngine - google-app-engine

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.

Related

Disabling version specific urls in Google appengine

Google App-Engine supports version-specific routing of requests as documented here.
This is useful for example for testing a new version prior to deploying it.
However, this may also be problematic. Say the new version includes security enhancements - there should be a way to prevent access to previous versions without deleting them completely (in order to allow for quick roll-back for instance). Could not find a way to disable previous versions.
Is there a way to accomplish that ?
Thanks.
There is no way to disable default/soft/targeted routing on the appspot.com domain.
But you could analyze the request's url structure and specifically reject requests with such undesired urls.
Or, if you're using a custom domain, reject all appspot.com requests (see Disable default domain https://[project-id].appspot.com of Node JS on Google App Engine) and only leave the custom domain operational. Then the domain will be served following the service's traffic migration/splitting configuration which you'd manipulate in your deployments/rollback actions (you cannot route to a specific service version in the dispatch.yaml file)
Update: indeed, as comments mentioned, blindly rejecting all appspot.com requests isn't a good idea. Since URLs would need to be parsed to select the undesired ones it may be worthy to take the opportunity to redirect to canonical custom domain counterparts instead of just rejecting the requests.

Correctly assign HTTPS only custom domain to flex env

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.

Google App Engine 302 Found response

We have a micro service running on GCloud and to our surprise today a very important callback we expect from a vendor service receives a 302 Found response. Which is not an issue, problem is that vendor is not prepared to adjust their code to follow redirects.
Is their any solution around such cases, some configuration in GCloud we can activate. Funny we don't get 302 when we make calls from local machine and testing environments.
Figured out the issue: In our case vendor was using HTTP protocol instead of HTTPS since we have a secure:always configuration in app.yaml they where getting 302 which makes sense, since app engine was redirecting to HTTPS.

Accessing Google Calendar API from AngularJS APP

I am implementing (I am trying to implement) a 100% client side AngularJS web app which should access the google calendar API. Of course, this doesn't work because I hit the cross domain problem:
XMLHttpRequest cannot load http://... . Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
Is there any solution to bypass this issue, except creating a proxy? By setting some header or changing some google configuration? I don't see one ...
Great hint Philipp! The google javascript api client (see here) does the job.
But I am wondering: How does the google javascript api client bypasses the cross domain issue? Does someone know?
You need googles side to return the right headers, Access-Control-Allow-Origin, to your browser so it doesnt complain about the cross browser issue.
Make sure in the google cloud console is configured correctly to web application. Im assuming web app because the redirect though.
If its a phoneapp or not serving anything on localhost:9000 redirect endpoint there are other options. For example you could open up the oauth redirect in another window, still use localhost:9000 as the redirect. Even though you are not listening at that port you could still grab the url code or error that is set on the redirect from the parent window.
CORS is an issue that you will experience when running the app through web browsers. I suggest you download a CORS toggle extension on google chrome so you can toggle off CORS and the API will connect. Good luck!

urlfetch.fetch() from Google App Engine not showing up in Fiddler2

I'm testing a Google App Engine app on my Windows machine, running locally on localhost:8084. Fiddler2 shows all my activity when I navigate around my app, but when requesting an external url with urlfetch.fetch() it doesn't show up in Fiddler at all, even when using an http, not an https address, and with a successful status code 200 in the response.
What do I need to do to get the urlfetch.fetch() request from Google App Engine to show up in Fiddler2?
My understanding is that Fiddler2 runs as an HTTP proxy; browser requests go through this proxy instead of directly to the internet resource. This allows Fiddler2 to capture information about the request and the response.
According to the Fiddler2 docs, "You can configure any application which accepts a HTTP Proxy to run through Fiddler so you can debug its traffic". So I think you would need to change the URLFetch API call to use a proxy, supplying the Fiddler URL and port. However, the URLFetch documentation doesn't specify exactly how to do this. You might be able to use urllib2 as specified in this question.
Irussell is generally right, but I'd like to make the answer more specific.
As proxies aren’t supported within Google AppEngine production environment, it’s not directly supported by development engine either. It seems that the only way to overcome this limitation is to modify the code of AppEngine development server.
You'll have to modify the urlfetch_stub.py file, by adding the following lines:
connection = connection_class('127.0.0.1', 8888)
and
full_path = protocol + "://" + host + full_path
You may find the detailed explanation in my blog post Use Fiddler to debug urlfetch requests in Google AppEngine

Resources