diff --git a/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs b/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs index 687b03ebd..ca9ad0fba 100644 --- a/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs @@ -66,6 +66,10 @@ public Task BasicSecurityScanShouldPass() => // - Disables one of ZAP's passive scan rules for the whole scan. // - Also disables a rule but only for the /about page. Use this to disable rules more specifically instead of the // whole scan. + // - Adds a false positive rule filter for the Absence of Anti-CSRF Tokens rule, but only for the search form with + // the ID or class "my-search-form" which is displayed on every page. For less common filters (e.g., filters other + // than by URL), you can use the .ModifyZapPlan() and .AddFalsePositiveRuleFilter() extension methods to configure + // the action filter YAML node directly. // - Configures sign in with a user account. This is what the scan will start with. This doesn't matter much with // the Blog recipe, because nothing on the frontend will change. You can use this to scan authenticated features // too. This is necessary because ZAP uses its own spider so it doesn't share session or cookies with the browser. @@ -84,6 +88,17 @@ public Task SecurityScanWithCustomConfigurationShouldPass() => .ExcludeUrlWithRegex(".*blog.*") .DisablePassiveScanRule(10020, "The response does not include either Content-Security-Policy with 'frame-ancestors' directive.") .DisableScanRuleForUrlWithRegex(".*/about", 10038, "Content Security Policy (CSP) Header Not Set") + .ModifyZapPlan(plan => plan + .AddFalsePositiveRuleFilter( + ".*", + 10202, + "Absence of Anti-CSRF Tokens", + "The search form doesn't alter the state of the application so anti-CSRF tokens are not needed.", + node => + { + node.Children["evidence"] = ".*my-search-form.*"; + node.Children["evidenceRegex"] = "true"; + })) .SignIn(), sarifLog => sarifLog.Runs[0].Results.Count.ShouldBe(0)), changeConfiguration: configuration => configuration.UseAssertAppLogsForSecurityScan()); diff --git a/Lombiq.Tests.UI/Docs/SecurityScanning.md b/Lombiq.Tests.UI/Docs/SecurityScanning.md index 88b2b1f35..34b7e5817 100644 --- a/Lombiq.Tests.UI/Docs/SecurityScanning.md +++ b/Lombiq.Tests.UI/Docs/SecurityScanning.md @@ -41,7 +41,7 @@ This is because the Docker installation is configured to use Windows images, whi - Most common alerts in Orchard Core can be resolved by [using the extension method in Lombiq Helpful Libraries](https://github.com/Lombiq/Helpful-Libraries/blob/dev/Lombiq.HelpfulLibraries.OrchardCore/Docs/Security.md) like this: `orchardCoreBuilder.ConfigureSecurityDefaults(allowInlineStyle: true)`. - If you're unsure what happens in a scan, run the [ZAP desktop app](https://www.zaproxy.org/download/) and load the Automation Framework plan's YAML file into it. If you use the default scans, then these will be available under the build output directory (like _bin/Debug_) under _SecurityScanning/AutomationFrameworkPlans_. Then, you can open and run them as demonstrated [in this video](https://youtu.be/PnCbIAnauD8?si=u0vi63Uvv9wZINzb&t=1173). -- If an alert is a false positive, follow [the official docs](https://www.zaproxy.org/faq/how-do-i-handle-a-false-positive/). You can use the [`alertFilter` job](https://www.zaproxy.org/docs/desktop/addons/alert-filters/automation/) to ignore alerts in very specific conditions. You can also access this via the .NET configuration API via `SecurityScanConfiguration.MarkScanRuleAsFalsePositiveForUrlWithRegex()`. +- If an alert is a false positive, follow [the official docs](https://www.zaproxy.org/faq/how-do-i-handle-a-false-positive/). You can use the [`alertFilter` job](https://www.zaproxy.org/docs/desktop/addons/alert-filters/automation/) to ignore alerts in very specific conditions. You can also access this via the .NET configuration API via `SecurityScanConfiguration.MarkScanRuleAsFalsePositiveForUrlWithRegex()`. For less common filters (e.g., filters other than by URL), you can use the `SecurityScanConfiguration.ModifyZapPlan()` and `YamlDocument.AddFalsePositiveRuleFilter()` extension methods to configure the action filter YAML node directly (see `SecurityScanWithCustomConfigurationShouldPass` test in the sample). - ZAP didn't find everything in your app? By default, ZAP has a crawl depth of 5 for its standard spider and 10 for its AJAX spider. Set `maxDepth` (and `maxChildren`) [for `spider`](https://www.zaproxy.org/docs/desktop/addons/automation-framework/job-spider/) and `maxCrawlDepth` [for `spiderAjax`](https://www.zaproxy.org/docs/desktop/addons/ajax-spider/automation/). - Do you sometimes get slightly different scan results? This is normal, and ZAP can be inconsistent/appear random within limits, see [the official docs page](https://www.zaproxy.org/faq/why-can-zap-scans-be-inconsistent/). - Is the active scan too slow?