mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #513 from calumgrant/cs/cwe-134
C#: New query cs/uncontrolled-format-string
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
| Using a package with a known vulnerability (cs/use-of-vulnerable-package) | security, external/cwe/cwe-937 | Finds project build files that import packages with known vulnerabilities. This is included by default. |
|
||||
|
||||
| Uncontrolled format string (cs/uncontrolled-format-string) | security, external/cwe/cwe-134 | Finds data flow from remote inputs to the format string in `String.Format`. This is included by default. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Passing untrusted format strings to <code>String.Format</code> can throw exceptions
|
||||
and cause a denial of service. For example, if the format string references a missing argument,
|
||||
or an argument of the wrong type, then <code>System.FormatException</code> is thrown.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>Use a string literal for the format string to prevent the possibility of data flow from
|
||||
an untrusted source. This also helps to prevent errors where the arguments to
|
||||
<code>String.Format</code> do not match the format string.</p>
|
||||
|
||||
<p>If the format string cannot be constant, ensure that it comes from a secure
|
||||
data source or is compiled into the source code.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>In this example, the format string is read from an HTTP request, which could cause
|
||||
the application to crash.</p>
|
||||
|
||||
<sample src="UncontrolledFormatStringBad.cs" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://www.owasp.org/index.php/Format_string_attack">Format string attack</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Microsoft docs:
|
||||
<a href="https://docs.microsoft.com/en-us/dotnet/api/system.string.format">String.Format Method</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @name Uncontrolled format string
|
||||
* @description Passing untrusted format strings from remote data sources can throw exceptions
|
||||
* and cause a denial of service.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id cs/uncontrolled-format-string
|
||||
* @tags security
|
||||
* external/cwe/cwe-134
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.dataflow.TaintTracking
|
||||
import semmle.code.csharp.frameworks.Format
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class FormatStringConfiguration extends TaintTracking::Configuration {
|
||||
FormatStringConfiguration() { this = "FormatStringConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink.asExpr() = any(FormatCall call).getFormatExpr()
|
||||
}
|
||||
}
|
||||
|
||||
from FormatStringConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"$@ flows to here and is used as a format string.", source.getNode(), source.getNode().toString()
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Web;
|
||||
|
||||
public class HttpHandler : IHttpHandler
|
||||
{
|
||||
string Surname, Forenames, FormattedName;
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string format = ctx.Request.QueryString["nameformat"];
|
||||
|
||||
// BAD: Uncontrolled format string.
|
||||
FormattedName = string.Format(format, Surname, Forenames);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/System.Web.cs
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
|
||||
public class TaintedPathHandler : IHttpHandler
|
||||
{
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
String path = ctx.Request.QueryString["page"];
|
||||
|
||||
// BAD: Uncontrolled format string.
|
||||
String.Format(path, "Do not do this");
|
||||
|
||||
// BAD: Using an IFormatProvider.
|
||||
String.Format((IFormatProvider)null, path, "Do not do this");
|
||||
|
||||
// GOOD: Not the format string.
|
||||
String.Format("Do not do this", path);
|
||||
|
||||
// GOOD: Not the format string.
|
||||
String.Format((IFormatProvider)null, "Do not do this", path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
edges
|
||||
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
|
||||
nodes
|
||||
| UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString |
|
||||
| UncontrolledFormatString.cs:14:23:14:26 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:17:46:17:49 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:20:23:20:38 | "Do not do this" |
|
||||
| UncontrolledFormatString.cs:23:46:23:61 | "Do not do this" |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString |
|
||||
| UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
|
||||
#select
|
||||
| UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString |
|
||||
| UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString |
|
||||
| UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | $@ flows to here and is used as a format string. | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | access to property QueryString |
|
||||
@@ -0,0 +1 @@
|
||||
Security Features/CWE-134/UncontrolledFormatString.ql
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Web;
|
||||
|
||||
public class HttpHandler : IHttpHandler
|
||||
{
|
||||
string Surname, Forenames, FormattedName;
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
string format = ctx.Request.QueryString["nameformat"];
|
||||
|
||||
// BAD: Uncontrolled format string.
|
||||
FormattedName = string.Format(format, Surname, Forenames);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user