mirror of
https://github.com/github/codeql.git
synced 2026-06-12 08:21:09 +02:00
Convert C# qlref tests to inline expectations
This commit is contained in:
committed by
GitHub
parent
27c62aa9b7
commit
d590687904
@@ -2,7 +2,7 @@
|
||||
|
||||
<div>
|
||||
<p>Value from InputText: @Value</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p> @* $ Alert[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<h3>Route parameter</h3>
|
||||
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
|
||||
<p>Parameter from URL: @UrlParam</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p> @* $ Alert[cs/web/xss]=r2 $ Alert[cs/web/xss]=r2 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -17,7 +17,7 @@
|
||||
<h3>Query parameter</h3>
|
||||
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
|
||||
<p>Parameter from query string: @QueryParam</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p> @* $ Alert[cs/web/xss]=r3 $ Alert[cs/web/xss]=r3 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<MyOutput Value="@QueryParam" />
|
||||
<MyOutput Value="@QueryParam" /> @* $ Source[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div>
|
||||
<p>Value from InputText: @Value</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p> @* $ Alert[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<h3>Route parameter</h3>
|
||||
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
|
||||
<p>Parameter from URL: @UrlParam</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p> @* $ Alert[cs/web/xss]=r2 $ Alert[cs/web/xss]=r2 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -17,7 +17,7 @@
|
||||
<h3>Query parameter</h3>
|
||||
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
|
||||
<p>Parameter from query string: @QueryParam</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p> @* $ Alert[cs/web/xss]=r3 $ Alert[cs/web/xss]=r3 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<MyOutput Value="@QueryParam" />
|
||||
<MyOutput Value="@QueryParam" /> @* $ Source[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div>
|
||||
<p>Value from InputText: @Value</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p>
|
||||
<p>Raw value from InputText: @(new MarkupString(Value))</p> @* $ Alert[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<h3>Route parameter</h3>
|
||||
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
|
||||
<p>Parameter from URL: @UrlParam</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
|
||||
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p> @* $ Alert[cs/web/xss]=r2 $ Alert[cs/web/xss]=r2 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -17,7 +17,7 @@
|
||||
<h3>Query parameter</h3>
|
||||
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
|
||||
<p>Parameter from query string: @QueryParam</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
|
||||
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p> @* $ Alert[cs/web/xss]=r3 $ Alert[cs/web/xss]=r3 *@
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<MyOutput Value="@QueryParam" />
|
||||
<MyOutput Value="@QueryParam" /> @* $ Source[cs/web/xss]=r1 *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -135,7 +135,7 @@ UrlParam
|
||||
__builder.AddContent(18, "Raw parameter from URL: ");
|
||||
__builder.AddContent(19,
|
||||
#nullable restore
|
||||
(MarkupString)UrlParam
|
||||
(MarkupString)UrlParam // $ Alert[cs/web/xss]=r1 $ Alert[cs/web/xss]=r1
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
@@ -185,7 +185,7 @@ QueryParam
|
||||
__builder.AddContent(35, "Raw parameter from query string: ");
|
||||
__builder.AddContent(36,
|
||||
#nullable restore
|
||||
new MarkupString(QueryParam)
|
||||
new MarkupString(QueryParam) // $ Alert[cs/web/xss]=r2 $ Alert[cs/web/xss]=r2
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace VulnerableBlazorApp.Components
|
||||
{
|
||||
builder.OpenElement(0, "div");
|
||||
builder.OpenElement(1, "p");
|
||||
builder.AddContent(2, (MarkupString)TheName);
|
||||
builder.AddContent(2, (MarkupString)TheName); // $ Alert[cs/web/xss]=r3 $ Alert[cs/web/xss]=r4
|
||||
builder.CloseElement();
|
||||
builder.CloseElement();
|
||||
}
|
||||
@@ -19,4 +19,4 @@ namespace VulnerableBlazorApp.Components
|
||||
[Parameter]
|
||||
public string TheName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace VulnerableBlazorApp.Components
|
||||
builder.OpenElement(6, "p");
|
||||
builder.AddContent(7, "Name: ");
|
||||
builder.OpenComponent<VulnerableBlazorApp.Components.Name>(8);
|
||||
builder.AddComponentParameter(9, nameof(VulnerableBlazorApp.Components.Name.TheName), Name);
|
||||
builder.AddComponentParameter(9, nameof(VulnerableBlazorApp.Components.Name.TheName), Name); // $ Source[cs/web/xss]=r4
|
||||
builder.CloseComponent();
|
||||
builder.CloseElement();
|
||||
}
|
||||
@@ -47,4 +47,4 @@ namespace VulnerableBlazorApp.Components
|
||||
|
||||
public List<string> Names { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace VulnerableBlazorApp.Components
|
||||
builder.OpenElement(6, "p");
|
||||
builder.AddContent(7, "Name: ");
|
||||
builder.OpenComponent<VulnerableBlazorApp.Components.Name>(8);
|
||||
builder.AddComponentParameter(9, "TheName", Name);
|
||||
builder.AddComponentParameter(9, "TheName", Name); // $ Source[cs/web/xss]=r3
|
||||
builder.CloseComponent();
|
||||
builder.CloseElement();
|
||||
}
|
||||
@@ -47,4 +47,4 @@ namespace VulnerableBlazorApp.Components
|
||||
|
||||
public List<string> Names { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: ASP/BlockCodeResponseWrite.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>2 + 3 = <%Response.Write(2 + 3)%></p>
|
||||
<p>2 + 3 = <%Response.Write(2 + 3)%></p> <%-- $ Alert[cs/asp/response-write] --%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>2 + 3 = <%Response.Write(2 + 3)%></p>
|
||||
<p>2 + 3 = <%Response.Write(2 + 3)%></p> <%-- $ Alert[cs/asp/response-write] --%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: ASP/ComplexInlineCode.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
} else {
|
||||
ec.Emit (Response, OpCodes.Ldloca, builder);
|
||||
}
|
||||
%>
|
||||
%> <%-- $ Alert[cs/asp/complex-inline-code] --%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Response.write(3 + 2);
|
||||
}
|
||||
End If
|
||||
%></p>
|
||||
%></p> <%-- $ Alert[cs/asp/complex-inline-code] --%>
|
||||
<p>2 + 3 = <%=2 + 3%></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: ASP/NonInternationalizedText.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>Amount: <%= Amount %></p>
|
||||
<p>Amount: <%= Amount %></p> <%-- $ Alert[cs/asp/text-not-internationalized] --%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This text is plain English.</p>
|
||||
<p>This text is plain English.</p> <%-- $ Alert[cs/asp/text-not-internationalized] --%>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: ASP/SplitControlStructure.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<% If ShouldWarn() Then %>
|
||||
<% If ShouldWarn() Then %> <%-- $ Alert[cs/asp/split-control-structure] --%>
|
||||
<p>WARNING: <%=warning()%></p>
|
||||
<% End If %>
|
||||
</body>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<% If Something() Then %>
|
||||
<% If Something() Then %> <%-- $ Alert[cs/asp/split-control-structure] --%>
|
||||
<p>2 + 3 = <%=2 + 3%></p>
|
||||
<% End If %>
|
||||
</body>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Configuration/EmptyPasswordInConfigurationFile.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Configuration/PasswordInConfigurationFile.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<sample>
|
||||
<db pwd=""/>
|
||||
<db pwd="foo"/>
|
||||
<db pwd=""/> <!-- $ Alert[cs/empty-password-in-configuration] -->
|
||||
<db pwd="foo"/> <!-- $ Alert[cs/password-in-configuration] -->
|
||||
<db dwp=""/>
|
||||
<db dwp="foo"/>
|
||||
<db Password=""/>
|
||||
<db Password="foo"/>
|
||||
<db Password=""/> <!-- $ Alert[cs/empty-password-in-configuration] -->
|
||||
<db Password="foo"/> <!-- $ Alert[cs/password-in-configuration] -->
|
||||
<db drowssaP=""/>
|
||||
<db drowssaP="foo"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;pwd=;"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;password=;"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;pwd=foo;"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;password=foo;"/>
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;pwd=;"/> <!-- $ Alert[cs/empty-password-in-configuration] -->
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;password=;"/> <!-- $ Alert[cs/empty-password-in-configuration] -->
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;pwd=foo;"/> <!-- $ Alert[cs/password-in-configuration] -->
|
||||
<db connectionString="Driver=ODBCDriver;server=ODBCServer;password=foo;"/> <!-- $ Alert[cs/password-in-configuration] -->
|
||||
</sample>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-011/ASPNetDebug.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
<compilation
|
||||
defaultLanguage="c#"
|
||||
debug="true"
|
||||
/>
|
||||
/> <!-- $ Alert[cs/web/debug-binary] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
<compilation
|
||||
defaultLanguage="c#"
|
||||
debug="true"
|
||||
/>
|
||||
/> <!-- $ Alert[cs/web/debug-binary] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-016/ASPNetMaxRequestLength.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime maxRequestLength="262144" />
|
||||
<httpRuntime maxRequestLength="262144" /> <!-- $ Alert[cs/web/large-max-request-length] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-016/ASPNetPagesValidateRequest.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<pages validateRequest="false" />
|
||||
<pages validateRequest="false" /> <!-- $ Alert[cs/web/request-validation-disabled] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-016/ASPNetRequestValidationMode.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime requestValidationMode="4.0"/>
|
||||
<httpRuntime requestValidationMode="4.0"/> <!-- $ Alert[cs/insecure-request-validation-mode] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
|
||||
@@ -6,11 +6,11 @@ public class UntrustedData : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
var name = ctx.Request.QueryString["name"];
|
||||
var name = ctx.Request.QueryString["name"]; // $ Alert[cs/untrusted-data-to-external-api]=r1 $ Alert[cs/untrusted-data-to-external-api]=r1 $ Source[cs/untrusted-data-to-external-api]=r2
|
||||
var len = name.Length;
|
||||
|
||||
var myEncodedString = HttpUtility.HtmlEncode(name);
|
||||
ctx.Response.Write(name);
|
||||
ctx.Response.Write(name); // $ Alert[cs/untrusted-data-to-external-api]=r2
|
||||
}
|
||||
|
||||
public bool IsReusable => true;
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-020/UntrustedDataToExternalAPI.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -7,14 +7,14 @@ public class TaintedPathHandler : IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
String path = ctx.Request.QueryString["page"];
|
||||
String path = ctx.Request.QueryString["page"]; // $ Source[cs/path-injection]=r1 $ Source[cs/path-injection]=r2 $ Source[cs/path-injection]=r3 $ Source[cs/path-injection]=r4 $ Source[cs/path-injection]=r5 $ Source[cs/path-injection]=r6 $ Source[cs/path-injection]=r7
|
||||
// BAD: Used via a File.Create... call.
|
||||
using (StreamWriter sw = File.CreateText(path))
|
||||
using (StreamWriter sw = File.CreateText(path)) // $ Alert[cs/path-injection]=r1
|
||||
{
|
||||
sw.WriteLine("Hello");
|
||||
}
|
||||
// BAD: Used via StreamWriter constructor
|
||||
using (StreamWriter sw = new StreamWriter(path))
|
||||
using (StreamWriter sw = new StreamWriter(path)) // $ Alert[cs/path-injection]=r2
|
||||
{
|
||||
sw.WriteLine("Hello");
|
||||
}
|
||||
@@ -22,20 +22,20 @@ public class TaintedPathHandler : IHttpHandler
|
||||
// BAD: Check is insufficient, text is read.
|
||||
if (!path.StartsWith("../"))
|
||||
{
|
||||
File.ReadAllText(path);
|
||||
File.ReadAllText(path); // $ Alert[cs/path-injection]=r3
|
||||
}
|
||||
|
||||
// BAD: Check is insufficient, text is read.
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
File.ReadAllText(path);
|
||||
File.ReadAllText(path); // $ Alert[cs/path-injection]=r4
|
||||
}
|
||||
|
||||
// BAD: Check is insufficient, text is read.
|
||||
string badPath = "/home/user/" + path;
|
||||
if (File.Exists(badPath))
|
||||
if (File.Exists(badPath)) // $ Alert[cs/path-injection]=r5
|
||||
{
|
||||
ctx.Response.Write(File.ReadAllText(badPath));
|
||||
ctx.Response.Write(File.ReadAllText(badPath)); // $ Alert[cs/path-injection]=r6
|
||||
}
|
||||
|
||||
// GOOD: Tainted path is passed through MapPath
|
||||
@@ -48,7 +48,7 @@ public class TaintedPathHandler : IHttpHandler
|
||||
File.ReadAllText(path);
|
||||
}
|
||||
|
||||
Directory.Exists(path);
|
||||
Directory.Exists(path); // $ Alert[cs/path-injection]=r7
|
||||
|
||||
// GOOD: A Guid.
|
||||
File.ReadAllText(new Guid(path).ToString());
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
query: Security Features/CWE-022/TaintedPath.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
|
||||
@@ -12,15 +12,15 @@ namespace ZipSlip
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
string fullPath = Path.GetFullPath(entry.FullName);
|
||||
string fullPath = Path.GetFullPath(entry.FullName); // $ Alert[cs/zipslip]=r1 $ Alert[cs/zipslip]=r2 $ Alert[cs/zipslip]=r3
|
||||
string fileName = Path.GetFileName(entry.FullName);
|
||||
string filename = entry.Name;
|
||||
string file = entry.FullName;
|
||||
string file = entry.FullName; // $ Alert[cs/zipslip]=r4
|
||||
if (!string.IsNullOrEmpty(file))
|
||||
{
|
||||
// BAD
|
||||
string destFileName = Path.Combine(destDirectory, file);
|
||||
entry.ExtractToFile(destFileName, true);
|
||||
entry.ExtractToFile(destFileName, true); // $ Sink[cs/zipslip]=r4
|
||||
|
||||
// GOOD
|
||||
string sanitizedFileName = Path.Combine(destDirectory, fileName);
|
||||
@@ -28,15 +28,15 @@ namespace ZipSlip
|
||||
|
||||
// BAD
|
||||
string destFilePath = Path.Combine(destDirectory, fullPath);
|
||||
entry.ExtractToFile(destFilePath, true);
|
||||
entry.ExtractToFile(destFilePath, true); // $ Sink[cs/zipslip]=r1
|
||||
|
||||
// BAD: destFilePath isn't fully resolved, so may still contain ..
|
||||
if (destFilePath.StartsWith(destDirectory))
|
||||
entry.ExtractToFile(destFilePath, true);
|
||||
entry.ExtractToFile(destFilePath, true); // $ Sink[cs/zipslip]=r2
|
||||
|
||||
// BAD
|
||||
destFilePath = Path.GetFullPath(Path.Combine(destDirectory, fullPath));
|
||||
entry.ExtractToFile(destFilePath, true);
|
||||
entry.ExtractToFile(destFilePath, true); // $ Sink[cs/zipslip]=r3
|
||||
|
||||
// GOOD: a check for StartsWith against a fully resolved path
|
||||
if (destFilePath.StartsWith(destDirectory))
|
||||
@@ -58,28 +58,28 @@ namespace ZipSlip
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
// figure out where we are putting the file
|
||||
String destFilePath = Path.Combine(InstallDir, entry.FullName);
|
||||
String destFilePath = Path.Combine(InstallDir, entry.FullName); // $ Alert[cs/zipslip]=r5 $ Alert[cs/zipslip]=r6 $ Alert[cs/zipslip]=r7 $ Alert[cs/zipslip]=r8
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
|
||||
|
||||
using (Stream archiveFileStream = entry.Open())
|
||||
{
|
||||
// BAD: writing to file stream
|
||||
using (Stream tfsFileStream = new FileStream(destFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
||||
using (Stream tfsFileStream = new FileStream(destFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) // $ Sink[cs/zipslip]=r5
|
||||
{
|
||||
Console.WriteLine(@"Writing ""{0}""", destFilePath);
|
||||
archiveFileStream.CopyTo(tfsFileStream);
|
||||
}
|
||||
|
||||
// BAD: can do it this way too
|
||||
using (Stream tfsFileStream = File.Create(destFilePath))
|
||||
using (Stream tfsFileStream = File.Create(destFilePath)) // $ Sink[cs/zipslip]=r6
|
||||
{
|
||||
Console.WriteLine(@"Writing ""{0}""", destFilePath);
|
||||
archiveFileStream.CopyTo(tfsFileStream);
|
||||
}
|
||||
|
||||
// BAD: creating stream using fileInfo
|
||||
var fileInfo = new FileInfo(destFilePath);
|
||||
var fileInfo = new FileInfo(destFilePath); // $ Sink[cs/zipslip]=r7
|
||||
using (FileStream fs = fileInfo.OpenWrite())
|
||||
{
|
||||
Console.WriteLine(@"Writing ""{0}""", destFilePath);
|
||||
@@ -87,7 +87,7 @@ namespace ZipSlip
|
||||
}
|
||||
|
||||
// BAD: creating stream using fileInfo
|
||||
var fileInfo1 = new FileInfo(destFilePath);
|
||||
var fileInfo1 = new FileInfo(destFilePath); // $ Sink[cs/zipslip]=r8
|
||||
using (FileStream fs = fileInfo1.Open(FileMode.Create))
|
||||
{
|
||||
Console.WriteLine(@"Writing ""{0}""", destFilePath);
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-022/ZipSlip.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -6,7 +6,7 @@ class Bad
|
||||
public static void WriteToDirectory(ZipArchiveEntry entry,
|
||||
string destDirectory)
|
||||
{
|
||||
string destFileName = Path.Combine(destDirectory, entry.FullName);
|
||||
entry.ExtractToFile(destFileName);
|
||||
string destFileName = Path.Combine(destDirectory, entry.FullName); // $ Alert[cs/zipslip]=r9
|
||||
entry.ExtractToFile(destFileName); // $ Sink[cs/zipslip]=r9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@ namespace Test
|
||||
public void WebCommandInjection()
|
||||
{
|
||||
// BAD: Reading from textbox, then using that in the arguments and file name
|
||||
string userInput = categoryTextBox.Text;
|
||||
Process.Start("foo.exe" + userInput, "/c " + userInput);
|
||||
string userInput = categoryTextBox.Text; // $ Source[cs/command-line-injection]=r1 $ Source[cs/command-line-injection]=r2 $ Source[cs/command-line-injection]=r3 $ Source[cs/command-line-injection]=r4 $ Source[cs/command-line-injection]=r5 $ Source[cs/command-line-injection]=r6 $ Source[cs/command-line-injection]=r7
|
||||
Process.Start("foo.exe" + userInput, "/c " + userInput); // $ Alert[cs/command-line-injection]=r1 $ Alert[cs/command-line-injection]=r2
|
||||
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(userInput, userInput);
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(userInput, userInput); // $ Alert[cs/command-line-injection]=r3 $ Alert[cs/command-line-injection]=r4
|
||||
Process.Start(startInfo);
|
||||
|
||||
ProcessStartInfo startInfoProps = new ProcessStartInfo();
|
||||
startInfoProps.FileName = userInput;
|
||||
startInfoProps.Arguments = userInput;
|
||||
startInfoProps.WorkingDirectory = userInput;
|
||||
startInfoProps.FileName = userInput; // $ Alert[cs/command-line-injection]=r5
|
||||
startInfoProps.Arguments = userInput; // $ Alert[cs/command-line-injection]=r6
|
||||
startInfoProps.WorkingDirectory = userInput; // $ Alert[cs/command-line-injection]=r7
|
||||
Process.Start(startInfoProps);
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@ namespace Test
|
||||
{
|
||||
connection.Open();
|
||||
SqlCommand customerCommand = new SqlCommand("SELECT * FROM customers", connection);
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader();
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader(); // $ Source[cs/command-line-injection]=r8
|
||||
|
||||
while (customerReader.Read())
|
||||
{
|
||||
// BAD: Read from database, and use it to directly execute a command
|
||||
Process.Start("foo.exe", "/c " + customerReader.GetString(1));
|
||||
Process.Start("foo.exe", "/c " + customerReader.GetString(1)); // $ Alert[cs/command-line-injection]=r8
|
||||
}
|
||||
customerReader.Close();
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-078/CommandInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace Test
|
||||
{
|
||||
connection.Open();
|
||||
SqlCommand customerCommand = new SqlCommand("SELECT * FROM customers", connection);
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader();
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader(); // $ Source[cs/web/xss]=r1
|
||||
|
||||
while (customerReader.Read())
|
||||
{
|
||||
// BAD: Read from database, write it straight to a response
|
||||
context.Response.Write("Orders for " + customerReader.GetString(1));
|
||||
context.Response.Write("Orders for " + customerReader.GetString(1)); // $ Alert[cs/web/xss]=r1
|
||||
}
|
||||
customerReader.Close();
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace Test
|
||||
{
|
||||
// BAD: Reading from textbox, then writing an amended value to a control that does not HTML encode
|
||||
StringBuilder userInput = new StringBuilder();
|
||||
userInput.AppendFormat("{0} test", categoryTextBox.Text);
|
||||
calendar.Caption = userInput.ToString();
|
||||
table.Caption = userInput.ToString();
|
||||
label.Text = userInput.ToString();
|
||||
userInput.AppendFormat("{0} test", categoryTextBox.Text); // $ Source[cs/web/xss]=r1 $ Source[cs/web/xss]=r2 $ Source[cs/web/xss]=r3
|
||||
calendar.Caption = userInput.ToString(); // $ Alert[cs/web/xss]=r1
|
||||
table.Caption = userInput.ToString(); // $ Alert[cs/web/xss]=r2
|
||||
label.Text = userInput.ToString(); // $ Alert[cs/web/xss]=r3
|
||||
|
||||
// GOOD: Reading from textbox, then writing an amended value to a control that does HTML encode
|
||||
categoryTextBox.Text = userInput.ToString();
|
||||
@@ -35,8 +35,8 @@ namespace Test
|
||||
public void processRequest(HttpContext context)
|
||||
{
|
||||
// BAD: Read user input from a request, write it straight to a response
|
||||
string name = context.Request.QueryString["name"];
|
||||
context.Response.Write(name);
|
||||
string name = context.Request.QueryString["name"]; // $ Source[cs/web/xss]=r4
|
||||
context.Response.Write(name); // $ Alert[cs/web/xss]=r4
|
||||
|
||||
// GOOD: Read user input from a request, but encode it before writing to the response
|
||||
string name2 = context.Request.QueryString["name"];
|
||||
@@ -55,9 +55,9 @@ namespace Test
|
||||
public void mvcProcess(HttpContext context)
|
||||
{
|
||||
// BAD: Mimic what happens in cshtml pages
|
||||
string name = context.Request.Unvalidated.QueryString["name"];
|
||||
string name = context.Request.Unvalidated.QueryString["name"]; // $ Source[cs/web/xss]=r5
|
||||
HtmlHelper html = new HtmlHelper(null, null);
|
||||
html.Raw(name);
|
||||
html.Raw(name); // $ Alert[cs/web/xss]=r5
|
||||
}
|
||||
|
||||
public void listener(HttpContext context)
|
||||
@@ -73,27 +73,27 @@ namespace Test
|
||||
public void contextBase(HttpContextBase context)
|
||||
{
|
||||
// BAD: Writing user input directly to a HttpListenerResponse
|
||||
string name = context.Request.QueryString["name"];
|
||||
context.Response.Write(name);
|
||||
string name = context.Request.QueryString["name"]; // $ Source[cs/web/xss]=r6
|
||||
context.Response.Write(name); // $ Alert[cs/web/xss]=r6
|
||||
// BAD: Writing user input directly to a HttpListenerResponse
|
||||
string name2 = context.Request["name"];
|
||||
context.Response.Write(name2);
|
||||
string name2 = context.Request["name"]; // $ Source[cs/web/xss]=r7
|
||||
context.Response.Write(name2); // $ Alert[cs/web/xss]=r7
|
||||
}
|
||||
|
||||
public void htmlStrings(HttpContextBase context)
|
||||
{
|
||||
// BAD: Writing user input into a HtmlString without encoding
|
||||
string name = context.Request.QueryString["name"];
|
||||
new HtmlString(name);
|
||||
new MvcHtmlString(name);
|
||||
string name = context.Request.QueryString["name"]; // $ Source[cs/web/xss]=r8 $ Source[cs/web/xss]=r9
|
||||
new HtmlString(name); // $ Alert[cs/web/xss]=r8
|
||||
new MvcHtmlString(name); // $ Alert[cs/web/xss]=r9
|
||||
new MyHtmlString(context.Request);
|
||||
}
|
||||
|
||||
public void WebContent(HttpContextBase context)
|
||||
{
|
||||
// BAD: Writing user input into a StringContent without encoding
|
||||
string name = context.Request.QueryString["name"];
|
||||
new StringContent(name);
|
||||
string name = context.Request.QueryString["name"]; // $ Source[cs/web/xss]=r10
|
||||
new StringContent(name); // $ Alert[cs/web/xss]=r10
|
||||
}
|
||||
|
||||
public void HtmlEncoded(HttpContextBase context)
|
||||
@@ -137,7 +137,7 @@ namespace Test
|
||||
|
||||
public string ToHtmlString()
|
||||
{
|
||||
return Request.RawUrl;
|
||||
return Request.RawUrl; // $ Alert[cs/web/xss]=r11 $ Alert[cs/web/xss]=r11
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
</script>
|
||||
|
||||
<script>
|
||||
<%= Request %>
|
||||
<%= Request %> <%-- $ Alert[cs/web/xss]=r12 $ Alert[cs/web/xss]=r12 --%>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
<%= Request.QueryString["name"] %>
|
||||
<%= Request.QueryString["name"] %> <%-- $ Alert[cs/web/xss]=r13 $ Alert[cs/web/xss]=r13 --%>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
<%= Request.QueryString["name"].Trim() %>
|
||||
<%= Request.QueryString["name"].Trim() %> <%-- $ Alert[cs/web/xss]=r14 $ Alert[cs/web/xss]=r14 --%>
|
||||
</script>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,36 +9,36 @@ public class LDAPInjectionHandler : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string userName = ctx.Request.QueryString["username"];
|
||||
string userName = ctx.Request.QueryString["username"]; // $ Source[cs/ldap-injection]=r1 $ Source[cs/ldap-injection]=r2 $ Source[cs/ldap-injection]=r3 $ Source[cs/ldap-injection]=r4 $ Source[cs/ldap-injection]=r5 $ Source[cs/ldap-injection]=r6
|
||||
|
||||
// BAD: Filter includes user input without encoding
|
||||
DirectorySearcher ds = new DirectorySearcher("accountname=" + userName);
|
||||
DirectorySearcher ds = new DirectorySearcher("accountname=" + userName); // $ Alert[cs/ldap-injection]=r1
|
||||
DirectorySearcher ds2 = new DirectorySearcher();
|
||||
ds.Filter = "accountname=" + userName;
|
||||
ds.Filter = "accountname=" + userName; // $ Alert[cs/ldap-injection]=r2
|
||||
|
||||
// GOOD: Filter includes user input with encoding
|
||||
DirectorySearcher ds3 = new DirectorySearcher("accountname=" + LDAPEncode(userName));
|
||||
|
||||
// BAD: SearchRequest Filter includes user input without encoding
|
||||
SearchRequest sr = new SearchRequest();
|
||||
sr.Filter = "accountname=" + userName;
|
||||
SearchRequest sr2 = new SearchRequest(null, "accountname=" + userName, System.DirectoryServices.Protocols.SearchScope.Base, null);
|
||||
sr.Filter = "accountname=" + userName; // $ Alert[cs/ldap-injection]=r3
|
||||
SearchRequest sr2 = new SearchRequest(null, "accountname=" + userName, System.DirectoryServices.Protocols.SearchScope.Base, null); // $ Alert[cs/ldap-injection]=r4
|
||||
|
||||
// BAD: Distinguished Name includes user input without encoding
|
||||
DirectoryEntry de = new DirectoryEntry("LDAP://Cn=" + userName);
|
||||
DirectoryEntry de = new DirectoryEntry("LDAP://Cn=" + userName); // $ Alert[cs/ldap-injection]=r5
|
||||
DirectoryEntry de2 = new DirectoryEntry();
|
||||
de2.Path = "LDAP://Cn=" + userName;
|
||||
de2.Path = "LDAP://Cn=" + userName; // $ Alert[cs/ldap-injection]=r6
|
||||
|
||||
using (SqlConnection connection = new SqlConnection(""))
|
||||
{
|
||||
connection.Open();
|
||||
SqlCommand customerCommand = new SqlCommand("SELECT * FROM customers", connection);
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader();
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader(); // $ Source[cs/ldap-injection]=r7
|
||||
|
||||
while (customerReader.Read())
|
||||
{
|
||||
// BAD: Read from database, write it straight to a response
|
||||
DirectorySearcher ds4 = new DirectorySearcher("accountname=" + customerReader.GetString(1));
|
||||
DirectorySearcher ds4 = new DirectorySearcher("accountname=" + customerReader.GetString(1)); // $ Alert[cs/ldap-injection]=r7
|
||||
}
|
||||
customerReader.Close();
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-090/LDAPInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -5,14 +5,14 @@ using System.Xml;
|
||||
|
||||
public class XMLInjectionHandler : IHttpHandler {
|
||||
public void ProcessRequest(HttpContext ctx) {
|
||||
string employeeName = ctx.Request.QueryString["employeeName"];
|
||||
string employeeName = ctx.Request.QueryString["employeeName"]; // $ Source[cs/xml-injection]=r1
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create("employees.xml"))
|
||||
{
|
||||
writer.WriteStartDocument();
|
||||
|
||||
// BAD: Insert user input directly into XML
|
||||
writer.WriteRaw("<employee><name>" + employeeName + "</name></employee>");
|
||||
writer.WriteRaw("<employee><name>" + employeeName + "</name></employee>"); // $ Alert[cs/xml-injection]=r1
|
||||
|
||||
// GOOD: Escape user input before inserting into string
|
||||
writer.WriteRaw("<employee><name>" + SecurityElement.Escape(employeeName) + "</name></employee>");
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-091/XMLInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -20,13 +20,13 @@ public class CommandInjectionHandler : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string code = ctx.Request.QueryString["code"];
|
||||
string code = ctx.Request.QueryString["code"]; // $ Source[cs/code-injection]=r1 $ Source[cs/code-injection]=r2
|
||||
CSharpCodeProvider c = new CSharpCodeProvider();
|
||||
ICodeCompiler icc = c.CreateCompiler();
|
||||
|
||||
CompilerParameters cp = new CompilerParameters();
|
||||
// BAD: Compiling unvalidated code from the user
|
||||
CompilerResults cr = icc.CompileAssemblyFromSource(cp, code);
|
||||
CompilerResults cr = icc.CompileAssemblyFromSource(cp, code); // $ Alert[cs/code-injection]=r1
|
||||
|
||||
System.Reflection.Assembly a = cr.CompiledAssembly;
|
||||
object o = a.CreateInstance("MyNamespace.MyClass");
|
||||
@@ -37,7 +37,7 @@ public class CommandInjectionHandler : IHttpHandler
|
||||
object s = mi.Invoke(o, null);
|
||||
|
||||
// BAD: Use the Roslyn APIs to dynamically evaluate C#
|
||||
CSharpScript.EvaluateAsync(code);
|
||||
CSharpScript.EvaluateAsync(code); // $ Alert[cs/code-injection]=r2
|
||||
}
|
||||
|
||||
public bool IsReusable
|
||||
@@ -53,6 +53,6 @@ public class CommandInjectionHandler : IHttpHandler
|
||||
void OnButtonClicked()
|
||||
{
|
||||
// BAD: Use the Roslyn APIs to dynamically evaluate C#
|
||||
CSharpScript.EvaluateAsync(box1.Text);
|
||||
CSharpScript.EvaluateAsync(box1.Text); // $ Alert[cs/code-injection]=r3 $ Alert[cs/code-injection]=r3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-094/CodeInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -5,12 +5,12 @@ public class ResourceInjectionHandler : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string userName = ctx.Request.QueryString["userName"];
|
||||
string userName = ctx.Request.QueryString["userName"]; // $ Source[cs/resource-injection]=r1 $ Source[cs/resource-injection]=r2
|
||||
string connectionString = "server=(local);user id=" + userName + ";password= pass;";
|
||||
// BAD: Direct use of user input in a connection string for the constructor
|
||||
SqlConnection sqlConnection = new SqlConnection(connectionString);
|
||||
SqlConnection sqlConnection = new SqlConnection(connectionString); // $ Alert[cs/resource-injection]=r1
|
||||
// BAD: Direct use of user input assigned to a connection string property
|
||||
sqlConnection.ConnectionString = connectionString;
|
||||
sqlConnection.ConnectionString = connectionString; // $ Alert[cs/resource-injection]=r2
|
||||
// GOOD: Use SqlConnectionStringBuilder
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||
builder["Data Source"] = "(local)";
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-099/ResourceInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,22 +9,22 @@ public class MissingXMLValidationHandler : IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
String userProvidedXml = ctx.Request.QueryString["userProvidedXml"];
|
||||
String userProvidedXml = ctx.Request.QueryString["userProvidedXml"]; // $ Source[cs/xml/missing-validation]=r1 $ Source[cs/xml/missing-validation]=r2 $ Source[cs/xml/missing-validation]=r3 $ Source[cs/xml/missing-validation]=r4 $ Source[cs/xml/missing-validation]=r5
|
||||
|
||||
// BAD: User provided XML is processed without any validation,
|
||||
// because there is no settings instance configured.
|
||||
XmlReader.Create(new StringReader(userProvidedXml));
|
||||
XmlReader.Create(new StringReader(userProvidedXml)); // $ Alert[cs/xml/missing-validation]=r1
|
||||
|
||||
// BAD: User provided XML is processed without any validation,
|
||||
// because the settings instance does not specify the ValidationType
|
||||
XmlReaderSettings badSettings1 = new XmlReaderSettings();
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings1);
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings1); // $ Alert[cs/xml/missing-validation]=r2
|
||||
|
||||
// BAD: User provided XML is processed without any validation,
|
||||
// because the settings instance specifies DTD as the ValidationType
|
||||
XmlReaderSettings badSettings2 = new XmlReaderSettings();
|
||||
badSettings2.ValidationType = ValidationType.DTD;
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings2);
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings2); // $ Alert[cs/xml/missing-validation]=r3
|
||||
|
||||
// GOOD: User provided XML is processed with validation
|
||||
XmlReaderSettings goodSettings = new XmlReaderSettings();
|
||||
@@ -42,7 +42,7 @@ public class MissingXMLValidationHandler : IHttpHandler
|
||||
XmlSchemaSet sc2 = new XmlSchemaSet();
|
||||
sc2.Add("urn:my-schema", "my.xsd");
|
||||
goodSettings.Schemas = sc2;
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings3);
|
||||
XmlReader.Create(new StringReader(userProvidedXml), badSettings3); // $ Alert[cs/xml/missing-validation]=r4 $ Alert[cs/xml/missing-validation]=r5
|
||||
}
|
||||
|
||||
public bool IsReusable
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-112/MissingXMLValidation.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-114/AssemblyPathInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,10 +4,10 @@ using System.Reflection;
|
||||
|
||||
public class DLLInjectionHandler : IHttpHandler {
|
||||
public void ProcessRequest(HttpContext ctx) {
|
||||
string libraryName = ctx.Request.QueryString["libraryName"];
|
||||
string libraryName = ctx.Request.QueryString["libraryName"]; // $ Source[cs/assembly-path-injection]=r1
|
||||
|
||||
// BAD: Load DLL based on user input
|
||||
var badDLL = Assembly.LoadFile(libraryName);
|
||||
var badDLL = Assembly.LoadFile(libraryName); // $ Alert[cs/assembly-path-injection]=r1
|
||||
|
||||
// GOOD: Load DLL using fixed string
|
||||
var goodDLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
|
||||
|
||||
@@ -11,26 +11,26 @@ public class Handler : IHttpHandler
|
||||
try
|
||||
{
|
||||
var password = "123456";
|
||||
ctx.Response.Write(password); // BAD
|
||||
ctx.Response.Write(password); // BAD // $ Alert[cs/sensitive-data-transmission]=r1 $ Alert[cs/sensitive-data-transmission]=r1
|
||||
}
|
||||
catch (System.Data.SqlClient.SqlException ex)
|
||||
{
|
||||
ctx.Response.Write(ex.ToString()); // BAD
|
||||
ctx.Response.Write(ex.ToString()); // BAD // $ Alert[cs/sensitive-data-transmission]=r2 $ Alert[cs/sensitive-data-transmission]=r2
|
||||
}
|
||||
catch (DbException ex)
|
||||
{
|
||||
ctx.Response.Write(ex.Message); // BAD
|
||||
ctx.Response.Write(ex.ToString()); // BAD
|
||||
ctx.Response.Write(ex.Data["password"]); // BAD
|
||||
ctx.Response.Write(ex.Message); // BAD // $ Alert[cs/sensitive-data-transmission]=r3 $ Alert[cs/sensitive-data-transmission]=r3
|
||||
ctx.Response.Write(ex.ToString()); // BAD // $ Alert[cs/sensitive-data-transmission]=r4 $ Alert[cs/sensitive-data-transmission]=r4
|
||||
ctx.Response.Write(ex.Data["password"]); // BAD // $ Alert[cs/sensitive-data-transmission]=r5 $ Alert[cs/sensitive-data-transmission]=r5
|
||||
}
|
||||
}
|
||||
|
||||
void SendPasswordToEmail()
|
||||
{
|
||||
var p = GetField("password"); // p is now tainted
|
||||
var message = new MailMessage("from", "to", p, p); // BAD
|
||||
message.Body = "This is your password: " + p; // BAD
|
||||
message.Subject = p; // BAD
|
||||
var p = GetField("password"); // p is now tainted // $ Source[cs/sensitive-data-transmission]=r6 $ Source[cs/sensitive-data-transmission]=r7 $ Source[cs/sensitive-data-transmission]=r8 $ Source[cs/sensitive-data-transmission]=r9
|
||||
var message = new MailMessage("from", "to", p, p); // BAD // $ Alert[cs/sensitive-data-transmission]=r6 $ Alert[cs/sensitive-data-transmission]=r7
|
||||
message.Body = "This is your password: " + p; // BAD // $ Alert[cs/sensitive-data-transmission]=r8
|
||||
message.Subject = p; // BAD // $ Alert[cs/sensitive-data-transmission]=r9
|
||||
}
|
||||
|
||||
string GetField(string field)
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-201/ExposureInTransmittedData.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -16,11 +16,11 @@ public class StackTraceHandler : IHttpHandler
|
||||
catch (Exception ex)
|
||||
{
|
||||
// BAD: printing a stack trace back to the response
|
||||
ctx.Response.Write(ex.ToString());
|
||||
ctx.Response.Write(ex.ToString()); // $ Alert[cs/information-exposure-through-exception]=r1 $ Alert[cs/information-exposure-through-exception]=r1
|
||||
// BAD: implicitly printing a stack trace back to the response
|
||||
ctx.Response.Write(ex);
|
||||
ctx.Response.Write(ex); // $ Alert[cs/information-exposure-through-exception]=r2 $ Alert[cs/information-exposure-through-exception]=r2
|
||||
// BAD: writing StackTrace property to response
|
||||
ctx.Response.Write(ex.StackTrace);
|
||||
ctx.Response.Write(ex.StackTrace); // $ Alert[cs/information-exposure-through-exception]=r3 $ Alert[cs/information-exposure-through-exception]=r3
|
||||
// GOOD: writing Message property to response
|
||||
ctx.Response.Write(ex.Message);
|
||||
return;
|
||||
@@ -36,15 +36,15 @@ public class StackTraceHandler : IHttpHandler
|
||||
log("Exception occurred", ex);
|
||||
ctx.Response.Write("Exception occurred");
|
||||
|
||||
textBox.Text = ex.InnerException.StackTrace; // BAD
|
||||
textBox.Text = ex.StackTrace; // BAD
|
||||
textBox.Text = ex.ToString(); // BAD
|
||||
textBox.Text = ex.InnerException.StackTrace; // BAD // $ Alert[cs/information-exposure-through-exception]=r4 $ Alert[cs/information-exposure-through-exception]=r4
|
||||
textBox.Text = ex.StackTrace; // BAD // $ Alert[cs/information-exposure-through-exception]=r5 $ Alert[cs/information-exposure-through-exception]=r5
|
||||
textBox.Text = ex.ToString(); // BAD // $ Alert[cs/information-exposure-through-exception]=r6 $ Alert[cs/information-exposure-through-exception]=r6
|
||||
textBox.Text = ex.Message; // GOOD
|
||||
return;
|
||||
}
|
||||
|
||||
// BAD: printing a stack trace back to the response for a custom exception
|
||||
ctx.Response.Write(new MyException().ToString());
|
||||
ctx.Response.Write(new MyException().ToString()); // $ Alert[cs/information-exposure-through-exception]=r7 $ Alert[cs/information-exposure-through-exception]=r7
|
||||
}
|
||||
|
||||
class MyException : Exception
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-209/ExceptionInformationExposure.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<customErrors mode="Off">
|
||||
</customErrors>
|
||||
</customErrors> <!-- $ Alert[cs/web/missing-global-error-handler] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
|
||||
@@ -14,21 +14,21 @@ namespace HardcodedSymmetricEncryptionKey
|
||||
var a = new AesCryptoServiceProvider();
|
||||
|
||||
// BAD: explicit key assignment, hard-coded value
|
||||
a.Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
|
||||
a.Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }; // $ Alert[cs/hardcoded-key]=r1 $ Alert[cs/hardcoded-key]=r1
|
||||
|
||||
var b = new AesCryptoServiceProvider()
|
||||
{
|
||||
// BAD: explicit key assignment, hard-coded value
|
||||
Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }
|
||||
Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 } // $ Alert[cs/hardcoded-key]=r2 $ Alert[cs/hardcoded-key]=r2
|
||||
};
|
||||
|
||||
var c = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
|
||||
var c = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }; // $ Source[cs/hardcoded-key]=r3 $ Source[cs/hardcoded-key]=r4 $ Source[cs/hardcoded-key]=r5 $ Source[cs/hardcoded-key]=r6
|
||||
var d = c;
|
||||
|
||||
var byteArrayFromString = Encoding.UTF8.GetBytes("Hello, world: here is a very bad way to create a key");
|
||||
var byteArrayFromString = Encoding.UTF8.GetBytes("Hello, world: here is a very bad way to create a key"); // $ Source[cs/hardcoded-key]=r7
|
||||
|
||||
// BAD: key assignment via variable, from hard-coded value
|
||||
a.Key = d;
|
||||
a.Key = d; // $ Alert[cs/hardcoded-key]=r3
|
||||
|
||||
// GOOD (not really, but better than hard coding)
|
||||
a.Key = File.ReadAllBytes("secret.key");
|
||||
@@ -65,7 +65,7 @@ namespace HardcodedSymmetricEncryptionKey
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(password, IV), CryptoStreamMode.Write))
|
||||
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(password, IV), CryptoStreamMode.Write)) // $ Alert[cs/hardcoded-key]=r4
|
||||
{
|
||||
cs.Write(cipherText, 0, cipherText.Length);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace HardcodedSymmetricEncryptionKey
|
||||
return new AesManaged()
|
||||
{
|
||||
// BAD: assignment from parameter
|
||||
Key = key
|
||||
Key = key // $ Alert[cs/hardcoded-key]=r5
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace HardcodedSymmetricEncryptionKey
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
// BAD: flow of hardcoded key to CreateEncryptor constructor
|
||||
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(key, IV), CryptoStreamMode.Write))
|
||||
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(key, IV), CryptoStreamMode.Write)) // $ Alert[cs/hardcoded-key]=r6 $ Alert[cs/hardcoded-key]=r7
|
||||
{
|
||||
cs.Write(rawPlaintext, 0, rawPlaintext.Length);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-321/HardcodedEncryptionKey.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,9 +9,9 @@ public class InsecureRandomness
|
||||
public void RandomTest()
|
||||
{
|
||||
// BAD: Using insecure RNG to generate password
|
||||
string password = InsecureRandomString(10);
|
||||
password = InsecureRandomStringFromSelection(10);
|
||||
password = InsecureRandomStringFromIndexer(10);
|
||||
string password = InsecureRandomString(10); // $ Alert[cs/insecure-randomness]=r1
|
||||
password = InsecureRandomStringFromSelection(10); // $ Alert[cs/insecure-randomness]=r2
|
||||
password = InsecureRandomStringFromIndexer(10); // $ Alert[cs/insecure-randomness]=r3
|
||||
// IGNORE - do not track further than the first assignment to a tainted variable
|
||||
string passwd = password;
|
||||
// GOOD: Use cryptographically secure RNG
|
||||
@@ -25,7 +25,7 @@ public class InsecureRandomness
|
||||
byte[] data = new byte[1];
|
||||
while (result.Length < length)
|
||||
{
|
||||
data[0] = (byte)r.Next(97, 122);
|
||||
data[0] = (byte)r.Next(97, 122); // $ Source[cs/insecure-randomness]=r1
|
||||
result.Append(new ASCIIEncoding().GetString(data));
|
||||
}
|
||||
return result.ToString();
|
||||
@@ -57,7 +57,7 @@ public class InsecureRandomness
|
||||
Random r = new Random();
|
||||
while (result.Length < length)
|
||||
{
|
||||
result += letters[r.Next(3)];
|
||||
result += letters[r.Next(3)]; // $ Source[cs/insecure-randomness]=r2
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public class InsecureRandomness
|
||||
Random r = new Random();
|
||||
while (result.Length < length)
|
||||
{
|
||||
result += letters[r.Next(3)];
|
||||
result += letters[r.Next(3)]; // $ Source[cs/insecure-randomness]=r3
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class InsecureRandomness
|
||||
public static string BiasPasswordGeneration()
|
||||
{
|
||||
// BAD: Membership.GeneratePassword generates a password with a bias
|
||||
string password = System.Web.Security.Membership.GeneratePassword(12, 3);
|
||||
string password = System.Web.Security.Membership.GeneratePassword(12, 3); // $ Alert[cs/insecure-randomness]=r4 $ Alert[cs/insecure-randomness]=r4
|
||||
return password;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/InsecureRandomness.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,7 +4,7 @@ public class HomeController : Controller
|
||||
{
|
||||
// BAD: Anti forgery token has been forgotten
|
||||
[HttpPost]
|
||||
public ActionResult Login()
|
||||
public ActionResult Login() // $ Alert[cs/web/missing-token-validation]
|
||||
{
|
||||
return View();
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class DerivedUnprotectedController : UnprotectedBaseController
|
||||
{
|
||||
// BAD: No antiforgery validation on this or any base class
|
||||
[HttpPost]
|
||||
public ActionResult NoInheritedValidation()
|
||||
public ActionResult NoInheritedValidation() // $ Alert[cs/web/missing-token-validation]
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-352/MissingAntiForgeryTokenValidation.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-451/MissingXFrameOptions.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
</system.web>
|
||||
</configuration>
|
||||
</configuration> <!-- $ Alert[cs/web/missing-x-frame-options] -->
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-548/ASPNetDirectoryListing.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<directoryBrowse enabled="true" />
|
||||
<directoryBrowse enabled="true" /> <!-- $ Alert[cs/web/directory-browse-enabled] -->
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
||||
@@ -10,7 +10,7 @@ public class UrlRedirectHandler : IHttpHandler
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
// BAD: a request parameter is incorporated without validation into a URL redirect
|
||||
ctx.Response.Redirect(ctx.Request.QueryString["page"]);
|
||||
ctx.Response.Redirect(ctx.Request.QueryString["page"]); // $ Alert[cs/web/unvalidated-url-redirection]=r2 $ Alert[cs/web/unvalidated-url-redirection]=r2
|
||||
|
||||
// GOOD: the request parameter is validated against a known fixed string
|
||||
if (VALID_REDIRECT == ctx.Request.QueryString["page"])
|
||||
@@ -20,7 +20,7 @@ public class UrlRedirectHandler : IHttpHandler
|
||||
|
||||
// GOOD: We check whether this is a local URL before redirecting, using UrlHelper.
|
||||
// As recommended by https://docs.microsoft.com/en-us/aspnet/mvc/overview/security/preventing-open-redirection-attacks
|
||||
string url = ctx.Request.QueryString["page"];
|
||||
string url = ctx.Request.QueryString["page"]; // $ Source[cs/web/unvalidated-url-redirection]=r5 $ Source[cs/web/unvalidated-url-redirection]=r6 $ Source[cs/web/unvalidated-url-redirection]=r7 $ Source[cs/web/unvalidated-url-redirection]=r8
|
||||
if (new UrlHelper(null).IsLocalUrl(url))
|
||||
{
|
||||
ctx.Response.Redirect(url);
|
||||
@@ -35,8 +35,8 @@ public class UrlRedirectHandler : IHttpHandler
|
||||
}
|
||||
|
||||
// BAD: Adding or appending a header
|
||||
ctx.Response.AddHeader("Location", ctx.Request.QueryString["page"]);
|
||||
ctx.Response.AppendHeader("Location", ctx.Request.QueryString["page"]);
|
||||
ctx.Response.AddHeader("Location", ctx.Request.QueryString["page"]); // $ Alert[cs/web/unvalidated-url-redirection]=r3 $ Alert[cs/web/unvalidated-url-redirection]=r3
|
||||
ctx.Response.AppendHeader("Location", ctx.Request.QueryString["page"]); // $ Alert[cs/web/unvalidated-url-redirection]=r4 $ Alert[cs/web/unvalidated-url-redirection]=r4
|
||||
|
||||
// GOOD: Redirecting to the RawUrl only reloads the current Url
|
||||
ctx.Response.Redirect(ctx.Request.RawUrl);
|
||||
@@ -45,7 +45,7 @@ public class UrlRedirectHandler : IHttpHandler
|
||||
ctx.Response.Redirect("foo.asp?param=" + url);
|
||||
|
||||
// BAD: Using Transfer with unvalidated user input
|
||||
ctx.Server.Transfer(url);
|
||||
ctx.Server.Transfer(url); // $ Alert[cs/web/unvalidated-url-redirection]=r5
|
||||
|
||||
// GOOD: request parameter is URL encoded
|
||||
ctx.Response.Redirect(HttpUtility.UrlEncode(ctx.Request.QueryString["page"]));
|
||||
@@ -61,19 +61,19 @@ public class UrlRedirectHandler : IHttpHandler
|
||||
ctx.Response.Redirect($"foo.asp?param={url}");
|
||||
|
||||
// BAD: The attacker can control the location
|
||||
ctx.Response.Redirect($"{url}.asp?param=foo");
|
||||
ctx.Response.Redirect($"{url}.asp?param=foo"); // $ Alert[cs/web/unvalidated-url-redirection]=r6
|
||||
|
||||
// GOOD: The attacker can only control the parameters, not the location
|
||||
ctx.Response.Redirect(string.Format("foo.asp?param={0}", url));
|
||||
|
||||
// BAD: The attacker can control the location
|
||||
ctx.Response.Redirect(string.Format("{0}.asp?param=foo", url));
|
||||
ctx.Response.Redirect(string.Format("{0}.asp?param=foo", url)); // $ Alert[cs/web/unvalidated-url-redirection]=r7
|
||||
|
||||
// GOOD: The attacker can only control the parameters, not the location
|
||||
ctx.Response.Redirect(string.Format("foo.asp?{1}param={0}", url, url));
|
||||
|
||||
// BAD: The attacker can control the location
|
||||
ctx.Response.Redirect(string.Format("{1}.asp?{0}param=foo", url, url));
|
||||
ctx.Response.Redirect(string.Format("{1}.asp?{0}param=foo", url, url)); // $ Alert[cs/web/unvalidated-url-redirection]=r8
|
||||
}
|
||||
|
||||
// Implementation as recommended by Microsoft.
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-601/UrlRedirect.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -11,7 +11,7 @@ public class UrlRedirectHandler2 : IHttpHandler
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
// BAD: a request parameter is incorporated without validation into a URL redirect
|
||||
ctx.Response.Redirect(ctx.Request.QueryString["page"]);
|
||||
ctx.Response.Redirect(ctx.Request.QueryString["page"]); // $ Alert[cs/web/unvalidated-url-redirection]=r1 $ Alert[cs/web/unvalidated-url-redirection]=r1
|
||||
|
||||
var redirectUrl = ctx.Request.QueryString["page"];
|
||||
if (VALID_REDIRECTS.Contains(redirectUrl))
|
||||
|
||||
@@ -10,50 +10,50 @@ namespace Testing.Controllers
|
||||
private static string SomeValue = "HeaderValue";
|
||||
|
||||
[HttpPost]
|
||||
public void Post([FromBody] string value)
|
||||
public void Post([FromBody] string value) // $ Source[cs/web/unvalidated-url-redirection]=r9 $ Source[cs/web/unvalidated-url-redirection]=r10 $ Source[cs/web/unvalidated-url-redirection]=r11 $ Source[cs/web/unvalidated-url-redirection]=r12 $ Source[cs/web/unvalidated-url-redirection]=r13 $ Source[cs/web/unvalidated-url-redirection]=r14 $ Source[cs/web/unvalidated-url-redirection]=r15
|
||||
{
|
||||
// BAD: straight up controller redirect
|
||||
Redirect(value);
|
||||
Redirect(value); // $ Alert[cs/web/unvalidated-url-redirection]=r9
|
||||
|
||||
// BAD: Setting response headers collection, location = redirect
|
||||
Response.Headers["location"] = value;
|
||||
Response.Headers["location"] = value; // $ Alert[cs/web/unvalidated-url-redirection]=r10
|
||||
|
||||
// GOOD: Setting response header to a constant value
|
||||
Response.Headers["location"] = SomeValue;
|
||||
|
||||
// BAD: Setting response headers collection, location = redirect via add method
|
||||
Response.Headers.Add("location", value);
|
||||
Response.Headers.Add("location", value); // $ Alert[cs/web/unvalidated-url-redirection]=r11
|
||||
|
||||
// GOOD: Setting response header to a constant value
|
||||
Response.Headers.Add("location", "foo");
|
||||
|
||||
// BAD: redirect via location
|
||||
Response.Headers.SetCommaSeparatedValues("location", value);
|
||||
Response.Headers.SetCommaSeparatedValues("location", value); // $ Alert[cs/web/unvalidated-url-redirection]=r12
|
||||
|
||||
// BAD = redirect via setting location value from tainted source
|
||||
Response.Headers.Append("location", value);
|
||||
Response.Headers.Append("location", value); // $ Alert[cs/web/unvalidated-url-redirection]=r13
|
||||
|
||||
// BAD: redirect via setting location header from comma-separated values
|
||||
Response.Headers.AppendCommaSeparatedValues("location", value);
|
||||
Response.Headers.AppendCommaSeparatedValues("location", value); // $ Alert[cs/web/unvalidated-url-redirection]=r14
|
||||
|
||||
// BAD: tainted redirect to Action
|
||||
RedirectToActionPermanent("Error" + value);
|
||||
RedirectToActionPermanent("Error" + value); // $ Alert[cs/web/unvalidated-url-redirection]=r15
|
||||
}
|
||||
|
||||
// PUT: api/Some/5
|
||||
[HttpPut("{id}")]
|
||||
public void Put(int id, [FromBody] string value)
|
||||
public void Put(int id, [FromBody] string value) // $ Source[cs/web/unvalidated-url-redirection]=r16 $ Source[cs/web/unvalidated-url-redirection]=r17 $ Source[cs/web/unvalidated-url-redirection]=r18
|
||||
{
|
||||
|
||||
RedirectToPage(value);
|
||||
RedirectToPage(value); // $ Alert[cs/web/unvalidated-url-redirection]=r16
|
||||
|
||||
var headers = new ResponseHeaders(Response.Headers);
|
||||
|
||||
// BAD: redirect via header helper class
|
||||
headers.Location = new Uri(value);
|
||||
headers.Location = new Uri(value); // $ Alert[cs/web/unvalidated-url-redirection]=r17
|
||||
|
||||
// BAD: response redirect
|
||||
Response.Redirect(value);
|
||||
Response.Redirect(value); // $ Alert[cs/web/unvalidated-url-redirection]=r18
|
||||
|
||||
// GOOD: whitelisted redirect
|
||||
if(Url.IsLocalUrl(value))
|
||||
|
||||
@@ -8,7 +8,7 @@ public class XMLHandler : IHttpHandler
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
// BAD: XmlTextReader is insecure with these options, using user-provided data
|
||||
XmlTextReader reader = new XmlTextReader(ctx.Request.QueryString["document"]) { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() };
|
||||
XmlTextReader reader = new XmlTextReader(ctx.Request.QueryString["document"]) { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() }; // $ Alert[cs/xml/insecure-dtd-handling]=r1 $ Alert[cs/xml/insecure-dtd-handling]=r1 $ Alert[cs/insecure-xml-read]
|
||||
}
|
||||
|
||||
public void insecureXMLBad(string content)
|
||||
@@ -18,10 +18,10 @@ public class XMLHandler : IHttpHandler
|
||||
settings.XmlResolver = new XmlUrlResolver();
|
||||
|
||||
// BAD: insecure settings
|
||||
XmlReader reader1 = XmlReader.Create(content, settings);
|
||||
XmlReader reader1 = XmlReader.Create(content, settings); // $ Alert[cs/insecure-xml-read]
|
||||
|
||||
// BAD: XmlTextReader is insecure with these options
|
||||
XmlTextReader reader2 = new XmlTextReader(content) { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() };
|
||||
XmlTextReader reader2 = new XmlTextReader(content) { DtdProcessing = DtdProcessing.Parse, XmlResolver = new XmlUrlResolver() }; // $ Alert[cs/insecure-xml-read]
|
||||
}
|
||||
|
||||
public void insecureXMLGood(string content)
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-611/UntrustedDataInsecureXml.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-611/UseXmlSecureResolver.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-614/RequireSSL.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authentication>
|
||||
<forms />
|
||||
<forms /> <!-- $ Alert[cs/web/requiressl-not-set] -->
|
||||
</authentication>
|
||||
<httpCookies requireSSL="true"/>
|
||||
</system.web>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
query: Security Features/CWE-614/RequireSSL.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authentication>
|
||||
<forms />
|
||||
<forms /> <!-- $ Alert[cs/web/requiressl-not-set] -->
|
||||
</authentication>
|
||||
<httpCookies />
|
||||
<httpCookies /> <!-- $ Alert[cs/web/requiressl-not-set] -->
|
||||
</system.web>
|
||||
</configuration>
|
||||
|
||||
@@ -8,16 +8,16 @@ public class XPathInjectionHandler : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string userName = ctx.Request.QueryString["userName"];
|
||||
string password = ctx.Request.QueryString["password"];
|
||||
string userName = ctx.Request.QueryString["userName"]; // $ Source[cs/xml/xpath-injection]=r1 $ Source[cs/xml/xpath-injection]=r3 $ Source[cs/xml/xpath-injection]=r5 $ Source[cs/xml/xpath-injection]=r7 $ Source[cs/xml/xpath-injection]=r9 $ Source[cs/xml/xpath-injection]=r11 $ Source[cs/xml/xpath-injection]=r13
|
||||
string password = ctx.Request.QueryString["password"]; // $ Source[cs/xml/xpath-injection]=r2 $ Source[cs/xml/xpath-injection]=r4 $ Source[cs/xml/xpath-injection]=r6 $ Source[cs/xml/xpath-injection]=r8 $ Source[cs/xml/xpath-injection]=r10 $ Source[cs/xml/xpath-injection]=r12 $ Source[cs/xml/xpath-injection]=r14
|
||||
|
||||
var s = "//users/user[login/text()='" + userName + "' and password/text() = '" + password + "']/home_dir/text()";
|
||||
|
||||
// BAD: User input used directly in an XPath expression
|
||||
XPathExpression.Compile(s);
|
||||
XPathExpression.Compile(s); // $ Alert[cs/xml/xpath-injection]=r1 $ Alert[cs/xml/xpath-injection]=r2
|
||||
XmlNode xmlNode = null;
|
||||
// BAD: User input used directly in an XPath expression to SelectNodes
|
||||
xmlNode.SelectNodes(s);
|
||||
xmlNode.SelectNodes(s); // $ Alert[cs/xml/xpath-injection]=r3 $ Alert[cs/xml/xpath-injection]=r4
|
||||
|
||||
// GOOD: Uses parameters to avoid including user input directly in XPath expression
|
||||
var expr = XPathExpression.Compile("//users/user[login/text()=$username]/home_dir/text()");
|
||||
@@ -26,31 +26,31 @@ public class XPathInjectionHandler : IHttpHandler
|
||||
var nav = doc.CreateNavigator();
|
||||
|
||||
// BAD
|
||||
nav.Select(s);
|
||||
nav.Select(s); // $ Alert[cs/xml/xpath-injection]=r5 $ Alert[cs/xml/xpath-injection]=r6
|
||||
|
||||
// GOOD
|
||||
nav.Select(expr);
|
||||
|
||||
// BAD
|
||||
nav.SelectSingleNode(s);
|
||||
nav.SelectSingleNode(s); // $ Alert[cs/xml/xpath-injection]=r7 $ Alert[cs/xml/xpath-injection]=r8
|
||||
|
||||
// GOOD
|
||||
nav.SelectSingleNode(expr);
|
||||
|
||||
// BAD
|
||||
nav.Compile(s);
|
||||
nav.Compile(s); // $ Alert[cs/xml/xpath-injection]=r9 $ Alert[cs/xml/xpath-injection]=r10
|
||||
|
||||
// GOOD
|
||||
nav.Compile("//users/user[login/text()=$username]/home_dir/text()");
|
||||
|
||||
// BAD
|
||||
nav.Evaluate(s);
|
||||
nav.Evaluate(s); // $ Alert[cs/xml/xpath-injection]=r11 $ Alert[cs/xml/xpath-injection]=r12
|
||||
|
||||
// Good
|
||||
nav.Evaluate(expr);
|
||||
|
||||
// BAD
|
||||
nav.Matches(s);
|
||||
nav.Matches(s); // $ Alert[cs/xml/xpath-injection]=r13 $ Alert[cs/xml/xpath-injection]=r14
|
||||
|
||||
// GOOD
|
||||
nav.Matches(expr);
|
||||
@@ -71,17 +71,17 @@ public class XPathInjectionHandler : IHttpHandler
|
||||
{
|
||||
connection.Open();
|
||||
SqlCommand customerCommand = new SqlCommand("SELECT * FROM customers", connection);
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader();
|
||||
SqlDataReader customerReader = customerCommand.ExecuteReader(); // $ Source[cs/xml/xpath-injection]=r15 $ Source[cs/xml/xpath-injection]=r16
|
||||
|
||||
while (customerReader.Read())
|
||||
{
|
||||
string userName = customerReader.GetString(1);
|
||||
string password = customerReader.GetString(2);
|
||||
// BAD: User input used directly in an XPath expression
|
||||
XPathExpression.Compile("//users/user[login/text()='" + userName + "' and password/text() = '" + password + "']/home_dir/text()");
|
||||
XPathExpression.Compile("//users/user[login/text()='" + userName + "' and password/text() = '" + password + "']/home_dir/text()"); // $ Alert[cs/xml/xpath-injection]=r15
|
||||
XmlNode xmlNode = null;
|
||||
// BAD: User input used directly in an XPath expression to SelectNodes
|
||||
xmlNode.SelectNodes("//users/user[login/text()='" + userName + "' and password/text() = '" + password + "']/home_dir/text()");
|
||||
xmlNode.SelectNodes("//users/user[login/text()='" + userName + "' and password/text() = '" + password + "']/home_dir/text()"); // $ Alert[cs/xml/xpath-injection]=r16
|
||||
|
||||
// GOOD: Uses parameters to avoid including user input directly in XPath expression
|
||||
XPathExpression.Compile("//users/user[login/text()=$username]/home_dir/text()");
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-643/XPathInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -8,20 +8,20 @@ public class RegexHandler : IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string userInput = ctx.Request.QueryString["userInput"];
|
||||
string userInput = ctx.Request.QueryString["userInput"]; // $ Source[cs/redos]=r1 $ Source[cs/redos]=r2 $ Source[cs/redos]=r3 $ Source[cs/redos]=r4 $ Source[cs/redos]=r5
|
||||
|
||||
// BAD:
|
||||
// Artificial regexes
|
||||
new Regex("^([a-z]+)+$").Match(userInput);
|
||||
new Regex("^([a-z]*)*$").Replace(userInput, "");
|
||||
new Regex("^([a-z]+)+$").Match(userInput); // $ Alert[cs/redos]=r1
|
||||
new Regex("^([a-z]*)*$").Replace(userInput, ""); // $ Alert[cs/redos]=r2
|
||||
// Known exponential blowup regex for e-mail address validation
|
||||
// Problematic part is: ([a-zA-Z0-9]+))*
|
||||
new Regex("^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$").Match(userInput);
|
||||
new Regex("^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$").Match(userInput); // $ Alert[cs/redos]=r3
|
||||
// Known exponential blowup regex for Java class name validation
|
||||
// Problematic part is: (([a-z])+.)+
|
||||
new Regex(JAVA_CLASS_REGEX).Match(userInput);
|
||||
new Regex(JAVA_CLASS_REGEX).Match(userInput); // $ Alert[cs/redos]=r4
|
||||
// Static use
|
||||
Regex.Match(userInput, JAVA_CLASS_REGEX);
|
||||
Regex.Match(userInput, JAVA_CLASS_REGEX); // $ Alert[cs/redos]=r5
|
||||
// GOOD:
|
||||
new Regex("^(([a-b]+[c-z]+)+$").Match(userInput);
|
||||
new Regex("^([a-z]+)+$", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)).Match(userInput);
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-730/ReDoS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-730/ReDoS.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -7,11 +7,11 @@ public class RegexInjectionHandler : IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string regex = ctx.Request.QueryString["regex"];
|
||||
string regex = ctx.Request.QueryString["regex"]; // $ Source[cs/regex-injection]=r1
|
||||
string userInput = ctx.Request.QueryString["userInput"];
|
||||
|
||||
// BAD: User input used as regex
|
||||
new Regex(regex).Match(userInput);
|
||||
new Regex(regex).Match(userInput); // $ Alert[cs/regex-injection]=r1
|
||||
// GOOD: User input escaped before being used as regex
|
||||
new Regex(Regex.Escape(regex)).Match(userInput);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-730/RegexInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,22 +9,22 @@ public class ConditionalBypassHandler : IHttpHandler
|
||||
{
|
||||
string user = ctx.Request.QueryString["user"];
|
||||
string password = ctx.Request.QueryString["password"];
|
||||
string isAdmin = ctx.Request.QueryString["isAdmin"];
|
||||
string isAdmin = ctx.Request.QueryString["isAdmin"]; // $ Source[cs/user-controlled-bypass]=r1
|
||||
|
||||
// BAD: login is only executed if isAdmin is false, but isAdmin
|
||||
// is controlled by the user
|
||||
if (isAdmin == "false")
|
||||
if (isAdmin == "false") // $ Alert[cs/user-controlled-bypass]=r1
|
||||
login(user, password);
|
||||
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"];
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"]; // $ Source[cs/user-controlled-bypass]=r2 $ Source[cs/user-controlled-bypass]=r3 $ Source[cs/user-controlled-bypass]=r4
|
||||
// BAD: login is only executed if the cookie value is false, but the cookie
|
||||
// is controlled by the user
|
||||
if (adminCookie.Value.Equals("false"))
|
||||
if (adminCookie.Value.Equals("false")) // $ Alert[cs/user-controlled-bypass]=r2
|
||||
login(user, password);
|
||||
|
||||
// FALSE POSITIVES: both methods are conditionally executed, but they probably
|
||||
// both perform the security-critical action
|
||||
if (adminCookie.Value == "false")
|
||||
if (adminCookie.Value == "false") // $ Alert[cs/user-controlled-bypass]=r3 $ Alert[cs/user-controlled-bypass]=r4
|
||||
{
|
||||
login(user, password);
|
||||
}
|
||||
@@ -39,14 +39,14 @@ public class ConditionalBypassHandler : IHttpHandler
|
||||
|
||||
// BAD: DNS may be controlled by the user
|
||||
IPAddress hostIPAddress = IPAddress.Parse("1.2.3.4");
|
||||
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
|
||||
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress); // $ Source[cs/user-controlled-bypass]=r5 $ Source[cs/user-controlled-bypass]=r6
|
||||
// Exact comparison
|
||||
if (hostInfo.HostName == "trustme.com")
|
||||
if (hostInfo.HostName == "trustme.com") // $ Alert[cs/user-controlled-bypass]=r5
|
||||
{
|
||||
login(user, password);
|
||||
}
|
||||
// Substring comparison
|
||||
if (hostInfo.HostName.EndsWith("trustme.com"))
|
||||
if (hostInfo.HostName.EndsWith("trustme.com")) // $ Alert[cs/user-controlled-bypass]=r6
|
||||
{
|
||||
login(user, password);
|
||||
}
|
||||
@@ -67,9 +67,9 @@ public class ConditionalBypassHandler : IHttpHandler
|
||||
|
||||
public static void Test2(HttpContext ctx, String user, String password)
|
||||
{
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"];
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"]; // $ Source[cs/user-controlled-bypass]=r7
|
||||
// BAD: login may happen once or twice
|
||||
if (adminCookie.Value == "false")
|
||||
if (adminCookie.Value == "false") // $ Alert[cs/user-controlled-bypass]=r7
|
||||
login(user, password);
|
||||
else
|
||||
{
|
||||
@@ -80,8 +80,8 @@ public class ConditionalBypassHandler : IHttpHandler
|
||||
|
||||
public static void Test3(HttpContext ctx, String user, String password)
|
||||
{
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"];
|
||||
if (adminCookie.Value == "false")
|
||||
HttpCookie adminCookie = ctx.Request.Cookies["adminCookie"]; // $ Source[cs/user-controlled-bypass]=r8
|
||||
if (adminCookie.Value == "false") // $ Alert[cs/user-controlled-bypass]=r8
|
||||
login(user, password);
|
||||
else
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user