Protect Endpoints on App Engine from Host Header Injection

342 views
Skip to first unread message

Alexandru Gogan

unread,
Jul 14, 2020, 2:24:11 PM7/14/20
to Google Cloud Endpoints
Hi everyone, 
I noticed a potential vulnerability using a node.js API deployed on App Engine Flex with Cloud Endpoints. 

GET / HTTP/1.1

As I understand from the documentation highlighting the openapi limitations (https://cloud.google.com/endpoints/docs/openapi/openapi-limitations) the ESP does not support root paths. Without overriding the host I receive the error 

{

 "code": 5,

 "message": "Method does not exist.",

 "details": [

  {

   "@type": "type.googleapis.com/google.rpc.DebugInfo",

   "stackEntries": [],

   "detail": "service_control"

  }

 ]

}

Is there a suggested way to configure the ESP to only accept requests with the host set to a set of allowed domains in order to protect from Host Header Injection?

Wayne Zhang

unread,
Jul 14, 2020, 3:04:34 PM7/14/20
to Alexandru Gogan, Google Cloud Endpoints
I am confused.  Are you saying, in ESP,  if not HOST specified in Http Get request with root "/",  it fails with 404, but with HOST, it works.  Is that correct?

Just
GET / HTTP/1.1
It fails with 404

Following works:
GET / HTTP/1.1

it gets 200,  is that correct?

My understanding is root path "/" is only supported in ESPv2,  ESP failed with "/" regardless HOST is set or not.



--
You received this message because you are subscribed to the Google Groups "Google Cloud Endpoints" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-cloud-endp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-cloud-endpoints/035b1e61-4ba0-4c74-b2d1-8c9e2ede82a7n%40googlegroups.com.

Alexandru Gogan

unread,
Jul 14, 2020, 3:20:22 PM7/14/20
to Google Cloud Endpoints
If HOST is specified in the GET request with '/' root and the correct host, I get a 404 method does not exist
e.g. 
GET / HTTP/1.1
Host: my.domain.com
Response 404

{
    "code": 5,
    "message": "Method does not exist.",
    "details": [
        {
            "@type": "type.googleapis.com/google.rpc.DebugInfo",
            "stackEntries": [],
            "detail": "service_control"
        }
    ]
}

if the HOST is specified in the GET request with '/' root and the host is specified to a different one, ESP follows it, responds with a 404 status code but loads the content of the specified host
e.g. 
GET / HTTP/1.1
Response 404
<html>
<head></head>
<body>EVIL SITE CONTENT</body>
</html>




Wayne Zhang

unread,
Jul 14, 2020, 3:55:56 PM7/14/20
to Alexandru Gogan, Google Cloud Endpoints
It is odd.  ESP set "sever_name" in its Nginx config as "".  It can accept any HOST headers.   Your requests must be rejected by AppEngine Flex,  not by ESP.



Alexandru Gogan

unread,
Jul 14, 2020, 4:03:57 PM7/14/20
to Google Cloud Endpoints
It doesn't seem like the request is actually hitting the AppEngine at all. Is there a way for me to identify for certain if a request was forwarded to AppEngine? 

Wayne Zhang

unread,
Jul 14, 2020, 4:49:49 PM7/14/20
to Alexandru Gogan, Google Cloud Endpoints
You can check the App Engine log in the Cloud Console

Alexandru Gogan

unread,
Jul 14, 2020, 4:59:48 PM7/14/20
to Google Cloud Endpoints
I can see requests with correct HOST on the root path being logged, however if I provide an additional, incorrect HOST the request is not being logged and I see the content of the site as the response with the status code 404

Wayne Zhang

unread,
Jul 14, 2020, 5:02:23 PM7/14/20
to Alexandru Gogan, Google Cloud Endpoints
I believe GCLB in front of AppEngine rejects it since it doesn't have the correct HOST header.

Alexandru Gogan

unread,
Jul 14, 2020, 5:05:03 PM7/14/20
to Google Cloud Endpoints
Is there a way to change the behaviour to not follow the host? I find it odd that it loads the content of the host in the response

Wayne Zhang

unread,
Jul 14, 2020, 5:18:40 PM7/14/20
to Alexandru Gogan, Google Cloud Endpoints
If you issue

curl app-engine-dns   -H "Host: evil-host"

The request is forwarded to "evil-host".

If that is the case, I think it is a bug in AppEngine.  Could you check with the Google AppEngine team?

Alexandru Gogan

unread,
Jul 14, 2020, 5:30:17 PM7/14/20
to Google Cloud Endpoints
So with this curl 

curl --location --request GET 'http://my-project.nn.r.appspot.com' \
--header 'Host: evil.host.com'
I receive a 404 not found with contents from google ... <p>The requested URL <code>/</code> was not found on this server.  <ins>That’s all we know.</ins>...

Using https instead like I receive an error message
curl --location --request GET 'https://my-project.nn.r.appspot.com' \
--header 'Host: evil.host.com

Error: Hostname/IP does not match certificate's altnames: Host: evil.host.com. is not in the cert's altnames: DNS:*.appspot-preview.com, DNS:*.an.r.appspot.com, DNS:*.app.google, DNS:*.appspot.com, DNS:*.as.r.appspot.com, DNS:*.de.r.appspot.com, DNS:*.df.r.appspot.com, DNS:*.dt.r.appspot.com, DNS:*.du.r.appspot.com, DNS:*.el.r.appspot.com, DNS:*.et.r.appspot.com, DNS:*.ew.r.appspot.com, DNS:*.ey.r.appspot.com, DNS:*.ez.r.appspot.com, DNS:*.lz.r.appspot.com, DNS:*.nn.r.appspot.com, DNS:*.nw.r.appspot.com, DNS:*.nz.r.appspot.com, DNS:*.oa.r.appspot.com, DNS:*.rj.r.appspot.com, DNS:*.thinkwithgoogle.com, DNS:*.ts.r.appspot.com, DNS:*.tz.r.appspot.com, DNS:*.uc.r.appspot.com, DNS:*.ue.r.appspot.com, DNS:*.uk.r.appspot.com, DNS:*.uw.r.appspot.com, DNS:*.withgoogle.com, DNS:*.withyoutube.com, DNS:*.wl.r.appspot.com, DNS:*.wm.r.appspot.com, DNS:*.wn.r.appspot.com, DNS:app.google, DNS:appspot-preview.com, DNS:appspot.com, DNS:thinkwithgoogle.com, DNS:withgoogle.com, DNS:withyoutube.com


Thanks for helping narrowing it down, I'll try to figure out if it is something that can be configured directly on AppEngine
Reply all
Reply to author
Forward
0 new messages