Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ASM] IAST: Add web form tests #6276

Merged
merged 3 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
// </copyright>

#if NETFRAMEWORK
using System.Net;
using System.Security.Policy;
using System.Threading.Tasks;
using Datadog.Trace.TestHelpers;
using Xunit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,26 @@ await VerifyHelper.VerifySpans(spansFiltered, settings)
newFixture.Dispose();
newFixture.SetOutput(null);
}

[Fact]
[Trait("Category", "ArmUnsupported")]
[Trait("RunOnWindows", "True")]
public async Task TestQueryParameterNameVulnerability()
{
var filename = "Iast.QueryParameterName.AspNetCore5";
var url = "/Iast/Print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1";
IncludeAllHttpSpans = true;
await TryStartApp();
var agent = Fixture.Agent;
var spans = await SendRequestsAsync(agent, [url]);
var spansFiltered = spans.Where(x => x.Type == SpanTypes.Web).ToList();

var settings = VerifyHelper.GetSpanVerifierSettings();
settings.AddIastScrubbing();
await VerifyHelper.VerifySpans(spansFiltered, settings)
.UseFileName(filename)
.DisableRequireUniquePrefix();
}
}

// Classes to test particular features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ public async Task TestStackTraceLeak(string test, string url)
{
await TestStrictTransportSecurityHeaderMissingVulnerability(test, url);
}

[Trait("Category", "EndToEnd")]
[Trait("RunOnWindows", "True")]
[Trait("LoadFromGAC", "True")]
[SkippableTheory]
[InlineData(AddressesConstants.RequestQuery, "/Iast/Print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1")]
public async Task TestQueryParameterNameVulnerability(string test, string url)
{
await TestQueryParameterName(test, url);
}
}

[Collection("IisTests")]
Expand Down Expand Up @@ -650,6 +660,19 @@ await VerifyHelper.VerifySpans(spansFiltered, settings)
.DisableRequireUniquePrefix();
}

protected async Task TestQueryParameterName(string test, string url)
{
var sanitisedUrl = VerifyHelper.SanitisePathsForVerify(url);
var settings = VerifyHelper.GetSpanVerifierSettings(test, sanitisedUrl, null);
var spans = await SendRequestsAsync(_iisFixture.Agent, [url]);
var filename = GetFileName("QueryParameterName");
var spansFiltered = spans.Where(x => x.Type == SpanTypes.Web).ToList();
settings.AddIastScrubbing();
await VerifyHelper.VerifySpans(spansFiltered, settings)
.UseFileName(filename)
.DisableRequireUniquePrefix();
}

protected override string GetTestName() => _testName;

private string GetFileName(string testName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// <copyright file="AspNetWebFormsWithIast.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#if NETFRAMEWORK
using System.Threading.Tasks;
using Datadog.Trace.Iast.Telemetry;
using Datadog.Trace.TestHelpers;
using Xunit;
using Xunit.Abstractions;

#pragma warning disable SA1402 // File may only contain a single class
#pragma warning disable SA1649 // File name must match first type name
namespace Datadog.Trace.Security.IntegrationTests.IAST;

[Collection("IisTests")]
public class AspNetWebFormsIntegratedWithIast : AspNetWebFormsWithIast
{
public AspNetWebFormsIntegratedWithIast(IisFixture iisFixture, ITestOutputHelper output)
: base(iisFixture, output, classicMode: false, enableSecurity: true)
{
}
}

[Collection("IisTests")]
public class AspNetWebFormsClassicIntegratedWithIast : AspNetWebFormsWithIast
{
public AspNetWebFormsClassicIntegratedWithIast(IisFixture iisFixture, ITestOutputHelper output)
: base(iisFixture, output, classicMode: true, enableSecurity: true)
{
}
}

public abstract class AspNetWebFormsWithIast : AspNetBase, IClassFixture<IisFixture>, IAsyncLifetime
{
private readonly IisFixture _iisFixture;
private readonly bool _classicMode;

public AspNetWebFormsWithIast(IisFixture iisFixture, ITestOutputHelper output, bool classicMode, bool enableSecurity)
: base("WebForms", output, "/home/shutdown", @"test\test-applications\security\aspnet")
{
EnableIast(true);
EnableEvidenceRedaction(false);
EnableIastTelemetry((int)IastMetricsVerbosityLevel.Off);
SetEnvironmentVariable("DD_IAST_DEDUPLICATION_ENABLED", "false");
SetEnvironmentVariable("DD_IAST_REQUEST_SAMPLING", "100");
SetEnvironmentVariable("DD_IAST_MAX_CONCURRENT_REQUESTS", "100");
SetEnvironmentVariable("DD_IAST_VULNERABILITIES_PER_REQUEST", "100");
SetEnvironmentVariable(Configuration.ConfigurationKeys.AppSec.StackTraceEnabled, "false");

_iisFixture = iisFixture;
_classicMode = classicMode;
_testName = "Security." + nameof(AspNetWebForms)
+ (classicMode ? ".Classic" : ".Integrated")
+ ".enableSecurity=" + enableSecurity;
}

[Trait("Category", "EndToEnd")]
[Trait("RunOnWindows", "True")]
[Trait("LoadFromGAC", "True")]
[SkippableTheory]
[InlineData("TestQueryParameterNameVulnerability")]
public async Task TestQueryParameterNameVulnerability(string test)
{
var url = "/print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1";

var settings = VerifyHelper.GetSpanVerifierSettings(test);
settings.AddIastScrubbing();

await TestAppSecRequestWithVerifyAsync(_iisFixture.Agent, url, null, 1, 1, settings, userAgent: "Hello/V");
}

public async Task InitializeAsync()
{
await _iisFixture.TryStartIis(this, _classicMode ? IisAppType.AspNetClassic : IisAppType.AspNetIntegrated);
SetHttpPort(_iisFixture.HttpPort);
}

public Task DisposeAsync() => Task.CompletedTask;

protected override string GetTestName() => _testName;
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[
{
TraceId: Id_1,
SpanId: Id_2,
Name: aspnet_core.request,
Resource: GET /iast/print,
Service: Samples.Security.AspNetCore5,
Type: web,
Tags: {
aspnet_core.endpoint: Samples.Security.AspNetCore5.Controllers.IastController.PrintReport (Samples.Security.AspNetCore5),
aspnet_core.route: iast/print,
component: aspnet_core,
env: integration_tests,
http.method: GET,
http.request.headers.host: localhost:00000,
http.route: iast/print,
http.status_code: 200,
http.url: http://localhost:00000/Iast/Print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1,
http.useragent: Mistake Not...,
language: dotnet,
runtime-id: Guid_1,
span.kind: server,
_dd.iast.enabled: 1,
_dd.iast.json:
{
"vulnerabilities": [
{
"type": "SQL_INJECTION",
"hash": -209503571,
"location": {
"spanId": XXX,
"path": "Samples.Security.AspNetCore5.Controllers.IastController",
"method": "ExecuteQuery"
},
"evidence": {
"valueParts": [
{
"value": "\r\nDECLARE @ClientDatabaseID INT = (SELECT ClientDatabaseID FROM[GetClientDatabase]('",
"source": 0
},
{
"value": "'))\r\n\r\nSELECT SSRSReports FROM [ClientCentral].[dbo].[ClientDatabases] WHERE ClientDatabaseID = @ClientDatabaseID)",
"source": 0
}
]
}
}
],
"sources": [
{
"origin": "http.request.parameter.name",
"name": "ClientDatabase"
}
]
}
},
Metrics: {
process_id: 0,
_dd.top_level: 1.0,
_dd.tracer_kr: 1.0,
_sampling_priority_v1: 2.0
}
},
{
TraceId: Id_1,
SpanId: Id_3,
Name: aspnet_core_mvc.request,
Resource: GET /iast/print,
Service: Samples.Security.AspNetCore5,
Type: web,
ParentId: Id_2,
Tags: {
aspnet_core.action: printreport,
aspnet_core.controller: iast,
aspnet_core.route: iast/print,
component: aspnet_core,
env: integration_tests,
language: dotnet,
span.kind: server
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
[
{
TraceId: Id_1,
SpanId: Id_2,
Name: aspnet.request,
Resource: GET /iast/print,
Service: sample,
Type: web,
Tags: {
env: integration_tests,
http.method: GET,
http.request.headers.host: localhost:00000,
http.route: {controller}/{action}/{id},
http.status_code: 200,
http.url: http://localhost:00000/Iast/Print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1,
http.useragent: Mistake Not...,
language: dotnet,
runtime-id: Guid_1,
span.kind: server,
_dd.iast.enabled: 1,
_dd.iast.json:
{
"vulnerabilities": [
{
"type": "SQL_INJECTION",
"hash": -209503571,
"location": {
"spanId": XXX,
"path": "Samples.Security.AspNetCore5.Controllers.IastController",
"method": "ExecuteQuery"
},
"evidence": {
"valueParts": [
{
"value": "\r\nDECLARE @ClientDatabaseID INT = (SELECT ClientDatabaseID FROM[GetClientDatabase]('",
"source": 0
},
{
"value": "'))\r\n\r\nSELECT SSRSReports FROM [ClientCentral].[dbo].[ClientDatabases] WHERE ClientDatabaseID = @ClientDatabaseID)",
"source": 0
}
]
}
}
],
"sources": [
{
"origin": "http.request.parameter.name",
"name": "ClientDatabase"
}
]
}
},
Metrics: {
process_id: 0,
_dd.top_level: 1.0,
_dd.tracer_kr: 1.0,
_sampling_priority_v1: 2.0
}
},
{
TraceId: Id_1,
SpanId: Id_3,
Name: aspnet-mvc.request,
Resource: GET /iast/print,
Service: sample,
Type: web,
ParentId: Id_2,
Tags: {
aspnet.action: print,
aspnet.controller: iast,
aspnet.route: {controller}/{action}/{id},
env: integration_tests,
http.method: GET,
http.request.headers.host: localhost:00000,
http.status_code: 200,
http.url: http://localhost:00000/Iast/Print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1,
http.useragent: Mistake Not...,
language: dotnet,
span.kind: server
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[
{
TraceId: Id_1,
SpanId: Id_2,
Name: aspnet.request,
Resource: GET /print,
Service: sample,
Type: web,
Tags: {
env: integration_tests,
http.method: GET,
http.request.headers.host: localhost:00000,
http.status_code: 200,
http.url: http://localhost:00000/print?Encrypt=True&ClientDatabase=774E4D65564946426A53694E48756B592B444A6C43673D3D&p=413&ID=2376&EntityType=114&Print=True&OutputType=WORDOPENXML&SSRSReportID=1,
http.useragent: Mistake Not... Hello/V,
language: dotnet,
runtime-id: Guid_1,
span.kind: server,
_dd.iast.enabled: 1,
_dd.iast.json:
{
"vulnerabilities": [
{
"type": "PATH_TRAVERSAL",
"hash": -1368908679,
"location": {
"spanId": XXX,
"path": "Iast_Print",
"method": "Page_Load",
"line": XXX
},
"evidence": {
"valueParts": [
{
"value": "ClientDatabase",
"source": 0
}
]
}
}
],
"sources": [
{
"origin": "http.request.parameter.name",
"name": "ClientDatabase"
}
]
}
},
Metrics: {
process_id: 0,
_dd.top_level: 1.0,
_dd.tracer_kr: 1.0,
_sampling_priority_v1: 2.0
}
}
]
Loading
Loading