mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge from master and resolve conflicts
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
The <code>requestValidationMode</code> attribute in ASP.NET is used to configure built-in validation to
|
||||
protect applications against code injections. Downgrading or disabling
|
||||
this configuration is not recommended. The default value of 4.5
|
||||
is the only recommended value, as previous versions only test a subset of requests.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Always set <code>requestValidationMode</code> to 4.5, or leave it at its default value.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following example shows the <code>requestValidationMode</code>
|
||||
attribute set to a value of 4.0, which disables some protections and
|
||||
ignores individual <code>Page</code> directives:
|
||||
</p>
|
||||
|
||||
<sample src="ASPNetRequestValidationModeBad.config" />
|
||||
|
||||
<p>
|
||||
Setting the value to 4.5 enables request validation for all requests:
|
||||
</p>
|
||||
|
||||
<sample src="ASPNetRequestValidationModeGood.config" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
Microsoft:
|
||||
<a
|
||||
href="https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.httpruntimesection.requestvalidationmode?view=netframework-4.8">HttpRuntimeSection.RequestValidationMode Property
|
||||
</a>.
|
||||
</li>
|
||||
<li>
|
||||
OWASP:
|
||||
<a
|
||||
href="https://www.owasp.org/index.php/ASP.NET_Request_Validation">ASP.NET Request Validation</a>.
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Insecure configuration for ASP.NET requestValidationMode
|
||||
* @description Setting 'requestValidationMode' to less than 4.5 disables built-in validations
|
||||
* included by default in ASP.NET. Disabling or downgrading this protection is not
|
||||
* recommended.
|
||||
* @kind problem
|
||||
* @id cs/insecure-request-validation-mode
|
||||
* @problem.severity warning
|
||||
* @tags security
|
||||
* external/cwe/cwe-016
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from XMLAttribute reqValidationMode
|
||||
where
|
||||
reqValidationMode.getName().toLowerCase() = "requestvalidationmode" and
|
||||
reqValidationMode.getValue().toFloat() < 4.5
|
||||
select reqValidationMode,
|
||||
"Insecure value for requestValidationMode (" + reqValidationMode.getValue() + ")."
|
||||
@@ -0,0 +1,5 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime requestValidationMode="4.0"/>
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,5 @@
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime requestValidationMode="4.5"/>
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -510,13 +510,20 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
ParameterNode p, ReturnNode ret, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough1(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
exists(ParameterNode p, ReturnNode ret |
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind() and
|
||||
simpleArgumentFlowsThrough0(p, ret, kind, t, config) and
|
||||
viableParamArg(call, p, arg)
|
||||
)
|
||||
}
|
||||
@@ -534,7 +541,7 @@ private predicate simpleArgumentFlowsThrough(
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
not inBarrier(out, config) and
|
||||
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
|
||||
simpleArgumentFlowsThrough1(call, arg, kind, t, config) and
|
||||
out = getAnOutNode(call, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -510,13 +510,20 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
ParameterNode p, ReturnNode ret, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough1(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
exists(ParameterNode p, ReturnNode ret |
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind() and
|
||||
simpleArgumentFlowsThrough0(p, ret, kind, t, config) and
|
||||
viableParamArg(call, p, arg)
|
||||
)
|
||||
}
|
||||
@@ -534,7 +541,7 @@ private predicate simpleArgumentFlowsThrough(
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
not inBarrier(out, config) and
|
||||
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
|
||||
simpleArgumentFlowsThrough1(call, arg, kind, t, config) and
|
||||
out = getAnOutNode(call, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -510,13 +510,20 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
ParameterNode p, ReturnNode ret, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough1(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
exists(ParameterNode p, ReturnNode ret |
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind() and
|
||||
simpleArgumentFlowsThrough0(p, ret, kind, t, config) and
|
||||
viableParamArg(call, p, arg)
|
||||
)
|
||||
}
|
||||
@@ -534,7 +541,7 @@ private predicate simpleArgumentFlowsThrough(
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
not inBarrier(out, config) and
|
||||
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
|
||||
simpleArgumentFlowsThrough1(call, arg, kind, t, config) and
|
||||
out = getAnOutNode(call, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -510,13 +510,20 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
ParameterNode p, ReturnNode ret, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough1(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
exists(ParameterNode p, ReturnNode ret |
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind() and
|
||||
simpleArgumentFlowsThrough0(p, ret, kind, t, config) and
|
||||
viableParamArg(call, p, arg)
|
||||
)
|
||||
}
|
||||
@@ -534,7 +541,7 @@ private predicate simpleArgumentFlowsThrough(
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
not inBarrier(out, config) and
|
||||
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
|
||||
simpleArgumentFlowsThrough1(call, arg, kind, t, config) and
|
||||
out = getAnOutNode(call, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -510,13 +510,20 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
ParameterNode p, ReturnNode ret, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough1(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
exists(ParameterNode p, ReturnNode ret |
|
||||
simpleParameterFlow(p, ret, t, config) and
|
||||
kind = ret.getKind() and
|
||||
simpleArgumentFlowsThrough0(p, ret, kind, t, config) and
|
||||
viableParamArg(call, p, arg)
|
||||
)
|
||||
}
|
||||
@@ -534,7 +541,7 @@ private predicate simpleArgumentFlowsThrough(
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
not inBarrier(out, config) and
|
||||
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
|
||||
simpleArgumentFlowsThrough1(call, arg, kind, t, config) and
|
||||
out = getAnOutNode(call, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ private module ImplCommon {
|
||||
*/
|
||||
cached
|
||||
predicate read(Node node1, Content f, Node node2) {
|
||||
readStep(node1, f, node2) and storeStep(_, f, _)
|
||||
readStep(node1, f, node2)
|
||||
or
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
read0(call, kind, node1, f) and
|
||||
|
||||
@@ -113,6 +113,12 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
)
|
||||
or
|
||||
e2 = any(OperatorCall oc |
|
||||
oc.getTarget().(ConversionOperator).fromLibrary() and
|
||||
e1 = oc.getAnArgument() and
|
||||
isSuccessor = true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -190,10 +190,16 @@ private module Internal {
|
||||
abstract RuntimeCallable getADynamicTarget();
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasOverrider(OverridableCallable oc, ValueOrRefType t) {
|
||||
exists(oc.getAnOverrider(t))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasCallable(OverridableCallable source, ValueOrRefType t, OverridableCallable c) {
|
||||
c.getSourceDeclaration() = source and
|
||||
t.hasCallable(c) and
|
||||
hasOverrider(c, t) and
|
||||
hasQualifierTypeOverridden0(t, _) and
|
||||
hasQualifierTypeOverridden1(source, _)
|
||||
}
|
||||
@@ -215,15 +221,19 @@ private module Internal {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasQualifierTypeOverridden0(ValueOrRefType t, DispatchMethodOrAccessorCall call) {
|
||||
exists(Type t0 | t0 = getAPossibleType(call.getQualifier(), false) |
|
||||
t = t0
|
||||
hasOverrider(_, t) and
|
||||
(
|
||||
exists(Type t0 | t0 = getAPossibleType(call.getQualifier(), false) |
|
||||
t = t0
|
||||
or
|
||||
Unification::subsumes(t0, t)
|
||||
or
|
||||
t = t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()
|
||||
)
|
||||
or
|
||||
Unification::subsumes(t0, t)
|
||||
or
|
||||
t = t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()
|
||||
constrainedTypeParameterQualifierTypeSubsumes(t,
|
||||
getAConstrainedTypeParameterQualifierType(call))
|
||||
)
|
||||
or
|
||||
constrainedTypeParameterQualifierTypeSubsumes(t, getAConstrainedTypeParameterQualifierType(call))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
|
||||
@@ -359,24 +359,25 @@ class Instruction extends Construction::TInstruction {
|
||||
*/
|
||||
int getDisplayIndexInBlock() {
|
||||
exists(IRBlock block |
|
||||
block = getBlock() and
|
||||
(
|
||||
exists(int index, int phiCount |
|
||||
phiCount = count(block.getAPhiInstruction()) and
|
||||
this = block.getInstruction(index) and
|
||||
result = index + phiCount
|
||||
this = block.getInstruction(result)
|
||||
or
|
||||
this = rank[-result - 1](PhiInstruction phiInstr |
|
||||
phiInstr = block.getAPhiInstruction()
|
||||
|
|
||||
phiInstr order by phiInstr.getUniqueId()
|
||||
)
|
||||
or
|
||||
this instanceof PhiInstruction and
|
||||
this = rank[result + 1](PhiInstruction phiInstr |
|
||||
phiInstr = block.getAPhiInstruction()
|
||||
|
|
||||
phiInstr order by phiInstr.getUniqueId()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private int getLineRank() {
|
||||
this = rank[result](Instruction instr |
|
||||
instr.getAST().getFile() = getAST().getFile() and
|
||||
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine()
|
||||
|
|
||||
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a human-readable string that uniquely identifies this instruction
|
||||
* within the function. This string is used to refer to this instruction when
|
||||
@@ -385,8 +386,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* Example: `r1_1`
|
||||
*/
|
||||
string getResultId() {
|
||||
result = getResultPrefix() + getBlock().getDisplayIndex().toString() + "_" +
|
||||
getDisplayIndexInBlock().toString()
|
||||
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -359,24 +359,25 @@ class Instruction extends Construction::TInstruction {
|
||||
*/
|
||||
int getDisplayIndexInBlock() {
|
||||
exists(IRBlock block |
|
||||
block = getBlock() and
|
||||
(
|
||||
exists(int index, int phiCount |
|
||||
phiCount = count(block.getAPhiInstruction()) and
|
||||
this = block.getInstruction(index) and
|
||||
result = index + phiCount
|
||||
this = block.getInstruction(result)
|
||||
or
|
||||
this = rank[-result - 1](PhiInstruction phiInstr |
|
||||
phiInstr = block.getAPhiInstruction()
|
||||
|
|
||||
phiInstr order by phiInstr.getUniqueId()
|
||||
)
|
||||
or
|
||||
this instanceof PhiInstruction and
|
||||
this = rank[result + 1](PhiInstruction phiInstr |
|
||||
phiInstr = block.getAPhiInstruction()
|
||||
|
|
||||
phiInstr order by phiInstr.getUniqueId()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private int getLineRank() {
|
||||
this = rank[result](Instruction instr |
|
||||
instr.getAST().getFile() = getAST().getFile() and
|
||||
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine()
|
||||
|
|
||||
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a human-readable string that uniquely identifies this instruction
|
||||
* within the function. This string is used to refer to this instruction when
|
||||
@@ -385,8 +386,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* Example: `r1_1`
|
||||
*/
|
||||
string getResultId() {
|
||||
result = getResultPrefix() + getBlock().getDisplayIndex().toString() + "_" +
|
||||
getDisplayIndexInBlock().toString()
|
||||
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import AliasAnalysis
|
||||
private import SimpleSSAImports
|
||||
import SimpleSSAPublicImports
|
||||
|
||||
private class IntValue = Ints::IntValue;
|
||||
|
||||
|
||||
@@ -2,4 +2,3 @@ import semmle.code.csharp.ir.implementation.raw.IR
|
||||
import semmle.code.csharp.ir.internal.IntegerConstant as Ints
|
||||
import semmle.code.csharp.ir.implementation.internal.OperandTag
|
||||
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
|
||||
import semmle.code.csharp.ir.internal.Overlap
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.code.csharp.ir.internal.Overlap
|
||||
Reference in New Issue
Block a user