doc/devdocs/tools/fuzzingtesting.md
Fuzzing is an automated testing technique that helps identify vulnerabilities and bugs by feeding random, invalid, or unexpected data into the application. This is especially important for PowerToys modules that handle file input/output or user input, such as Hosts File Editor, Registry Preview, and others.
PowerToys integrates Microsoft's OneFuzz service to systematically discover edge cases and unexpected behaviors that could lead to crashes or security vulnerabilities. Fuzzing testing is a requirement from the security team to ensure robust and secure modules.
PowerToys supports two types of fuzzing depending on the module's implementation language:
Create a new test project within your module folder. Ensure the project name follows the format *.FuzzTests.
Set up a .NET 8 (Windows) project
Add the required files to your fuzzing test project:
OneFuzzConfig.json configuration fileThe OneFuzzConfig.json file provides critical information for deploying fuzzing jobs. For detailed guidance, see the OneFuzzConfig V3 Documentation.
{
"fuzzers": [
{
"name": "YourModuleFuzzer",
"fuzzerLibrary": "libfuzzer-dotnet",
"targetAssembly": "YourModule.FuzzTests.dll",
"targetClass": "YourModule.FuzzTests.FuzzTestClass",
"targetMethod": "FuzzTest",
"FuzzingTargetBinaries": [
"YourModule.FuzzTests.dll"
]
}
],
"adoTemplate": [
{
"AssignedTo": "[email protected]",
"jobNotificationEmail": "[email protected]"
}
],
"oneFuzzJobs": [
{
"projectName": "PowerToys",
"targetName": "YourModule",
"jobDependencies": {
"binaries": [
"PowerToys\\x64\\Debug\\tests\\YourModule.FuzzTests\\net8.0-windows10.0.19041.0\\**"
]
}
}
],
"configVersion": "3.0.0"
}
Key fields to update:
targetAssembly, targetClass, targetMethod, and FuzzingTargetBinaries fieldsAssignedTo and jobNotificationEmail to your Microsoft emailprojectName and targetName fieldsModify the patterns in the job steps within job-fuzz.yml to match your fuzzing project name:
- download: current
displayName: Download artifacts
artifact: $(ArtifactName)
patterns: |-
**/tests/*.FuzzTests/**
<ModuleName>.FuzzingTestEdit the project file to enable fuzzing:
<PropertyGroup>
<EnableASAN>true</EnableASAN>
<EnableFuzzer>true</EnableFuzzer>
</PropertyGroup>
Add these to AdditionalOptions under the Fuzzing configuration:
/fsanitize=address
/fsanitize-coverage=inline-8bit-counters
/fsanitize-coverage=edge
/fsanitize-coverage=trace-cmp
/fsanitize-coverage=trace-div
%(AdditionalOptions)
In Linker → Input → Additional Dependencies, add:
$(VCToolsInstallDir)lib\$(Platform)\libsancov.lib
Add a PostBuildEvent to copy the ASAN DLL:
<Command>
xcopy /y "$(VCToolsInstallDir)bin\Hostx64\x64\clang_rt.asan_dynamic-x86_64.dll" "$(OutDir)"
</Command>
To avoid annotation issues, add these to the Preprocessor Definitions:
_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION
Every C++ fuzzing project must expose this function:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
std::string input(reinterpret_cast<const char*>(data), size);
try
{
// Call your module with the input here
}
catch (...) {}
return 0;
}
To run .NET fuzzing tests locally, follow the Running a .NET Fuzz Target Locally guide:
# Instrument the assembly
.\dotnet-fuzzing-windows\sharpfuzz\SharpFuzz.CommandLine.exe path\to\YourModule.FuzzTests.dll
# Set environment variables
$env:LIBFUZZER_DOTNET_TARGET_ASSEMBLY="path\to\YourModule.FuzzTests.dll"
$env:LIBFUZZER_DOTNET_TARGET_CLASS="YourModule.FuzzTests.FuzzTestClass"
$env:LIBFUZZER_DOTNET_TARGET_METHOD="FuzzTest"
# Run the fuzzer
.\dotnet-fuzzing-windows\libfuzzer-dotnet\libfuzzer-dotnet.exe --target_path=dotnet-fuzzing-windows\LibFuzzerDotnetLoader\LibFuzzerDotnetLoader.exe
To submit a job to the OneFuzz cloud service, follow the OneFuzz Cloud Testing Walkthrough:
Run the pipeline:
Alternative: Use OIP (OneFuzz Ingestion Preparation) tool:
oip submit --config .\OneFuzzConfig.json --drop-path <your_submission_directory> --platform windows --do-not-file-bugs --duration 1
--do-not-file-bugs to prevent automatic bug creation during initial testing--duration specifies the number of hours (default is 48 if not specified)OneFuzz will send you an email when the job has started with a link to view results
PowerToys has implemented fuzzing for several modules:
Modules that still need fuzzing implementation:
To log into the production instance of OneFuzz with the CLI, you must request access. Visit the OneFuzz Access Request Page.