summaryrefslogtreecommitdiff
path: root/lib/http2.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2019-02-18 09:10:01 +0100
committerDaniel Stenberg <daniel@haxx.se>2019-02-20 08:18:02 +0100
commitaa5a28bd697d652f78ba471022092e148d0b6e4f (patch)
treeca8573ac9127aa9e193777cd6bb89bf34bd92e4c /lib/http2.c
parentafc00e047c773faeaa60a5f86a246cbbeeba5819 (diff)
downloadcurl-aa5a28bd697d652f78ba471022092e148d0b6e4f.tar.gz
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/http2.c')
-rw-r--r--lib/http2.c22
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 *