nghttpx: Strip incoming Early-Data header field by default

This commit is contained in:
Tatsuhiro Tsujikawa 2018-09-09 22:37:22 +09:00
parent cfe7fa9a75
commit 5b42815afb
9 changed files with 55 additions and 3 deletions

View File

@ -31,6 +31,7 @@ HEADERS = [
"user-agent", "user-agent",
"date", "date",
"content-type", "content-type",
"early-data",
# disallowed h1 headers # disallowed h1 headers
'connection', 'connection',
'keep-alive', 'keep-alive',

View File

@ -174,6 +174,7 @@ OPTIONS = [
"tls-max-early-data", "tls-max-early-data",
"tls13-ciphers", "tls13-ciphers",
"tls13-client-ciphers", "tls13-client-ciphers",
"no-strip-incoming-early-data",
] ]
LOGVARS = [ LOGVARS = [

View File

@ -389,6 +389,11 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
case HD_TRANSFER_ENCODING: case HD_TRANSFER_ENCODING:
case HD_UPGRADE: case HD_UPGRADE:
continue; continue;
case HD_EARLY_DATA:
if (flags & HDOP_STRIP_EARLY_DATA) {
continue;
}
break;
case HD_FORWARDED: case HD_FORWARDED:
if (flags & HDOP_STRIP_FORWARDED) { if (flags & HDOP_STRIP_FORWARDED) {
continue; continue;
@ -483,6 +488,11 @@ void build_http1_headers_from_headers(DefaultMemchunks *buf,
case HD_SERVER: case HD_SERVER:
case HD_UPGRADE: case HD_UPGRADE:
continue; continue;
case HD_EARLY_DATA:
if (flags & HDOP_STRIP_EARLY_DATA) {
continue;
}
break;
case HD_FORWARDED: case HD_FORWARDED:
if (flags & HDOP_STRIP_FORWARDED) { if (flags & HDOP_STRIP_FORWARDED) {
continue; continue;
@ -828,6 +838,11 @@ int lookup_token(const uint8_t *name, size_t namelen) {
break; break;
case 10: case 10:
switch (name[9]) { switch (name[9]) {
case 'a':
if (util::streq_l("early-dat", name, 9)) {
return HD_EARLY_DATA;
}
break;
case 'e': case 'e':
if (util::streq_l("keep-aliv", name, 9)) { if (util::streq_l("keep-aliv", name, 9)) {
return HD_KEEP_ALIVE; return HD_KEEP_ALIVE;

View File

@ -203,9 +203,13 @@ enum HeaderBuildOp {
// Via header fields must be stripped. If this flag is not set, all // Via header fields must be stripped. If this flag is not set, all
// Via header fields other than last one are added. // Via header fields other than last one are added.
HDOP_STRIP_VIA = 1 << 3, HDOP_STRIP_VIA = 1 << 3,
// Early-Data header fields must be stripped. If this flag is not
// set, all Early-Data header fields are added.
HDOP_STRIP_EARLY_DATA = 1 << 4,
// Strip above all header fields. // Strip above all header fields.
HDOP_STRIP_ALL = HDOP_STRIP_FORWARDED | HDOP_STRIP_X_FORWARDED_FOR | HDOP_STRIP_ALL = HDOP_STRIP_FORWARDED | HDOP_STRIP_X_FORWARDED_FOR |
HDOP_STRIP_X_FORWARDED_PROTO | HDOP_STRIP_VIA, HDOP_STRIP_X_FORWARDED_PROTO | HDOP_STRIP_VIA |
HDOP_STRIP_EARLY_DATA,
}; };
// Appends headers in |headers| to |nv|. |headers| must be indexed // Appends headers in |headers| to |nv|. |headers| must be indexed
@ -304,6 +308,7 @@ enum {
HD_CONTENT_TYPE, HD_CONTENT_TYPE,
HD_COOKIE, HD_COOKIE,
HD_DATE, HD_DATE,
HD_EARLY_DATA,
HD_EXPECT, HD_EXPECT,
HD_FORWARDED, HD_FORWARDED,
HD_HOST, HD_HOST,

View File

@ -1487,6 +1487,7 @@ void fill_default_config(Config *config) {
httpconf.max_requests = std::numeric_limits<size_t>::max(); httpconf.max_requests = std::numeric_limits<size_t>::max();
httpconf.xfp.add = true; httpconf.xfp.add = true;
httpconf.xfp.strip_incoming = true; httpconf.xfp.strip_incoming = true;
httpconf.early_data.strip_incoming = true;
auto &http2conf = config->http2; auto &http2conf = config->http2;
{ {
@ -2644,6 +2645,9 @@ HTTP:
Default: obfuscated Default: obfuscated
--no-via Don't append to Via header field. If Via header field --no-via Don't append to Via header field. If Via header field
is received, it is left unaltered. is received, it is left unaltered.
--no-strip-incoming-early-data
Don't strip Early-Data header field from inbound client
requests.
--no-location-rewrite --no-location-rewrite
Don't rewrite location header field in default mode. Don't rewrite location header field in default mode.
When --http2-proxy is used, location header field will When --http2-proxy is used, location header field will
@ -3475,6 +3479,8 @@ int main(int argc, char **argv) {
{SHRPX_OPT_TLS_MAX_EARLY_DATA.c_str(), required_argument, &flag, 163}, {SHRPX_OPT_TLS_MAX_EARLY_DATA.c_str(), required_argument, &flag, 163},
{SHRPX_OPT_TLS13_CIPHERS.c_str(), required_argument, &flag, 164}, {SHRPX_OPT_TLS13_CIPHERS.c_str(), required_argument, &flag, 164},
{SHRPX_OPT_TLS13_CLIENT_CIPHERS.c_str(), required_argument, &flag, 165}, {SHRPX_OPT_TLS13_CLIENT_CIPHERS.c_str(), required_argument, &flag, 165},
{SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA.c_str(), no_argument, &flag,
166},
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
int option_index = 0; int option_index = 0;
@ -4263,6 +4269,11 @@ int main(int argc, char **argv) {
// --tls13-client-ciphers // --tls13-client-ciphers
cmdcfgs.emplace_back(SHRPX_OPT_TLS13_CLIENT_CIPHERS, StringRef{optarg}); cmdcfgs.emplace_back(SHRPX_OPT_TLS13_CLIENT_CIPHERS, StringRef{optarg});
break; break;
case 166:
// --no-strip-incoming-early-data
cmdcfgs.emplace_back(SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA,
StringRef::from_lit("yes"));
break;
default: default:
break; break;
} }

View File

@ -2186,6 +2186,11 @@ int option_lookup_token(const char *name, size_t namelen) {
break; break;
case 28: case 28:
switch (name[27]) { switch (name[27]) {
case 'a':
if (util::strieq_l("no-strip-incoming-early-dat", name, 27)) {
return SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA;
}
break;
case 'd': case 'd':
if (util::strieq_l("tls-dyn-rec-warmup-threshol", name, 27)) { if (util::strieq_l("tls-dyn-rec-warmup-threshol", name, 27)) {
return SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD; return SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD;
@ -3626,6 +3631,10 @@ int parse_config(Config *config, int optid, const StringRef &opt,
case SHRPX_OPTID_TLS_MAX_EARLY_DATA: { case SHRPX_OPTID_TLS_MAX_EARLY_DATA: {
return parse_uint_with_unit(&config->tls.max_early_data, opt, optarg); return parse_uint_with_unit(&config->tls.max_early_data, opt, optarg);
} }
case SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA:
config->http.early_data.strip_incoming = !util::strieq_l("yes", optarg);
return 0;
case SHRPX_OPTID_CONF: case SHRPX_OPTID_CONF:
LOG(WARN) << "conf: ignored"; LOG(WARN) << "conf: ignored";

View File

@ -354,6 +354,8 @@ constexpr auto SHRPX_OPT_TLS_MAX_EARLY_DATA =
constexpr auto SHRPX_OPT_TLS13_CIPHERS = StringRef::from_lit("tls13-ciphers"); constexpr auto SHRPX_OPT_TLS13_CIPHERS = StringRef::from_lit("tls13-ciphers");
constexpr auto SHRPX_OPT_TLS13_CLIENT_CIPHERS = constexpr auto SHRPX_OPT_TLS13_CLIENT_CIPHERS =
StringRef::from_lit("tls13-client-ciphers"); StringRef::from_lit("tls13-client-ciphers");
constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA =
StringRef::from_lit("no-strip-incoming-early-data");
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
@ -704,6 +706,9 @@ struct HttpConfig {
bool add; bool add;
bool strip_incoming; bool strip_incoming;
} xfp; } xfp;
struct {
bool strip_incoming;
} early_data;
std::vector<AltSvc> altsvcs; std::vector<AltSvc> altsvcs;
std::vector<ErrorPage> error_pages; std::vector<ErrorPage> error_pages;
HeaderRefs add_request_headers; HeaderRefs add_request_headers;
@ -1100,6 +1105,7 @@ enum {
SHRPX_OPTID_NO_OCSP, SHRPX_OPTID_NO_OCSP,
SHRPX_OPTID_NO_SERVER_PUSH, SHRPX_OPTID_NO_SERVER_PUSH,
SHRPX_OPTID_NO_SERVER_REWRITE, SHRPX_OPTID_NO_SERVER_REWRITE,
SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA,
SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO, SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO,
SHRPX_OPTID_NO_VERIFY_OCSP, SHRPX_OPTID_NO_VERIFY_OCSP,
SHRPX_OPTID_NO_VIA, SHRPX_OPTID_NO_VIA,

View File

@ -320,11 +320,13 @@ int Http2DownstreamConnection::push_request_headers() {
auto &fwdconf = httpconf.forwarded; auto &fwdconf = httpconf.forwarded;
auto &xffconf = httpconf.xff; auto &xffconf = httpconf.xff;
auto &xfpconf = httpconf.xfp; auto &xfpconf = httpconf.xfp;
auto &earlydataconf = httpconf.early_data;
uint32_t build_flags = uint32_t build_flags =
(fwdconf.strip_incoming ? http2::HDOP_STRIP_FORWARDED : 0) | (fwdconf.strip_incoming ? http2::HDOP_STRIP_FORWARDED : 0) |
(xffconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_FOR : 0) | (xffconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_FOR : 0) |
(xfpconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_PROTO : 0); (xfpconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_PROTO : 0) |
(earlydataconf.strip_incoming ? http2::HDOP_STRIP_EARLY_DATA : 0);
http2::copy_headers_to_nva_nocopy(nva, req.fs.headers(), build_flags); http2::copy_headers_to_nva_nocopy(nva, req.fs.headers(), build_flags);

View File

@ -540,11 +540,13 @@ int HttpDownstreamConnection::push_request_headers() {
auto &fwdconf = httpconf.forwarded; auto &fwdconf = httpconf.forwarded;
auto &xffconf = httpconf.xff; auto &xffconf = httpconf.xff;
auto &xfpconf = httpconf.xfp; auto &xfpconf = httpconf.xfp;
auto &earlydataconf = httpconf.early_data;
uint32_t build_flags = uint32_t build_flags =
(fwdconf.strip_incoming ? http2::HDOP_STRIP_FORWARDED : 0) | (fwdconf.strip_incoming ? http2::HDOP_STRIP_FORWARDED : 0) |
(xffconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_FOR : 0) | (xffconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_FOR : 0) |
(xfpconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_PROTO : 0); (xfpconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_PROTO : 0) |
(earlydataconf.strip_incoming ? http2::HDOP_STRIP_EARLY_DATA : 0);
http2::build_http1_headers_from_headers(buf, req.fs.headers(), build_flags); http2::build_http1_headers_from_headers(buf, req.fs.headers(), build_flags);