Skip to content

Commit

Permalink
[ASM][IAST] Fix System.Text.Json: Properly implement GetRawText() aspect
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-0 authored May 17, 2024
1 parent 5b95b8d commit 18d5da4
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ internal static partial class AspectDefinitions
"[AspectClass(\"System.Text.Json\",[None],Source,[])] Datadog.Trace.Iast.Aspects.System.Text.Json.JsonDocumentAspects",
" [AspectMethodReplace(\"System.Text.Json.JsonDocument::Parse(System.String,System.Text.Json.JsonDocumentOptions)\",\"\",[0],[False],[None],Default,[])] Parse(System.String,System.Text.Json.JsonDocumentOptions)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetString()\",\"\",[0],[True],[None],Default,[])] GetString(System.Object)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetRawText()\",\"\",[0],[True],[None],Default,[])] GetString(System.Object)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetRawText()\",\"\",[0],[True],[None],Default,[])] GetRawText(System.Object)",
"[AspectClass(\"System.Web\",[None],Sink,[UnvalidatedRedirect])] Datadog.Trace.Iast.Aspects.System.Web.HttpResponseAspect",
" [AspectMethodInsertBefore(\"System.Web.HttpResponse::Redirect(System.String)\",\"\",[0],[False],[None],Default,[])] Redirect(System.String)",
" [AspectMethodInsertBefore(\"System.Web.HttpResponse::Redirect(System.String,System.Boolean)\",\"\",[1],[False],[None],Default,[])] Redirect(System.String)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ internal static partial class AspectDefinitions
"[AspectClass(\"System.Text.Json\",[None],Source,[])] Datadog.Trace.Iast.Aspects.System.Text.Json.JsonDocumentAspects",
" [AspectMethodReplace(\"System.Text.Json.JsonDocument::Parse(System.String,System.Text.Json.JsonDocumentOptions)\",\"\",[0],[False],[None],Default,[])] Parse(System.String,System.Text.Json.JsonDocumentOptions)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetString()\",\"\",[0],[True],[None],Default,[])] GetString(System.Object)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetRawText()\",\"\",[0],[True],[None],Default,[])] GetString(System.Object)",
" [AspectMethodReplace(\"System.Text.Json.JsonElement::GetRawText()\",\"\",[0],[True],[None],Default,[])] GetRawText(System.Object)",
"[AspectClass(\"System.Web\",[None],Sink,[UnvalidatedRedirect])] Datadog.Trace.Iast.Aspects.System.Web.HttpResponseAspect",
" [AspectMethodInsertBefore(\"System.Web.HttpResponse::Redirect(System.String)\",\"\",[0],[False],[None],Default,[])] Redirect(System.String)",
" [AspectMethodInsertBefore(\"System.Web.HttpResponse::Redirect(System.String,System.Boolean)\",\"\",[1],[False],[None],Default,[])] Redirect(System.String)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ internal interface IJsonElement
object Parent { get; }

public string GetString();

public string GetRawText();
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ public static object Parse(string json, JsonDocumentOptions options)
}

/// <summary>
/// GetString and GetRawText method aspect
/// GetString method aspect
/// Taint the string result when the parent is tainted
/// </summary>
/// <param name="target">the JsonElement instance</param>
/// <returns>the string result</returns>
[AspectMethodReplace("System.Text.Json.JsonElement::GetString()", [0], [true])]
[AspectMethodReplace("System.Text.Json.JsonElement::GetRawText()", [0], [true])]
public static string? GetString(object target)
{
IJsonElement? element;
Expand Down Expand Up @@ -86,6 +85,45 @@ public static object Parse(string json, JsonDocumentOptions options)
return str;
}

/// <summary>
/// GetRawText method aspect
/// Taint the raw string result when the parent is tainted
/// </summary>
/// <param name="target">the JsonElement instance</param>
/// <returns>the raw string result</returns>
[AspectMethodReplace("System.Text.Json.JsonElement::GetRawText()", [0], [true])]
public static string? GetRawText(object target)
{
IJsonElement? element;
try
{
element = target.DuckCast<IJsonElement>();
}
catch (Exception ex)
{
Log.Warning(ex, "Error casting to IJsonElement");
return null;
}

var str = element.GetRawText();

try
{
var taintedObjects = IastModule.GetIastContext()?.GetTaintedObjects();
var taintedTarget = taintedObjects?.Get(element.Parent);
if (taintedObjects is not null && taintedTarget is not null)
{
taintedObjects.Taint(str, [new Range(0, str.Length)]);
}
}
catch (Exception ex)
{
Log.Warning(ex, "Error tainting JsonElement.GetRawText result");
}

return str;
}

private static void TaintJsonElements(string json, JsonDocument doc)
{
var taintedObjects = IastModule.GetIastContext()?.GetTaintedObjects();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public void GivenASimpleJson_WhenParsing_GetProperty_GetRawText_Vulnerable()
var value = element.GetProperty("key");
var str = value.GetRawText();

Assert.Equal("value", str);
Assert.Equal("\"value\"", str);
AssertTainted(str);
}

Expand Down

0 comments on commit 18d5da4

Please sign in to comment.