nghttpx: Stream error if disallowed header field in HTTP2 is received
This commit is contained in:
parent
33743ab832
commit
89cd2ff479
|
@ -170,6 +170,24 @@ void copy_url_component(std::string& dest, http_parser_url *u, int field,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_http2_allowed_header(const char *name)
|
||||||
|
{
|
||||||
|
return check_http2_allowed_header(reinterpret_cast<const uint8_t*>(name),
|
||||||
|
strlen(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_http2_allowed_header(const uint8_t *name, size_t namelen)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
!util::strieq("connection", name, namelen) &&
|
||||||
|
!util::strieq("host", name, namelen) &&
|
||||||
|
!util::strieq("keep-alive", name, namelen) &&
|
||||||
|
!util::strieq("proxy-connection", name, namelen) &&
|
||||||
|
!util::strieq("te", name, namelen) &&
|
||||||
|
!util::strieq("transfer-encoding", name, namelen) &&
|
||||||
|
!util::strieq("upgrade", name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -52,6 +52,14 @@ std::string colorizeHeaders(const char *hdrs);
|
||||||
void copy_url_component(std::string& dest, http_parser_url *u, int field,
|
void copy_url_component(std::string& dest, http_parser_url *u, int field,
|
||||||
const char* url);
|
const char* url);
|
||||||
|
|
||||||
|
// Returns true if the header field |name| with length |namelen| bytes
|
||||||
|
// is valid for HTTP/2.0.
|
||||||
|
bool check_http2_allowed_header(const uint8_t *name, size_t namelen);
|
||||||
|
|
||||||
|
// Calls check_http2_allowed_header with |name| and strlen(name),
|
||||||
|
// assuming |name| is null-terminated string.
|
||||||
|
bool check_http2_allowed_header(const char *name);
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -217,6 +217,10 @@ void on_frame_recv_callback
|
||||||
{
|
{
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
for(i = 0, j = 0; i < frame->headers.nvlen && j < req_hdlen;) {
|
for(i = 0, j = 0; i < frame->headers.nvlen && j < req_hdlen;) {
|
||||||
|
if(!http::check_http2_allowed_header(nva[i].name, nva[i].namelen)) {
|
||||||
|
bad_req = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
int rv = util::strcompare(req_headers[j], nva[i].name, nva[i].namelen);
|
int rv = util::strcompare(req_headers[j], nva[i].name, nva[i].namelen);
|
||||||
if(rv > 0) {
|
if(rv > 0) {
|
||||||
if(nva[i].namelen > 0 && nva[i].name[0] != ':') {
|
if(nva[i].namelen > 0 && nva[i].name[0] != ':') {
|
||||||
|
@ -915,13 +919,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
|
||||||
nv[hdidx++] = response_status.c_str();
|
nv[hdidx++] = response_status.c_str();
|
||||||
for(Headers::const_iterator i = downstream->get_response_headers().begin();
|
for(Headers::const_iterator i = downstream->get_response_headers().begin();
|
||||||
i != downstream->get_response_headers().end(); ++i) {
|
i != downstream->get_response_headers().end(); ++i) {
|
||||||
if(util::strieq((*i).first.c_str(), "connection") ||
|
if(!http::check_http2_allowed_header((*i).first.c_str())) {
|
||||||
util::strieq((*i).first.c_str(), "host") ||
|
|
||||||
util::strieq((*i).first.c_str(), "keep-alive") ||
|
|
||||||
util::strieq((*i).first.c_str(), "proxy-connection") ||
|
|
||||||
util::strieq((*i).first.c_str(), "te") ||
|
|
||||||
util::strieq((*i).first.c_str(), "transfer-encoding") ||
|
|
||||||
util::strieq((*i).first.c_str(), "upgrade")) {
|
|
||||||
// These are ignored
|
// These are ignored
|
||||||
} else if(!get_config()->no_via &&
|
} else if(!get_config()->no_via &&
|
||||||
util::strieq((*i).first.c_str(), "via")) {
|
util::strieq((*i).first.c_str(), "via")) {
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "shrpx_spdy_downstream_connection.h"
|
#include "shrpx_spdy_downstream_connection.h"
|
||||||
#include "shrpx_client_handler.h"
|
#include "shrpx_client_handler.h"
|
||||||
#include "shrpx_ssl.h"
|
#include "shrpx_ssl.h"
|
||||||
|
#include "shrpx_http.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
|
@ -747,6 +748,10 @@ void on_frame_recv_callback
|
||||||
auto nva = frame->headers.nva;
|
auto nva = frame->headers.nva;
|
||||||
std::string status, content_length;
|
std::string status, content_length;
|
||||||
for(size_t i = 0; i < frame->headers.nvlen; ++i) {
|
for(size_t i = 0; i < frame->headers.nvlen; ++i) {
|
||||||
|
if(!http::check_http2_allowed_header(nva[i].name, nva[i].namelen)) {
|
||||||
|
status.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(util::strieq(":status", nva[i].name, nva[i].namelen)) {
|
if(util::strieq(":status", nva[i].name, nva[i].namelen)) {
|
||||||
status.assign(reinterpret_cast<char*>(nva[i].value),
|
status.assign(reinterpret_cast<char*>(nva[i].value),
|
||||||
nva[i].valuelen);
|
nva[i].valuelen);
|
||||||
|
|
Loading…
Reference in New Issue