diff options
author | Daniel Stenberg <daniel@haxx.se> | 2019-02-18 09:10:01 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-02-20 08:18:02 +0100 |
commit | aa5a28bd697d652f78ba471022092e148d0b6e4f (patch) | |
tree | ca8573ac9127aa9e193777cd6bb89bf34bd92e4c /lib | |
parent | afc00e047c773faeaa60a5f86a246cbbeeba5819 (diff) |
http2: verify :athority in push promise requests
RFC 7540 says we should verify that the push is for an "authoritative"
server. We make sure of this by only allowing push with an :athority
header that matches the host that was asked for in the URL.
Fixes #3577
Reported-by: Nicolas Grekas
Bug: https://curl.haxx.se/mail/lib-2019-02/0057.html
Closes #3581
Diffstat (limited to 'lib')
-rw-r--r-- | lib/http2.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/http2.c b/lib/http2.c index 2884c7152..b5c53cdf6 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -969,6 +969,28 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { char *h; + if(!strcmp(":authority", (const char *)name)) { + /* psuedo headers are lower case */ + int rc = 0; + char *check = aprintf("%s:%d", conn->host.name, conn->remote_port); + if(!check) + /* no memory */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + if(!Curl_strcasecompare(check, (const char *)value)) { + /* This is push is not for the same authority that was asked for in + * the URL. RFC 7540 section 8.2 says: "A client MUST treat a + * PUSH_PROMISE for which the server is not authoritative as a stream + * error of type PROTOCOL_ERROR." + */ + (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + stream_id, NGHTTP2_PROTOCOL_ERROR); + rc = NGHTTP2_ERR_CALLBACK_FAILURE; + } + free(check); + if(rc) + return rc; + } + if(!stream->push_headers) { stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * |