From b351668b400e4a0d38ad7e854a0ac892aeb823c2 Mon Sep 17 00:00:00 2001 From: tyler92 Date: Thu, 26 Sep 2024 01:39:29 +0300 Subject: [PATCH] poco: Net library fuzzing (#12506) Two new fuzzing targets: - HTTP messages (request/response/authorization) parsing - Mail message parsing --- projects/poco/Dockerfile | 2 + projects/poco/build.sh | 26 ++++++++ projects/poco/http_message_fuzzer.cc | 97 ++++++++++++++++++++++++++++ projects/poco/mail_message_fuzzer.cc | 38 +++++++++++ 4 files changed, 163 insertions(+) create mode 100644 projects/poco/http_message_fuzzer.cc create mode 100644 projects/poco/mail_message_fuzzer.cc diff --git a/projects/poco/Dockerfile b/projects/poco/Dockerfile index afe63d192b75..4182c72ca5c5 100644 --- a/projects/poco/Dockerfile +++ b/projects/poco/Dockerfile @@ -24,5 +24,7 @@ COPY build.sh \ xml_parse_fuzzer.cc \ date_time_fuzzer.cc \ jwt_decode_fuzzer.cc \ + http_message_fuzzer.cc \ + mail_message_fuzzer.cc \ xml.dict \ $SRC/ diff --git a/projects/poco/build.sh b/projects/poco/build.sh index 9ced2e3ffefb..fff158e28165 100755 --- a/projects/poco/build.sh +++ b/projects/poco/build.sh @@ -77,4 +77,30 @@ $CXX $CXXFLAGS $LIB_FUZZING_ENGINE jwt_decode_fuzzer.o \ ./lib/libPocoCrypto.a \ -o $OUT/jwt_decode_fuzzer -lpthread -ldl -lrt -lssl -lcrypto +$CXX $CXXFLAGS -DPOCO_HAVE_FD_EPOLL -DPOCO_OS_FAMILY_UNIX \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ + -D_REENTRANT -D_THREAD_SAFE -D_XOPEN_SOURCE=500 \ + -I/src/poco/Foundation/include \ + -I/src/poco/Net/include \ + -O2 -g -DNDEBUG -std=c++17 \ + -o http_message_fuzzer.o -c $SRC/http_message_fuzzer.cc + +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE http_message_fuzzer.o \ + ./lib/libPocoNet.a \ + ./lib/libPocoFoundation.a \ + -o $OUT/http_message_fuzzer -lpthread -ldl -lrt + +$CXX $CXXFLAGS -DPOCO_HAVE_FD_EPOLL -DPOCO_OS_FAMILY_UNIX \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ + -D_REENTRANT -D_THREAD_SAFE -D_XOPEN_SOURCE=500 \ + -I/src/poco/Foundation/include \ + -I/src/poco/Net/include \ + -O2 -g -DNDEBUG -std=c++17 \ + -o mail_message_fuzzer.o -c $SRC/mail_message_fuzzer.cc + +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE mail_message_fuzzer.o \ + ./lib/libPocoNet.a \ + ./lib/libPocoFoundation.a \ + -o $OUT/mail_message_fuzzer -lpthread -ldl -lrt + cp $SRC/xml.dict $OUT/xml_parser_fuzzer.dict diff --git a/projects/poco/http_message_fuzzer.cc b/projects/poco/http_message_fuzzer.cc new file mode 100644 index 000000000000..c9b18ca0817d --- /dev/null +++ b/projects/poco/http_message_fuzzer.cc @@ -0,0 +1,97 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "Poco/MemoryStream.h" +#include "Poco/Net/EscapeHTMLStream.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/Net/HTTPCredentials.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" +#include "Poco/Net/OAuth10Credentials.h" +#include "Poco/Net/OAuth20Credentials.h" +#include "Poco/NullStream.h" + +using namespace Poco; + +template +void catchExceptions(const F &func) { + try { + func(); + } catch (const std::exception &) { + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + NullOutputStream null; + + // HTTPRequest parsing + catchExceptions([&] { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::HTTPRequest request; + request.read(stream); + request.write(null); + }); + + // HTTPResponse parsing + catchExceptions([&] { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::HTTPResponse response; + response.read(stream); + response.write(null); + }); + + // HTTPCredentials + catchExceptions([&] { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::HTTPResponse response; + response.read(stream); + + Net::HTTPRequest request(Net::HTTPRequest::HTTP_GET, "/"); + request.setHost(response.get(Net::HTTPRequest::HOST)); + + Net::HTTPCredentials creds; + creds.authenticate(request, response); + creds.updateAuthInfo(request); + creds.proxyAuthenticate(request, response); + creds.updateProxyAuthInfo(request); + }); + + // OAuth10Credentials + catchExceptions([&] { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::HTTPRequest request; + request.read(stream); + + Net::EscapeHTMLOutputStream htmlStream(null); + Net::HTMLForm form(request, stream); + form.prepareSubmit(request); + form.write(htmlStream); + + Net::OAuth10Credentials oauth10(request); + oauth10.verify(request, URI(request.getURI()), form); + oauth10.authenticate(request, URI(request.getURI()), form); + }); + + // OAuth20Credentials + catchExceptions([&] { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::HTTPRequest request; + request.read(stream); + + Net::OAuth20Credentials oauth20(request); + oauth20.authenticate(request); + }); + + return 0; +} diff --git a/projects/poco/mail_message_fuzzer.cc b/projects/poco/mail_message_fuzzer.cc new file mode 100644 index 000000000000..170bf5a42f50 --- /dev/null +++ b/projects/poco/mail_message_fuzzer.cc @@ -0,0 +1,38 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "Poco/MemoryStream.h" +#include "Poco/Net/MailMessage.h" +#include "Poco/Net/MailStream.h" +#include "Poco/NullStream.h" + +using namespace Poco; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + try { + MemoryInputStream stream(reinterpret_cast(data), size); + Net::MailInputStream mis(stream); + Net::MailMessage mail; + mail.read(mis); + mail.addRecipient( + Net::MailRecipient(Net::MailRecipient::CC_RECIPIENT, + Net::MailMessage::encodeWord(mail.getSender()))); + NullOutputStream null; + Net::MailOutputStream mos(null); + mail.write(mos); + } catch (const std::exception &) { + } + + return 0; +}