nghttpx: Escape certain characters in access log
The certain characters coming from client are now escaped with "\xNN" where NN is the ascii code of the character in hex notation.
This commit is contained in:
parent
e77883e980
commit
19ee7ec794
105
src/shrpx_log.cc
105
src/shrpx_log.cc
|
@ -240,6 +240,105 @@ std::pair<OutputIterator, OutputIterator> copy(T n, OutputIterator d_first,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// 1 means that character must be escaped as "\xNN", where NN is ascii
|
||||||
|
// code of the character in hex notation.
|
||||||
|
constexpr uint8_t ESCAPE_TBL[] = {
|
||||||
|
1 /* NUL */, 1 /* SOH */, 1 /* STX */, 1 /* ETX */, 1 /* EOT */,
|
||||||
|
1 /* ENQ */, 1 /* ACK */, 1 /* BEL */, 1 /* BS */, 1 /* HT */,
|
||||||
|
1 /* LF */, 1 /* VT */, 1 /* FF */, 1 /* CR */, 1 /* SO */,
|
||||||
|
1 /* SI */, 1 /* DLE */, 1 /* DC1 */, 1 /* DC2 */, 1 /* DC3 */,
|
||||||
|
1 /* DC4 */, 1 /* NAK */, 1 /* SYN */, 1 /* ETB */, 1 /* CAN */,
|
||||||
|
1 /* EM */, 1 /* SUB */, 1 /* ESC */, 1 /* FS */, 1 /* GS */,
|
||||||
|
1 /* RS */, 1 /* US */, 0 /* SPC */, 0 /* ! */, 1 /* " */,
|
||||||
|
0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */,
|
||||||
|
0 /* ( */, 0 /* ) */, 0 /* * */, 0 /* + */, 0 /* , */,
|
||||||
|
0 /* - */, 0 /* . */, 0 /* / */, 0 /* 0 */, 0 /* 1 */,
|
||||||
|
0 /* 2 */, 0 /* 3 */, 0 /* 4 */, 0 /* 5 */, 0 /* 6 */,
|
||||||
|
0 /* 7 */, 0 /* 8 */, 0 /* 9 */, 0 /* : */, 0 /* ; */,
|
||||||
|
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
|
||||||
|
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
|
||||||
|
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
|
||||||
|
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||||
|
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
|
||||||
|
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
|
||||||
|
0 /* Z */, 0 /* [ */, 1 /* \ */, 0 /* ] */, 0 /* ^ */,
|
||||||
|
0 /* _ */, 0 /* ` */, 0 /* a */, 0 /* b */, 0 /* c */,
|
||||||
|
0 /* d */, 0 /* e */, 0 /* f */, 0 /* g */, 0 /* h */,
|
||||||
|
0 /* i */, 0 /* j */, 0 /* k */, 0 /* l */, 0 /* m */,
|
||||||
|
0 /* n */, 0 /* o */, 0 /* p */, 0 /* q */, 0 /* r */,
|
||||||
|
0 /* s */, 0 /* t */, 0 /* u */, 0 /* v */, 0 /* w */,
|
||||||
|
0 /* x */, 0 /* y */, 0 /* z */, 0 /* { */, 0 /* | */,
|
||||||
|
0 /* } */, 0 /* ~ */, 1 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
|
||||||
|
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
|
||||||
|
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
||||||
|
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
|
||||||
|
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
|
||||||
|
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
|
||||||
|
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
||||||
|
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
|
||||||
|
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
|
||||||
|
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
|
||||||
|
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
||||||
|
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
|
||||||
|
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
|
||||||
|
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
|
||||||
|
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
||||||
|
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
|
||||||
|
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 1 /* 0xd0 */, 1 /* 0xd1 */,
|
||||||
|
1 /* 0xd2 */, 1 /* 0xd3 */, 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */,
|
||||||
|
1 /* 0xd7 */, 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
||||||
|
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, 1 /* 0xe0 */,
|
||||||
|
1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, 1 /* 0xe4 */, 1 /* 0xe5 */,
|
||||||
|
1 /* 0xe6 */, 1 /* 0xe7 */, 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */,
|
||||||
|
1 /* 0xeb */, 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
||||||
|
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, 1 /* 0xf4 */,
|
||||||
|
1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, 1 /* 0xf8 */, 1 /* 0xf9 */,
|
||||||
|
1 /* 0xfa */, 1 /* 0xfb */, 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */,
|
||||||
|
1 /* 0xff */,
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename OutputIterator>
|
||||||
|
std::pair<OutputIterator, OutputIterator>
|
||||||
|
copy_escape(const char *src, size_t srclen, OutputIterator d_first,
|
||||||
|
OutputIterator d_last) {
|
||||||
|
auto safe_first = src;
|
||||||
|
for (auto p = src; p != src + srclen && d_first != d_last; ++p) {
|
||||||
|
unsigned char c = *p;
|
||||||
|
if (!ESCAPE_TBL[c]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto n =
|
||||||
|
std::min(std::distance(d_first, d_last), std::distance(safe_first, p));
|
||||||
|
d_first = std::copy_n(safe_first, n, d_first);
|
||||||
|
if (std::distance(d_first, d_last) < 4) {
|
||||||
|
return std::make_pair(d_first, d_last);
|
||||||
|
}
|
||||||
|
*d_first++ = '\\';
|
||||||
|
*d_first++ = 'x';
|
||||||
|
*d_first++ = LOWER_XDIGITS[c >> 4];
|
||||||
|
*d_first++ = LOWER_XDIGITS[c & 0xf];
|
||||||
|
safe_first = p + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto n = std::min(std::distance(d_first, d_last),
|
||||||
|
std::distance(safe_first, src + srclen));
|
||||||
|
return std::make_pair(std::copy_n(safe_first, n, d_first), d_last);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename OutputIterator>
|
||||||
|
std::pair<OutputIterator, OutputIterator> copy_escape(const StringRef &src,
|
||||||
|
OutputIterator d_first,
|
||||||
|
OutputIterator d_last) {
|
||||||
|
return copy_escape(src.c_str(), src.size(), d_first, d_last);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Construct absolute request URI from |Request|, mainly to log
|
// Construct absolute request URI from |Request|, mainly to log
|
||||||
// request URI for proxy request (HTTP/2 proxy or client proxy). This
|
// request URI for proxy request (HTTP/2 proxy or client proxy). This
|
||||||
|
@ -329,7 +428,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
case SHRPX_LOGF_REQUEST:
|
case SHRPX_LOGF_REQUEST:
|
||||||
std::tie(p, last) = copy(method, p, last);
|
std::tie(p, last) = copy(method, p, last);
|
||||||
std::tie(p, last) = copy(' ', p, last);
|
std::tie(p, last) = copy(' ', p, last);
|
||||||
std::tie(p, last) = copy(path, p, last);
|
std::tie(p, last) = copy_escape(path, p, last);
|
||||||
std::tie(p, last) = copy_l(" HTTP/", p, last);
|
std::tie(p, last) = copy_l(" HTTP/", p, last);
|
||||||
std::tie(p, last) = copy(req.http_major, p, last);
|
std::tie(p, last) = copy(req.http_major, p, last);
|
||||||
if (req.http_major < 2) {
|
if (req.http_major < 2) {
|
||||||
|
@ -346,7 +445,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
case SHRPX_LOGF_HTTP: {
|
case SHRPX_LOGF_HTTP: {
|
||||||
auto hd = req.fs.header(lf.value);
|
auto hd = req.fs.header(lf.value);
|
||||||
if (hd) {
|
if (hd) {
|
||||||
std::tie(p, last) = copy((*hd).value, p, last);
|
std::tie(p, last) = copy_escape((*hd).value, p, last);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +486,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
std::tie(p, last) = copy(lgsp.pid, p, last);
|
std::tie(p, last) = copy(lgsp.pid, p, last);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_ALPN:
|
case SHRPX_LOGF_ALPN:
|
||||||
std::tie(p, last) = copy(lgsp.alpn, p, last);
|
std::tie(p, last) = copy_escape(lgsp.alpn, p, last);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SSL_CIPHER:
|
case SHRPX_LOGF_SSL_CIPHER:
|
||||||
if (!lgsp.tls_info) {
|
if (!lgsp.tls_info) {
|
||||||
|
|
Loading…
Reference in New Issue