// // Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include #include #include #include #include #include #include #include #include "test_common/ci_server.hpp" using namespace boost::mysql; namespace asio = boost::asio; // Fuzzes format_sql in an attempt to find SQL injection vulnerabilities. // This is not a usual fuzzer, as it sends the generated SQL to a real server - // this is the only way to be truly sure that no injection took place namespace { class fuzzer { asio::io_context ctx_; any_connection conn_; public: fuzzer() : conn_(ctx_) { connect_params params{ host_and_port{test::get_hostname()}, test::integ_user, test::integ_passwd, test::integ_db, }; params.ssl = ssl_mode::disable; conn_.connect(params); } int test(const uint8_t* data, size_t size) { // Create the query format_context ctx(conn_.format_opts().value()); format_sql_to( ctx, "SELECT id FROM three_rows_table WHERE field_varchar = {}", string_view(reinterpret_cast(data), size) ); auto query = std::move(ctx).get(); // If the generated query contains an error, the input wasn't valid UTF-8 - reject the sample if (query.has_error()) return -1; // Execute it results r; conn_.execute(*query, r); // Check that we didn't get excess data auto retrieved_rows = r.rows().size(); if (retrieved_rows != 1u && retrieved_rows != 0u) throw std::runtime_error("Retrieved more rows than expected"); return 0; } }; } // namespace extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { static fuzzer f; return f.test(data, size); }