diff options
Diffstat (limited to 'libs/cpp-httplib/test/fuzzing')
17 files changed, 428 insertions, 0 deletions
diff --git a/libs/cpp-httplib/test/fuzzing/CMakeLists.txt b/libs/cpp-httplib/test/fuzzing/CMakeLists.txt new file mode 100644 index 0000000..7e416c7 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB HTTPLIB_CORPUS corpus/*) +add_executable(httplib-test-fuzz + server_fuzzer.cc + standalone_fuzz_target_runner.cpp +) +target_link_libraries(httplib-test-fuzz PRIVATE httplib) +add_test( + NAME httplib-test-fuzz + COMMAND httplib-test-fuzz ${HTTPLIB_CORPUS} +) diff --git a/libs/cpp-httplib/test/fuzzing/Makefile b/libs/cpp-httplib/test/fuzzing/Makefile new file mode 100644 index 0000000..b08ecd0 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/Makefile @@ -0,0 +1,27 @@ + +#CXX = clang++ +# Do not add default sanitizer flags here as OSS-fuzz adds its own sanitizer flags. +CXXFLAGS += -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I../.. -I. -Wall -Wextra -Wtype-limits -Wconversion + +OPENSSL_DIR = /usr/local/opt/openssl@1.1 + +# Using full path to libssl and libcrypto to avoid accidentally picking openssl libs brought in by msan. +OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -I$(OPENSSL_DIR)/lib /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a + +ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz + +BROTLI_DIR = /usr/local/opt/brotli +# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec + +# Runs all the tests and also fuzz tests against seed corpus. +all : server_fuzzer + ./server_fuzzer corpus/* + +# Fuzz target, so that you can choose which $(LIB_FUZZING_ENGINE) to use. +server_fuzzer : server_fuzzer.cc ../../httplib.h +# $(CXX) $(CXXFLAGS) -o $@ $< -Wl,-Bstatic $(OPENSSL_SUPPORT) -Wl,-Bdynamic -ldl $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread + $(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread -lanl + zip -q -r server_fuzzer_seed_corpus.zip corpus + +clean: + rm -f server_fuzzer pem *.0 *.o *.1 *.srl *.zip diff --git a/libs/cpp-httplib/test/fuzzing/corpus/1 b/libs/cpp-httplib/test/fuzzing/corpus/1 new file mode 100644 index 0000000..2b9fcc4 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/1 @@ -0,0 +1 @@ +PUT /search/sample?a=12 HTTP/1.1
\ No newline at end of file diff --git a/libs/cpp-httplib/test/fuzzing/corpus/2 b/libs/cpp-httplib/test/fuzzing/corpus/2 new file mode 100644 index 0000000..bdb9bcc --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/2 @@ -0,0 +1,5 @@ +GET /hello.htm HTTP/1.1 +User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT) +Accept-Language: en-us +Accept-Encoding: gzip, deflate +Connection: Keep-Alive
\ No newline at end of file diff --git a/libs/cpp-httplib/test/fuzzing/corpus/3 b/libs/cpp-httplib/test/fuzzing/corpus/3 Binary files differnew file mode 100644 index 0000000..878944f --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/3 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 Binary files differnew file mode 100644 index 0000000..0325729 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5372331946541056 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5372331946541056 Binary files differnew file mode 100644 index 0000000..6fca86b --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5372331946541056 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5386708825800704 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5386708825800704 Binary files differnew file mode 100644 index 0000000..1f1e4ae --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5386708825800704 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5667822731132928 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5667822731132928 Binary files differnew file mode 100644 index 0000000..b21d1ce --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5667822731132928 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5886572146327552 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5886572146327552 Binary files differnew file mode 100644 index 0000000..797165c --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5886572146327552 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5942767436562432 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5942767436562432 Binary files differnew file mode 100644 index 0000000..a2fedd5 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5942767436562432 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6007379124158464 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6007379124158464 Binary files differnew file mode 100644 index 0000000..4c4c57e --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6007379124158464 diff --git a/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696 b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696 new file mode 100644 index 0000000..6f89836 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-6508706672541696 @@ -0,0 +1,7 @@ +PUT { HTTP/1.0
+Content-Type:multipart/form-databoundary=m
+Range:bytes=-
+
+--m
+C +c
PUT ?&+&:&<&&I&`&a&&s&&&2&&&@&!&
PUT ?&+&:&<&&I&`&a&&s&&&2&&&@&!&
PUT ?&+&:&<&&I&`&a&&s&&&2&&&@&!&
X-Forwarded-Host
X-Forwarded-Host
PUT ?&+&:&<&&I&`&a&&s&&&2&&&@&!&
PUT ?&+&:&<&&I&`&a&&s&&&2&&&@&!&
X-Forwarded-Host
2
+/v+
\ No newline at end of file diff --git a/libs/cpp-httplib/test/fuzzing/corpus/issue1264 b/libs/cpp-httplib/test/fuzzing/corpus/issue1264 new file mode 100644 index 0000000..fd53db5 --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/corpus/issue1264 @@ -0,0 +1,19 @@ +POST /fform%u008anom%u08ag HTTP/1.0
+Don +Rcn ,Co +Cofffffffffffffffffffffffntemt + + + + + +Content-Length:dent:applica;tion/x-wsw-form%`00368aogrlencod368angrlencoded
+JJ` +o
+
+8 +
+8 +92H +Content-Encoding:PUT { HTTP/1.0
+Content-Type:Range:bytes=-
multipart/
\ No newline at end of file diff --git a/libs/cpp-httplib/test/fuzzing/server_fuzzer.cc b/libs/cpp-httplib/test/fuzzing/server_fuzzer.cc new file mode 100644 index 0000000..a0f7c0e --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/server_fuzzer.cc @@ -0,0 +1,100 @@ +#include <cstdint> + +#include <httplib.h> + +class FuzzedStream : public httplib::Stream { +public: + FuzzedStream(const uint8_t *data, size_t size) + : data_(data), size_(size), read_pos_(0) {} + + ssize_t read(char *ptr, size_t size) override { + if (size + read_pos_ > size_) { size = size_ - read_pos_; } + memcpy(ptr, data_ + read_pos_, size); + read_pos_ += size; + return static_cast<ssize_t>(size); + } + + ssize_t write(const char *ptr, size_t size) override { + response_.append(ptr, size); + return static_cast<int>(size); + } + + ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); } + + ssize_t write(const std::string &s) { return write(s.data(), s.size()); } + + bool is_readable() const override { return true; } + + bool wait_readable() const override { return true; } + + bool wait_writable() const override { return true; } + + void get_remote_ip_and_port(std::string &ip, int &port) const override { + ip = "127.0.0.1"; + port = 8080; + } + + void get_local_ip_and_port(std::string &ip, int &port) const override { + ip = "127.0.0.1"; + port = 8080; + } + + socket_t socket() const override { return 0; } + + time_t duration() const override { return 0; }; + +private: + const uint8_t *data_; + size_t size_; + size_t read_pos_; + std::string response_; +}; + +class FuzzableServer : public httplib::Server { +public: + void ProcessFuzzedRequest(FuzzedStream &stream) { + bool connection_close = false; + process_request(stream, + /*remote_addr=*/"", + /*remote_port =*/0, + /*local_addr=*/"", + /*local_port =*/0, + /*last_connection=*/false, connection_close, nullptr); + } +}; + +static FuzzableServer g_server; + +extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) { + g_server.Get(R"(.*)", + [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + g_server.Post(R"(.*)", + [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + g_server.Put(R"(.*)", + [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + g_server.Patch(R"(.*)", + [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + g_server.Delete( + R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + g_server.Options( + R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) { + res.set_content("response content", "text/plain"); + }); + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedStream stream{data, size}; + g_server.ProcessFuzzedRequest(stream); + return 0; +} diff --git a/libs/cpp-httplib/test/fuzzing/server_fuzzer.dict b/libs/cpp-httplib/test/fuzzing/server_fuzzer.dict new file mode 100644 index 0000000..47283dc --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/server_fuzzer.dict @@ -0,0 +1,224 @@ +# Sources: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields + +# misc +"HTTP/1.1" + +# verbs +"CONNECT" +"DELETE" +"GET" +"HEAD" +"OPTIONS" +"PATCH" +"POST" +"PUT" +"TRACE" + + +# Webdav/caldav verbs +"ACL" +"BASELINE-CONTROL" +"BIND" +"CHECKIN" +"CHECKOUT" +"COPY" +"LABEL" +"LINK" +"LOCK" +"MERGE" +"MKACTIVITY" +"MKCALENDAR" +"MKCOL" +"MKREDIRECTREF" +"MKWORKSPACE" +"MOVE" +"ORDERPATCH" +"PRI" +"PROPFIND" +"PROPPATCH" +"REBIND" +"REPORT" +"SEARCH" +"UNBIND" +"UNCHECKOUT" +"UNLINK" +"UNLOCK" +"UPDATE" +"UPDATEREDIRECTREF" +"VERSION-CONTROL" + + +# Fields +"A-IM" +"Accept" +"Accept-Charset" +"Accept-Datetime" +"Accept-Encoding" +"Accept-Language" +"Accept-Patch" +"Accept-Ranges" +"Access-Control-Allow-Credentials" +"Access-Control-Allow-Headers" +"Access-Control-Allow-Methods" +"Access-Control-Allow-Origin" +"Access-Control-Expose-Headers" +"Access-Control-Max-Age" +"Access-Control-Request-Headers" +"Access-Control-Request-Method" +"Age" +"Allow" +"Alt-Svc" +"Authorization" +"Cache-Control" +"Connection" +"Connection:" +"Content-Disposition" +"Content-Encoding" +"Content-Language" +"Content-Length" +"Content-Location" +"Content-MD5" +"Content-Range" +"Content-Security-Policy" +"Content-Type" +"Cookie" +"DNT" +"Date" +"Delta-Base" +"ETag" +"Expect" +"Expires" +"Forwarded" +"From" +"Front-End-Https" +"HTTP2-Settings" +"Host" +"IM" +"If-Match" +"If-Modified-Since" +"If-None-Match" +"If-Range" +"If-Unmodified-Since" +"Last-Modified" +"Link" +"Location" +"Max-Forwards" +"Origin" +"P3P" +"Pragma" +"Proxy-Authenticate" +"Proxy-Authorization" +"Proxy-Connection" +"Public-Key-Pins" +"Range" +"Referer" +"Refresh" +"Retry-After" +"Save-Data" +"Server" +"Set-Cookie" +"Status" +"Strict-Transport-Security" +"TE" +"Timing-Allow-Origin" +"Tk" +"Trailer" +"Transfer-Encoding" +"Upgrade" +"Upgrade-Insecure-Requests" +"User-Agent" +"Vary" +"Via" +"WWW-Authenticate" +"Warning" +"X-ATT-DeviceId" +"X-Content-Duration" +"X-Content-Security-Policy" +"X-Content-Type-Options" +"X-Correlation-ID" +"X-Csrf-Token" +"X-Forwarded-For" +"X-Forwarded-Host" +"X-Forwarded-Proto" +"X-Frame-Options" +"X-Http-Method-Override" +"X-Powered-By" +"X-Request-ID" +"X-Requested-With" +"X-UA-Compatible" +"X-UIDH" +"X-Wap-Profile" +"X-WebKit-CSP" +"X-XSS-Protection" + +# Source: string and character literals in httplib.h +" " +"&" +", " +"-" +"--" +"." +".." +":" +"=" +" = = " +"0123456789abcdef" +"%02X" +"%0A" +"\\x0a\\x0d" +"%0D" +"%20" +"%27" +"%2B" +"%2C" +"%3A" +"%3B" +"application/javascript" +"application/json" +"application/pdf" +"application/xhtml+xml" +"application/xml" +"application/x-www-form-urlencoded" +"Bad Request" +"boundary=" +"bytes=" +"chunked" +"close" +"CONNECT" +"css" +"Forbidden" +"Found" +"gif" +"gzip" +"html" +"ico" +"image/gif" +"image/jpg" +"image/png" +"image/svg+xml" +"image/x-icon" +"index.html" +"Internal Server Error" +"jpeg" +"js" +"json" +"Location" +"Moved Permanently" +"multipart/form-data" +"Not Found" +"Not Modified" +"OK" +"pdf" +"png" +"Range" +"REMOTE_ADDR" +"See Other" +"svg" +"text/" +"text/css" +"text/html" +"text/plain" +"txt" +"Unsupported Media Type" +"xhtml" +"xml"
\ No newline at end of file diff --git a/libs/cpp-httplib/test/fuzzing/standalone_fuzz_target_runner.cpp b/libs/cpp-httplib/test/fuzzing/standalone_fuzz_target_runner.cpp new file mode 100644 index 0000000..e8bd5ed --- /dev/null +++ b/libs/cpp-httplib/test/fuzzing/standalone_fuzz_target_runner.cpp @@ -0,0 +1,35 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); + +// This runner does not do any fuzzing, but allows us to run the fuzz target +// on the test corpus or on a single file, +// e.g. the one that comes from a bug report. + +#include <cstdint> +#include <fstream> +#include <iostream> +#include <vector> + +// Forward declare the "fuzz target" interface. +// We deliberately keep this interface simple and header-free. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +// It reads all files passed as parameters and feeds their contents +// one by one into the fuzz target (LLVMFuzzerTestOneInput). +int main(int argc, char **argv) { + for (int i = 1; i < argc; i++) { + std::ifstream in(argv[i]); + in.seekg(0, in.end); + size_t length = static_cast<size_t>(in.tellg()); + in.seekg(0, in.beg); + std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl; + // Allocate exactly length bytes so that we reliably catch buffer overflows. + std::vector<char> bytes(length); + in.read(bytes.data(), static_cast<std::streamsize>(bytes.size())); + LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()), + bytes.size()); + std::cout << "Execution successful" << std::endl; + } + std::cout << "Execution finished" << std::endl; + return 0; +} |
