mirror of
https://github.com/github/codeql.git
synced 2026-06-15 18:01:10 +02:00
Compare commits
59 Commits
copilot/co
...
copilot/ch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f658bc9b39 | ||
|
|
8cb4b9b118 | ||
|
|
ab4f170780 | ||
|
|
14c72def96 | ||
|
|
d0841d2283 | ||
|
|
6934aa0e39 | ||
|
|
359e272577 | ||
|
|
daefaff969 | ||
|
|
4bc083fd7f | ||
|
|
89c1d66f90 | ||
|
|
b9670ef831 | ||
|
|
346d140c87 | ||
|
|
9f0feb467a | ||
|
|
ff61344afa | ||
|
|
fe8c029ac7 | ||
|
|
8d46bfcbd4 | ||
|
|
f0640d78d2 | ||
|
|
fb9e4a8c40 | ||
|
|
3c407f77a9 | ||
|
|
9465a1d063 | ||
|
|
072c4837d2 | ||
|
|
ee040da575 | ||
|
|
524330c188 | ||
|
|
7d54669696 | ||
|
|
951a26a01a | ||
|
|
2bbcc1e88c | ||
|
|
d101e45efc | ||
|
|
912dc9c0bd | ||
|
|
eea406f622 | ||
|
|
de7afcaec3 | ||
|
|
f3ec7087e3 | ||
|
|
bea5522473 | ||
|
|
eedef515f7 | ||
|
|
9078b511c6 | ||
|
|
1ac079d066 | ||
|
|
29b0c286a7 | ||
|
|
ad18659373 | ||
|
|
a4bf2b8f58 | ||
|
|
a375e186ed | ||
|
|
923fe2dcb9 | ||
|
|
642259cd51 | ||
|
|
0d984588f9 | ||
|
|
b4a9689341 | ||
|
|
6a8e20a0c8 | ||
|
|
4c411bbcb5 | ||
|
|
b60bf8c79f | ||
|
|
ef00aa2567 | ||
|
|
6d0968744b | ||
|
|
98f147556a | ||
|
|
3693185b6b | ||
|
|
1c1d26453d | ||
|
|
4c1a0058bf | ||
|
|
01173bf383 | ||
|
|
e93bc11f6f | ||
|
|
2884428b62 | ||
|
|
e10750b35e | ||
|
|
18550039f2 | ||
|
|
0caa483925 | ||
|
|
640b17ec78 |
@@ -59,9 +59,5 @@ MODULE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/rust.yml @github/codeql-rust
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
# Misc
|
||||
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL
|
||||
/misc/scripts/generate-code-scanning-query-list.py @RasmusWL
|
||||
|
||||
# .devcontainer
|
||||
/.devcontainer/ @github/codeql-ci-reviewers
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.
|
||||
@@ -2,10 +2,12 @@ import actions
|
||||
|
||||
bindingset[runner]
|
||||
predicate isGithubHostedRunner(string runner) {
|
||||
// list of github hosted repos: https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
runner
|
||||
.toLowerCase()
|
||||
.regexpMatch("^(ubuntu-([0-9.]+|latest)|macos-([0-9]+|latest)(-x?large)?|windows-([0-9.]+|latest))$")
|
||||
// The list of github hosted repos:
|
||||
// https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
// https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories
|
||||
runner.toLowerCase().regexpMatch("^ubuntu-([0-9.]+|latest|slim)(-arm)?$") or
|
||||
runner.toLowerCase().regexpMatch("^macos-([0-9]+|latest)(-x?large|-intel)?$") or
|
||||
runner.toLowerCase().regexpMatch("^windows-([0-9.]+|latest)(-vs[0-9.]+)?(-arm)?$")
|
||||
}
|
||||
|
||||
bindingset[runner]
|
||||
|
||||
43
actions/ql/test/query-tests/Security/CWE-284/.github/workflows/test3.yml
vendored
Normal file
43
actions/ql/test/query-tests/Security/CWE-284/.github/workflows/test3.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04
|
||||
- ubuntu-24.04-arm
|
||||
- ubuntu-22.04
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-26.04
|
||||
- ubuntu-26.04-arm
|
||||
- ubuntu-slim
|
||||
- macos-26
|
||||
- macos-26-xlarge
|
||||
- macos-26-intel
|
||||
- macos-26-large
|
||||
- macos-latest-large
|
||||
- macos-15-large
|
||||
- macos-15
|
||||
- macos-15-intel
|
||||
- macos-latest
|
||||
- macos-15
|
||||
- macos-15-xlarge
|
||||
- macos-14-large
|
||||
- macos-14
|
||||
- macos-14-xlarge
|
||||
- windows-2025-vs2026
|
||||
- windows-latest
|
||||
- windows-2025
|
||||
- windows-2022
|
||||
- windows-11
|
||||
- windows-11-arm
|
||||
- windows-11-vs2026-arm
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: cmd
|
||||
2578
cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
Normal file
2578
cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1071,7 +1071,7 @@ class NullPointerType extends BuiltInType {
|
||||
* const float fa[40];
|
||||
* ```
|
||||
*/
|
||||
class DerivedType extends Type, @derivedtype {
|
||||
class DerivedType extends Type, NameQualifyingElement, @derivedtype {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string getName() { derivedtypes(underlyingElement(this), result, _, _) }
|
||||
|
||||
@@ -1430,7 +1430,8 @@ specialnamequalifyingelements(
|
||||
@namequalifyingelement = @namespace
|
||||
| @specialnamequalifyingelement
|
||||
| @usertype
|
||||
| @decltype;
|
||||
| @decltype
|
||||
| @derivedtype;
|
||||
|
||||
namequalifiers(
|
||||
unique int id: @namequalifier,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1,3 +1,7 @@
|
||||
| inconsistency2.cpp:3:3:3:5 | T:: | inconsistency2.cpp:3:3:3:6 | x | inconsistency2.cpp:2:20:2:20 | T |
|
||||
| inconsistency2.cpp:3:3:3:11 | const s:: | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | (int)... | inconsistency.cpp:4:8:4:8 | S |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | A | inconsistency.cpp:4:8:4:8 | S |
|
||||
| name_qualifiers.cpp:29:7:29:8 | :: | name_qualifiers.cpp:29:7:29:9 | x | file://:0:0:0:0 | (global namespace) |
|
||||
| name_qualifiers.cpp:31:7:31:10 | N1:: | name_qualifiers.cpp:31:7:31:12 | nx | name_qualifiers.cpp:4:11:4:12 | N1 |
|
||||
| name_qualifiers.cpp:34:7:34:8 | :: | name_qualifiers.cpp:34:9:34:12 | N1:: | file://:0:0:0:0 | (global namespace) |
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import cpp
|
||||
|
||||
from NameQualifier nq, Location l
|
||||
where
|
||||
l = nq.getQualifiedElement().getLocation() and
|
||||
l.getFile().getShortName() = "name_qualifiers"
|
||||
where l = nq.getQualifiedElement().getLocation()
|
||||
select nq, nq.getQualifiedElement(), nq.getQualifyingElement()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// This file is present to test whether name-qualifying an enum constant leads to a database inconsistency.
|
||||
// As such, there is no QL part of the test.
|
||||
|
||||
|
||||
struct S { enum E { A }; };
|
||||
|
||||
static int f() {
|
||||
static void f() {
|
||||
switch(0) { case S::A: break; }
|
||||
}
|
||||
|
||||
12
cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp
Normal file
12
cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace {
|
||||
template <typename T> T f() {
|
||||
T::x;
|
||||
return {};
|
||||
}
|
||||
struct s {
|
||||
static int x;
|
||||
};
|
||||
struct t {
|
||||
s x = f<const s>();
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
|
||||
@@ -50,15 +50,15 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
|
|
||||
add instanceof AddOperation and
|
||||
e1.getAChild*() = add.getAnOperand() and
|
||||
e1 instanceof BinaryBitwiseOperation and
|
||||
e2 = e1.(BinaryBitwiseOperation).getLeftOperand() and
|
||||
e1 instanceof BinaryBitwiseExpr and
|
||||
e2 = e1.(BinaryBitwiseExpr).getLeftOperand() and
|
||||
v = addAssign.getTargetVariable() and
|
||||
addAssign.getAChild*() = add and
|
||||
(xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and
|
||||
addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and
|
||||
xorAssign.getAChild*() = xor and
|
||||
v = xorAssign.getTargetVariable() and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseExpr) and
|
||||
xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and
|
||||
notAssign.getAChild*() = notOp and
|
||||
v = notAssign.getTargetVariable() and
|
||||
|
||||
@@ -290,7 +290,7 @@ module AssignableInternal {
|
||||
newtype TAssignableDefinition =
|
||||
TAssignmentDefinition(Assignment a) {
|
||||
not a.getLeftOperand() instanceof TupleExpr and
|
||||
not a instanceof AssignCallOperation and
|
||||
not a instanceof AssignCallExpr and
|
||||
not a instanceof AssignCoalesceExpr
|
||||
} or
|
||||
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
|
||||
@@ -324,7 +324,7 @@ module AssignableInternal {
|
||||
TAddressOfDefinition(AddressOfExpr aoe) or
|
||||
TPatternDefinition(TopLevelPatternDecl tlpd) or
|
||||
TAssignOperationDefinition(AssignOperation ao) {
|
||||
ao instanceof AssignCallOperation and not ao instanceof CompoundAssignmentOperatorCall
|
||||
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
|
||||
or
|
||||
ao instanceof AssignCoalesceExpr
|
||||
}
|
||||
|
||||
@@ -912,18 +912,17 @@ module Internal {
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
exists(BinaryOperation bo, Expr o |
|
||||
bo instanceof BinaryArithmeticOperation or
|
||||
bo instanceof AssignArithmeticOperation
|
||||
|
|
||||
result = bo and
|
||||
bo.getAnOperand() = e and
|
||||
bo.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
result =
|
||||
any(BinaryArithmeticOperation bao |
|
||||
exists(Expr o |
|
||||
bao.getAnOperand() = e and
|
||||
bao.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -934,10 +933,10 @@ module Internal {
|
||||
any(QualifiableExpr qe |
|
||||
qe.isConditional() and
|
||||
result = qe.getQualifier()
|
||||
) or
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand()) or
|
||||
e = any(AssignArithmeticOperation aao | result = aao.getAnOperand())
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
|
||||
}
|
||||
|
||||
deprecated predicate isGuard(Expr e, GuardValue val) {
|
||||
|
||||
@@ -172,6 +172,10 @@ module Ast implements AstSig<Location> {
|
||||
|
||||
class DoStmt = CS::DoStmt;
|
||||
|
||||
class UntilStmt extends LoopStmt {
|
||||
UntilStmt() { none() }
|
||||
}
|
||||
|
||||
final private class FinalForStmt = CS::ForStmt;
|
||||
|
||||
class ForStmt extends FinalForStmt {
|
||||
@@ -203,7 +207,7 @@ module Ast implements AstSig<Location> {
|
||||
final private class FinalTryStmt = CS::TryStmt;
|
||||
|
||||
class TryStmt extends FinalTryStmt {
|
||||
Stmt getBody() { result = this.getBlock() }
|
||||
AstNode getBody(int index) { index = 0 and result = this.getBlock() }
|
||||
|
||||
CatchClause getCatch(int index) { result = this.getCatchClause(index) }
|
||||
|
||||
|
||||
@@ -124,9 +124,7 @@ private module Internal {
|
||||
TDispatchDynamicOperatorCall(DynamicOperatorCall doc) or
|
||||
TDispatchDynamicMemberAccess(DynamicMemberAccess dma) or
|
||||
TDispatchDynamicElementAccess(DynamicElementAccess dea) or
|
||||
TDispatchDynamicEventAccess(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
TDispatchDynamicEventAccess(AssignArithmeticExpr aao, DynamicMemberAccess dma, string name) {
|
||||
isPotentialEventCall(aao, dma, name)
|
||||
} or
|
||||
TDispatchDynamicObjectCreation(DynamicObjectCreation doc) or
|
||||
@@ -230,7 +228,7 @@ private module Internal {
|
||||
* accessor.
|
||||
*/
|
||||
private predicate isPotentialEventCall(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
AssignArithmeticExpr aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
aao instanceof DynamicOperatorCall and
|
||||
dma = aao.getLeftOperand() and
|
||||
@@ -1397,9 +1395,7 @@ private module Internal {
|
||||
private class DispatchDynamicEventAccess extends DispatchReflectionOrDynamicCall,
|
||||
TDispatchDynamicEventAccess
|
||||
{
|
||||
override AssignArithmeticOperation getCall() {
|
||||
this = TDispatchDynamicEventAccess(result, _, _)
|
||||
}
|
||||
override AssignArithmeticExpr getCall() { this = TDispatchDynamicEventAccess(result, _, _) }
|
||||
|
||||
override string getName() { this = TDispatchDynamicEventAccess(_, _, result) }
|
||||
|
||||
|
||||
@@ -11,19 +11,27 @@ import Expr
|
||||
* (`UnaryArithmeticOperation`) or a binary arithmetic operation
|
||||
* (`BinaryArithmeticOperation`).
|
||||
*/
|
||||
class ArithmeticOperation extends Operation, @arith_op_expr {
|
||||
class ArithmeticOperation extends Operation, @arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary arithmetic operation. Either a unary minus operation
|
||||
* (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
* A binary arithmetic operation. Either a binary arithmetic expression (`BinaryArithmeticExpr`) or
|
||||
* an arithmetic assignment expression (`AssignArithmeticExpr`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_op_expr { }
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary minus operation, for example `-x`.
|
||||
* A unary arithmetic operation. Either a unary minus expression
|
||||
* (`UnaryMinusExpr`), a unary plus expression (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_operation { }
|
||||
|
||||
/**
|
||||
* A unary minus expression, for example `-x`.
|
||||
*/
|
||||
class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -32,7 +40,7 @@ class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary plus operation, for example `+x`.
|
||||
* A unary plus expression, for example `+x`.
|
||||
*/
|
||||
class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -44,40 +52,40 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
* A mutator operation. Either an increment operation (`IncrementOperation`)
|
||||
* or a decrement operation (`DecrementOperation`).
|
||||
*/
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_op_expr { }
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_operation { }
|
||||
|
||||
/**
|
||||
* An increment operation. Either a postfix increment operation
|
||||
* (`PostIncrExpr`) or a prefix increment operation (`PreIncrExpr`).
|
||||
* An increment operation. Either a postfix increment expression
|
||||
* (`PostIncrExpr`) or a prefix increment expression (`PreIncrExpr`).
|
||||
*/
|
||||
class IncrementOperation extends MutatorOperation, @incr_op_expr {
|
||||
class IncrementOperation extends MutatorOperation, @incr_operation {
|
||||
override string getOperator() { result = "++" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A decrement operation. Either a postfix decrement operation
|
||||
* (`PostDecrExpr`) or a prefix decrement operation (`PreDecrExpr`).
|
||||
* A decrement operation. Either a postfix decrement expression
|
||||
* (`PostDecrExpr`) or a prefix decrement expression (`PreDecrExpr`).
|
||||
*/
|
||||
class DecrementOperation extends MutatorOperation, @decr_op_expr {
|
||||
class DecrementOperation extends MutatorOperation, @decr_operation {
|
||||
override string getOperator() { result = "--" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix increment operation, for example `++x`.
|
||||
* A prefix increment expression, for example `++x`.
|
||||
*/
|
||||
class PreIncrExpr extends IncrementOperation, @pre_incr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreIncrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix decrement operation, for example `--x`.
|
||||
* A prefix decrement expression, for example `--x`.
|
||||
*/
|
||||
class PreDecrExpr extends DecrementOperation, @pre_decr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreDecrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix increment operation, for example `x++`.
|
||||
* A postfix increment expression, for example `x++`.
|
||||
*/
|
||||
class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -86,7 +94,7 @@ class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix decrement operation, for example `x--`.
|
||||
* A postfix decrement expression, for example `x--`.
|
||||
*/
|
||||
class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -95,55 +103,84 @@ class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary arithmetic operation. Either an addition operation
|
||||
* (`AddExpr`), a subtraction operation (`SubExpr`), a multiplication
|
||||
* operation (`MulExpr`), a division operation (`DivExpr`), or a
|
||||
* remainder operation (`RemExpr`).
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_op_expr {
|
||||
override string getOperator() { none() }
|
||||
class AddOperation extends BinaryArithmeticOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryArithmeticOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryArithmeticOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryArithmeticOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An addition operation, for example `x + y`.
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticOperation, AddOperation, @add_expr {
|
||||
class RemOperation extends BinaryArithmeticOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A binary arithmetic expression. Either an addition expression
|
||||
* (`AddExpr`), a subtraction expression (`SubExpr`), a multiplication
|
||||
* expression (`MulExpr`), a division expression (`DivExpr`), or a
|
||||
* remainder expression (`RemExpr`).
|
||||
*/
|
||||
class BinaryArithmeticExpr extends BinaryArithmeticOperation, @bin_arith_expr { }
|
||||
|
||||
/**
|
||||
* An addition expression, for example `x + y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticExpr, AddOperation, @add_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction operation, for example `x - y`.
|
||||
* A subtraction expression, for example `x - y`.
|
||||
*/
|
||||
class SubExpr extends BinaryArithmeticOperation, SubOperation, @sub_expr {
|
||||
class SubExpr extends BinaryArithmeticExpr, SubOperation, @sub_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A multiplication operation, for example `x * y`.
|
||||
* A multiplication expression, for example `x * y`.
|
||||
*/
|
||||
class MulExpr extends BinaryArithmeticOperation, MulOperation, @mul_expr {
|
||||
class MulExpr extends BinaryArithmeticExpr, MulOperation, @mul_expr {
|
||||
override string getOperator() { result = "*" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A division operation, for example `x / y`.
|
||||
* A division expression, for example `x / y`.
|
||||
*/
|
||||
class DivExpr extends BinaryArithmeticOperation, DivOperation, @div_expr {
|
||||
class DivExpr extends BinaryArithmeticExpr, DivOperation, @div_expr {
|
||||
override string getOperator() { result = "/" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, for example `x % y`.
|
||||
* A remainder expression, for example `x % y`.
|
||||
*/
|
||||
class RemExpr extends BinaryArithmeticOperation, RemOperation, @rem_expr {
|
||||
class RemExpr extends BinaryArithmeticExpr, RemOperation, @rem_expr {
|
||||
override string getOperator() { result = "%" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RemExpr" }
|
||||
|
||||
@@ -72,9 +72,9 @@ class AssignExpr extends Assignment, @simple_assign_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* An assignment operation. Either an arithmetic assignment operation
|
||||
* (`AssignArithmeticOperation`), a bitwise assignment operation
|
||||
* (`AssignBitwiseOperation`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* An assignment operation. Either an arithmetic assignment expression
|
||||
* (`AssignArithmeticExpr`), a bitwise assignment expression
|
||||
* (`AssignBitwiseExpr`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* a null-coalescing assignment (`AssignCoalesceExpr`).
|
||||
*/
|
||||
class AssignOperation extends Assignment, @assign_op_expr {
|
||||
@@ -94,134 +94,147 @@ class AssignOperation extends Assignment, @assign_op_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A compound assignment operation that invokes an operator.
|
||||
* A compound assignment expression that invokes an operator.
|
||||
*
|
||||
* (1) `x += y` invokes the compound assignment operator `+=` (if it exists).
|
||||
* (2) `x += y` invokes the operator `+` and assigns `x + y` to `x`.
|
||||
*
|
||||
* Either an arithmetic assignment operation (`AssignArithmeticOperation`) or a bitwise
|
||||
* assignment operation (`AssignBitwiseOperation`).
|
||||
* Either an arithmetic assignment expression (`AssignArithmeticExpr`) or a bitwise
|
||||
* assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, QualifiableExpr,
|
||||
@assign_op_call_expr
|
||||
{
|
||||
class AssignCallExpr extends AssignOperation, OperatorCall, QualifiableExpr, @assign_op_call_expr {
|
||||
override string toString() { result = AssignOperation.super.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An arithmetic assignment operation. Either an addition assignment operation
|
||||
* (`AssignAddExpr`), a subtraction assignment operation (`AssignSubExpr`), a
|
||||
* multiplication assignment operation (`AssignMulExpr`), a division assignment
|
||||
* operation (`AssignDivExpr`), or a remainder assignment operation
|
||||
* (`AssignRemExpr`).
|
||||
* DEPRECATED: Use `AssignCallExpr` instead.
|
||||
*/
|
||||
class AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { }
|
||||
deprecated class AssignCallOperation = AssignCallExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment operation, for example `x += y`.
|
||||
* An arithmetic assignment expression. Either an addition assignment expression
|
||||
* (`AssignAddExpr`), a subtraction assignment expression (`AssignSubExpr`), a
|
||||
* multiplication assignment expression (`AssignMulExpr`), a division assignment
|
||||
* expression (`AssignDivExpr`), or a remainder assignment expression
|
||||
* (`AssignRemExpr`).
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticOperation, AddOperation, @assign_add_expr {
|
||||
class AssignArithmeticExpr extends AssignCallExpr, @assign_arith_expr { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `AssignArithmeticExpr` instead.
|
||||
*/
|
||||
deprecated class AssignArithmeticOperation = AssignArithmeticExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment expression, for example `x += y`.
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticExpr, AddOperation, @assign_add_expr {
|
||||
override string getOperator() { result = "+=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction assignment operation, for example `x -= y`.
|
||||
* A subtraction assignment expression, for example `x -= y`.
|
||||
*/
|
||||
class AssignSubExpr extends AssignArithmeticOperation, SubOperation, @assign_sub_expr {
|
||||
class AssignSubExpr extends AssignArithmeticExpr, SubOperation, @assign_sub_expr {
|
||||
override string getOperator() { result = "-=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignSubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An multiplication assignment operation, for example `x *= y`.
|
||||
* A multiplication assignment expression, for example `x *= y`.
|
||||
*/
|
||||
class AssignMulExpr extends AssignArithmeticOperation, MulOperation, @assign_mul_expr {
|
||||
class AssignMulExpr extends AssignArithmeticExpr, MulOperation, @assign_mul_expr {
|
||||
override string getOperator() { result = "*=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignMulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An division assignment operation, for example `x /= y`.
|
||||
* A division assignment expression, for example `x /= y`.
|
||||
*/
|
||||
class AssignDivExpr extends AssignArithmeticOperation, DivOperation, @assign_div_expr {
|
||||
class AssignDivExpr extends AssignArithmeticExpr, DivOperation, @assign_div_expr {
|
||||
override string getOperator() { result = "/=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignDivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder assignment operation, for example `x %= y`.
|
||||
* A remainder assignment expression, for example `x %= y`.
|
||||
*/
|
||||
class AssignRemExpr extends AssignArithmeticOperation, RemOperation, @assign_rem_expr {
|
||||
class AssignRemExpr extends AssignArithmeticExpr, RemOperation, @assign_rem_expr {
|
||||
override string getOperator() { result = "%=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRemExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise assignment operation. Either a bitwise-and assignment
|
||||
* operation (`AssignAndExpr`), a bitwise-or assignment
|
||||
* operation (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* operation (`AssignXorExpr`), a left-shift assignment
|
||||
* operation (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* operation (`AssignUnsignedRightShiftExpr`).
|
||||
* A bitwise assignment expression. Either a bitwise-and assignment
|
||||
* expression (`AssignAndExpr`), a bitwise-or assignment
|
||||
* expression (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* expression (`AssignXorExpr`), a left-shift assignment
|
||||
* expression (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* expression (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* expression (`AssignUnsignedRightShiftExpr`).
|
||||
*/
|
||||
class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { }
|
||||
class AssignBitwiseExpr extends AssignCallExpr, @assign_bitwise_expr { }
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment operation, for example `x &= y`.
|
||||
* DEPRECATED: Use `AssignBitwiseExpr` instead.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseOperation, BitwiseAndOperation, @assign_and_expr {
|
||||
deprecated class AssignBitwiseOperation = AssignBitwiseExpr;
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment expression, for example `x &= y`.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseExpr, BitwiseAndOperation, @assign_and_expr {
|
||||
override string getOperator() { result = "&=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or assignment operation, for example `x |= y`.
|
||||
* A bitwise-or assignment expression, for example `x |= y`.
|
||||
*/
|
||||
class AssignOrExpr extends AssignBitwiseOperation, BitwiseOrOperation, @assign_or_expr {
|
||||
class AssignOrExpr extends AssignBitwiseExpr, BitwiseOrOperation, @assign_or_expr {
|
||||
override string getOperator() { result = "|=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or assignment operation, for example `x ^= y`.
|
||||
* A bitwise exclusive-or assignment expression, for example `x ^= y`.
|
||||
*/
|
||||
class AssignXorExpr extends AssignBitwiseOperation, BitwiseXorOperation, @assign_xor_expr {
|
||||
class AssignXorExpr extends AssignBitwiseExpr, BitwiseXorOperation, @assign_xor_expr {
|
||||
override string getOperator() { result = "^=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignXorExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift assignment operation, for example `x <<= y`.
|
||||
* A left-shift assignment expression, for example `x <<= y`.
|
||||
*/
|
||||
class AssignLeftShiftExpr extends AssignBitwiseOperation, LeftShiftOperation, @assign_lshift_expr {
|
||||
class AssignLeftShiftExpr extends AssignBitwiseExpr, LeftShiftOperation, @assign_lshift_expr {
|
||||
override string getOperator() { result = "<<=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift assignment operation, for example `x >>= y`.
|
||||
* A right-shift assignment expression, for example `x >>= y`.
|
||||
*/
|
||||
class AssignRightShiftExpr extends AssignBitwiseOperation, RightShiftOperation, @assign_rshift_expr {
|
||||
class AssignRightShiftExpr extends AssignBitwiseExpr, RightShiftOperation, @assign_rshift_expr {
|
||||
override string getOperator() { result = ">>=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift assignment operation, for example `x >>>= y`.
|
||||
* An unsigned right-shift assignment expression, for example `x >>>= y`.
|
||||
*/
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseOperation, UnsignedRightShiftOperation,
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseExpr, UnsignedRightShiftOperation,
|
||||
@assign_urshift_expr
|
||||
{
|
||||
override string getOperator() { result = ">>>=" }
|
||||
@@ -297,10 +310,10 @@ class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing assignment operation, for example `x ??= y`.
|
||||
* A null-coalescing assignment expression, for example `x ??= y`.
|
||||
*/
|
||||
class AssignCoalesceExpr extends AssignOperation, NullCoalescingOperation, @assign_coalesce_expr {
|
||||
override string toString() { result = "... ??= ..." }
|
||||
override string getOperator() { result = "??=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignCoalesceExpr" }
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import Expr
|
||||
* A bitwise operation. Either a unary bitwise operation (`UnaryBitwiseOperation`)
|
||||
* or a binary bitwise operation (`BinaryBitwiseOperation`).
|
||||
*/
|
||||
class BitwiseOperation extends Operation, @bit_expr { }
|
||||
class BitwiseOperation extends Operation, @bit_operation { }
|
||||
|
||||
/**
|
||||
* A unary bitwise operation, that is, a bitwise complement operation
|
||||
* (`ComplementExpr`).
|
||||
*/
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_op_expr { }
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise complement operation, for example `~x`.
|
||||
* A bitwise complement expression, for example `~x`.
|
||||
*/
|
||||
class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
override string getOperator() { result = "~" }
|
||||
@@ -28,67 +28,101 @@ class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary bitwise operation. Either a bitwise-and operation
|
||||
* (`BitwiseAndExpr`), a bitwise-or operation (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or operation (`BitwiseXorExpr`), a left-shift
|
||||
* operation (`LeftShiftExpr`), a right-shift operation (`RightShiftExpr`),
|
||||
* or an unsigned right-shift operation (`UnsignedRightShiftExpr`).
|
||||
* A binary bitwise operation. Either a binary bitwise expression (`BinaryBitwiseExpr`) or
|
||||
* a bitwise assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_op_expr {
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift operation, for example `x << y`.
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseOperation, LeftShiftOperation, @lshift_expr {
|
||||
class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A binary bitwise expression. Either a bitwise-and expression
|
||||
* (`BitwiseAndExpr`), a bitwise-or expression (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or expression (`BitwiseXorExpr`), a left-shift
|
||||
* expression (`LeftShiftExpr`), a right-shift expression (`RightShiftExpr`),
|
||||
* or an unsigned right-shift expression (`UnsignedRightShiftExpr`).
|
||||
*/
|
||||
class BinaryBitwiseExpr extends BinaryBitwiseOperation, @bin_bit_expr { }
|
||||
|
||||
/**
|
||||
* A left-shift expression, for example `x << y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseExpr, LeftShiftOperation, @lshift_expr {
|
||||
override string getOperator() { result = "<<" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift operation, for example `x >> y`.
|
||||
* A right-shift expression, for example `x >> y`.
|
||||
*/
|
||||
class RightShiftExpr extends BinaryBitwiseOperation, RightShiftOperation, @rshift_expr {
|
||||
class RightShiftExpr extends BinaryBitwiseExpr, RightShiftOperation, @rshift_expr {
|
||||
override string getOperator() { result = ">>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, for example `x >>> y`.
|
||||
* An unsigned right-shift expression, for example `x >>> y`.
|
||||
*/
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseOperation, UnsignedRightShiftOperation,
|
||||
@urshift_expr
|
||||
{
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseExpr, UnsignedRightShiftOperation, @urshift_expr {
|
||||
override string getOperator() { result = ">>>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, for example `x & y`.
|
||||
* A bitwise-and expression, for example `x & y`.
|
||||
*/
|
||||
class BitwiseAndExpr extends BinaryBitwiseOperation, BitwiseAndOperation, @bit_and_expr {
|
||||
class BitwiseAndExpr extends BinaryBitwiseExpr, BitwiseAndOperation, @bit_and_expr {
|
||||
override string getOperator() { result = "&" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, for example `x | y`.
|
||||
* A bitwise-or expression, for example `x | y`.
|
||||
*/
|
||||
class BitwiseOrExpr extends BinaryBitwiseOperation, BitwiseOrOperation, @bit_or_expr {
|
||||
class BitwiseOrExpr extends BinaryBitwiseExpr, BitwiseOrOperation, @bit_or_expr {
|
||||
override string getOperator() { result = "|" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, for example `x ^ y`.
|
||||
* A bitwise exclusive-or expression, for example `x ^ y`.
|
||||
*/
|
||||
class BitwiseXorExpr extends BinaryBitwiseOperation, BitwiseXorOperation, @bit_xor_expr {
|
||||
class BitwiseXorExpr extends BinaryBitwiseExpr, BitwiseXorOperation, @bit_xor_expr {
|
||||
override string getOperator() { result = "^" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseXorExpr" }
|
||||
|
||||
@@ -609,7 +609,7 @@ class InstanceMutatorOperatorCall extends MutatorOperatorCall {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class CompoundAssignmentOperatorCall extends AssignCallOperation {
|
||||
class CompoundAssignmentOperatorCall extends AssignCallExpr {
|
||||
CompoundAssignmentOperatorCall() { this.getTarget() instanceof CompoundAssignmentOperator }
|
||||
|
||||
override Expr getArgument(int i) { result = this.getChildExpr(i + 1) and i >= 0 }
|
||||
|
||||
@@ -14,7 +14,6 @@ import Creation
|
||||
import Dynamic
|
||||
import Literal
|
||||
import LogicalOperation
|
||||
import Operation
|
||||
import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
@@ -212,7 +211,7 @@ class LocalConstantDeclExpr extends LocalVariableDeclExpr {
|
||||
* (`UnaryOperation`), a binary operation (`BinaryOperation`), or a
|
||||
* ternary operation (`TernaryOperation`).
|
||||
*/
|
||||
class Operation extends Expr, @op_expr {
|
||||
class Operation extends Expr, @operation_expr {
|
||||
/** Gets the name of the operator in this operation. */
|
||||
string getOperator() { none() }
|
||||
|
||||
@@ -227,7 +226,7 @@ class Operation extends Expr, @op_expr {
|
||||
* indirection operation (`PointerIndirectionExpr`), an address-of operation
|
||||
* (`AddressOfExpr`), or a unary logical operation (`UnaryLogicalOperation`).
|
||||
*/
|
||||
class UnaryOperation extends Operation, @un_op {
|
||||
class UnaryOperation extends Operation, @un_operation {
|
||||
/** Gets the operand of this unary operation. */
|
||||
Expr getOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -241,7 +240,7 @@ class UnaryOperation extends Operation, @un_op {
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or an
|
||||
* assignment (`Assignment`).
|
||||
*/
|
||||
class BinaryOperation extends Operation, @bin_op {
|
||||
class BinaryOperation extends Operation, @bin_operation {
|
||||
/** Gets the left operand of this binary operation. */
|
||||
Expr getLeftOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -264,7 +263,7 @@ class BinaryOperation extends Operation, @bin_op {
|
||||
* A ternary operation, that is, a ternary conditional operation
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryOperation extends Operation, @ternary_op { }
|
||||
class TernaryOperation extends Operation, @ternary_operation { }
|
||||
|
||||
/**
|
||||
* A parenthesized expression, for example `(2 + 3)` in
|
||||
|
||||
@@ -11,14 +11,14 @@ import Expr
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or a ternary logical
|
||||
* operation (`TernaryLogicalOperation`).
|
||||
*/
|
||||
class LogicalOperation extends Operation, @log_expr {
|
||||
class LogicalOperation extends Operation, @log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary logical operation, that is, a logical 'not' (`LogicalNotExpr`).
|
||||
*/
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_op_expr { }
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_operation { }
|
||||
|
||||
/**
|
||||
* A logical 'not', for example `!String.IsNullOrEmpty(s)`.
|
||||
@@ -31,10 +31,10 @@ class LogicalNotExpr extends UnaryLogicalOperation, @log_not_expr {
|
||||
|
||||
/**
|
||||
* A binary logical operation. Either a logical 'and' (`LogicalAndExpr`),
|
||||
* a logical 'or' (`LogicalAndExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingExpr`).
|
||||
* a logical 'or' (`LogicalOrExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingOperation`).
|
||||
*/
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_op_expr {
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
@@ -57,7 +57,12 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, for example `s ?? ""` on line 2 in
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing expression, for example `s ?? ""` on line 2 in
|
||||
*
|
||||
* ```csharp
|
||||
* string NonNullOrEmpty(string s) {
|
||||
@@ -65,9 +70,7 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation,
|
||||
@null_coalescing_expr
|
||||
{
|
||||
class NullCoalescingExpr extends NullCoalescingOperation, @null_coalescing_expr {
|
||||
override string getOperator() { result = "??" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NullCoalescingExpr" }
|
||||
@@ -77,7 +80,7 @@ class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation
|
||||
* A ternary logical operation, that is, a ternary conditional expression
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_op_expr { }
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_operation { }
|
||||
|
||||
/**
|
||||
* A conditional expression, for example `s != null ? s.Length : -1`
|
||||
|
||||
@@ -1,71 +1,6 @@
|
||||
/**
|
||||
* Provides classes for operations that also have compound assignment forms.
|
||||
*/
|
||||
deprecated module;
|
||||
|
||||
import Expr
|
||||
|
||||
/**
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class AddOperation extends BinaryOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class RemOperation extends BinaryOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class BitwiseAndOperation extends BinaryOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryOperation, @null_coalescing_operation { }
|
||||
|
||||
@@ -1254,33 +1254,39 @@ case @expr.kind of
|
||||
|
||||
@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr;
|
||||
|
||||
@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@incr_op_expr = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_op_expr = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_op_expr = @incr_op_expr | @decr_op_expr;
|
||||
@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr;
|
||||
@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr;
|
||||
@bin_arith_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@bin_arith_operation = @mul_operation | @div_operation | @rem_operation | @add_operation | @sub_operation;
|
||||
|
||||
@ternary_log_op_expr = @conditional_expr;
|
||||
@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr;
|
||||
@un_log_op_expr = @log_not_expr;
|
||||
@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
|
||||
@incr_operation = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_operation = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_operation = @incr_operation | @decr_operation;
|
||||
@un_arith_operation = @plus_expr | @minus_expr | @mut_operation;
|
||||
@arith_operation = @bin_arith_operation | @un_arith_operation;
|
||||
|
||||
@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@un_bit_op_expr = @bit_not_expr;
|
||||
@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;
|
||||
@ternary_log_operation = @conditional_expr;
|
||||
@bin_log_operation = @log_and_expr | @log_or_expr | @null_coalescing_operation;
|
||||
@un_log_operation = @log_not_expr;
|
||||
@log_operation = @un_log_operation | @bin_log_operation | @ternary_log_operation;
|
||||
|
||||
@bin_bit_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@bin_bit_operation = @and_operation | @or_operation | @xor_operation | @lshift_operation
|
||||
| @rshift_operation | @urshift_operation;
|
||||
@un_bit_expr = @bit_not_expr;
|
||||
@un_bit_operation = @un_bit_expr;
|
||||
@bit_expr = @un_bit_expr | @bin_bit_expr;
|
||||
@bit_operation = @un_bit_operation | @bin_bit_operation;
|
||||
|
||||
@equality_op_expr = @eq_expr | @ne_expr;
|
||||
@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr;
|
||||
@comp_expr = @equality_op_expr | @rel_op_expr;
|
||||
|
||||
@op_expr = @un_op | @bin_op | @ternary_op;
|
||||
@operation_expr = @un_operation | @bin_operation | @ternary_operation;
|
||||
|
||||
@ternary_op = @ternary_log_op_expr;
|
||||
@bin_op = @assign_expr | @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr;
|
||||
@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
@ternary_operation = @ternary_log_operation;
|
||||
@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_operation | @bin_bit_operation | @comp_expr;
|
||||
@un_operation = @un_arith_operation | @un_log_operation | @un_bit_operation | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
|
||||
@anonymous_function_expr = @lambda_expr | @anonymous_method_expr;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -1,6 +1,7 @@
|
||||
binarybitwise
|
||||
| Operators.cs:7:18:7:25 | ... >>> ... | Operators.cs:7:18:7:19 | access to local variable x1 | Operators.cs:7:25:7:25 | 2 | >>> | UnsignedRightShiftExpr |
|
||||
| Operators.cs:10:18:10:25 | ... >>> ... | Operators.cs:10:18:10:19 | access to local variable y1 | Operators.cs:10:25:10:25 | 3 | >>> | UnsignedRightShiftExpr |
|
||||
| Operators.cs:13:9:13:16 | ... >>>= ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>>= | AssignUnsignedRightShiftExpr |
|
||||
assignbitwise
|
||||
| Operators.cs:13:9:13:16 | ... >>>= ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>>= | AssignUnsignedRightShiftExpr |
|
||||
userdefined
|
||||
|
||||
@@ -11,7 +11,7 @@ query predicate binarybitwise(
|
||||
}
|
||||
|
||||
query predicate assignbitwise(
|
||||
AssignBitwiseOperation op, Expr left, Expr right, string name, string qlclass
|
||||
AssignBitwiseExpr op, Expr left, Expr right, string name, string qlclass
|
||||
) {
|
||||
op.getFile().getStem() = "Operators" and
|
||||
left = op.getLeftOperand() and
|
||||
|
||||
@@ -10,7 +10,7 @@ toolchain go1.26.4
|
||||
// bazel mod tidy
|
||||
require (
|
||||
golang.org/x/mod v0.37.0
|
||||
golang.org/x/tools v0.45.0
|
||||
golang.org/x/tools v0.46.0
|
||||
)
|
||||
|
||||
require github.com/stretchr/testify v1.11.1
|
||||
@@ -18,6 +18,6 @@ require github.com/stretchr/testify v1.11.1
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sync v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -8,10 +8,10 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
|
||||
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk=
|
||||
golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* @name Web Cache Deception
|
||||
* @description A caching system has been detected on the application and is vulnerable to web cache deception. By manipulating the URL it is possible to force the application to cache pages that are only accessible by an authenticated user. Once cached, these pages can be accessed by an unauthenticated user.
|
||||
* @kind problem
|
||||
|
||||
@@ -54,31 +54,31 @@ func main() {}
|
||||
// bad is an example of a bad implementation
|
||||
func (ld *Ldap) bad(req *http.Request) {
|
||||
// ...
|
||||
untrusted := req.UserAgent()
|
||||
untrusted := req.UserAgent() // $ Source
|
||||
goldap.NewSearchRequest(
|
||||
untrusted, // BAD: untrusted dn
|
||||
untrusted, // $ Alert // BAD: untrusted dn
|
||||
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute
|
||||
nil,
|
||||
)
|
||||
goldapv3.NewSearchRequest(
|
||||
untrusted, // BAD: untrusted dn
|
||||
untrusted, // $ Alert // BAD: untrusted dn
|
||||
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute
|
||||
nil,
|
||||
)
|
||||
gopkgldapv2.NewSearchRequest(
|
||||
untrusted, // BAD: untrusted dn
|
||||
untrusted, // $ Alert // BAD: untrusted dn
|
||||
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
|
||||
"(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter
|
||||
[]string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute
|
||||
nil,
|
||||
)
|
||||
client := &ldapclient.LDAPClient{}
|
||||
client.Authenticate(untrusted, "123456") // BAD: untrusted filter
|
||||
client.GetGroupsOfUser(untrusted) // BAD: untrusted filter
|
||||
client.Authenticate(untrusted, "123456") // $ Alert // BAD: untrusted filter
|
||||
client.GetGroupsOfUser(untrusted) // $ Alert // BAD: untrusted filter
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-090/LDAPInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-203/Timing.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -12,9 +12,9 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
secret := "MySuperSecretPasscode"
|
||||
secretHeader := "X-Secret"
|
||||
|
||||
headerSecret := req.Header.Get(secretHeader)
|
||||
headerSecret := req.Header.Get(secretHeader) // $ Source
|
||||
secretStr := string(secret)
|
||||
if len(headerSecret) != 0 && headerSecret != secretStr {
|
||||
if len(headerSecret) != 0 && headerSecret != secretStr { // $ Alert
|
||||
return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret)
|
||||
}
|
||||
return nil, nil
|
||||
@@ -25,9 +25,9 @@ func bad2(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
secret := "MySuperSecretPasscode"
|
||||
secretHeader := "X-Secret"
|
||||
|
||||
headerSecret := req.Header.Get(secretHeader)
|
||||
headerSecret := req.Header.Get(secretHeader) // $ Source
|
||||
secretStr := string(secret)
|
||||
if len(headerSecret) != 0 && strings.Compare(headerSecret, secretStr) != 0 {
|
||||
if len(headerSecret) != 0 && strings.Compare(headerSecret, secretStr) != 0 { // $ Alert
|
||||
return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret)
|
||||
}
|
||||
return nil, nil
|
||||
@@ -38,8 +38,8 @@ func bad4(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
secret := "MySuperSecretPasscode"
|
||||
secretHeader := "X-Secret"
|
||||
|
||||
headerSecret := req.Header.Get(secretHeader)
|
||||
if len(secret) != 0 && headerSecret != "SecretStringLiteral" {
|
||||
headerSecret := req.Header.Get(secretHeader) // $ Source
|
||||
if len(secret) != 0 && headerSecret != "SecretStringLiteral" { // $ Alert
|
||||
return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret)
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-285/PamAuthBypass.ql
|
||||
query: experimental/CWE-285/PamAuthBypass.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func bad() error {
|
||||
t, _ := pam.StartFunc("", "", func(s pam.Style, msg string) (string, error) {
|
||||
return "", nil
|
||||
})
|
||||
}) // $ Alert
|
||||
return t.Authenticate(0)
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
ldapServer := "ldap.example.com"
|
||||
ldapPort := 389
|
||||
bindDN := "cn=admin,dc=example,dc=com"
|
||||
bindPassword := req.URL.Query()["password"][0]
|
||||
bindPassword := req.URL.Query()["password"][0] // $ Source
|
||||
|
||||
// Connect to the LDAP server
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
@@ -25,7 +25,7 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
defer l.Close()
|
||||
|
||||
// BAD: user input is not sanetized
|
||||
err = l.Bind(bindDN, bindPassword)
|
||||
err = l.Bind(bindDN, bindPassword) // $ Alert
|
||||
if err != nil {
|
||||
return fmt.Errorf("LDAP bind failed: %v", err), err
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func bad2(req *http.Request) {
|
||||
ldapPort := 389
|
||||
bindDN := "cn=admin,dc=example,dc=com"
|
||||
// BAD : empty password
|
||||
bindPassword := ""
|
||||
bindPassword := "" // $ Source
|
||||
|
||||
// Connect to the LDAP server
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
|
||||
@@ -94,7 +94,7 @@ func bad2(req *http.Request) {
|
||||
defer l.Close()
|
||||
|
||||
// BAD : bindPassword is empty
|
||||
err = l.Bind(bindDN, bindPassword)
|
||||
err = l.Bind(bindDN, bindPassword) // $ Alert
|
||||
if err != nil {
|
||||
log.Fatalf("LDAP bind failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-287/ImproperLdapAuth.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#select
|
||||
| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:24:32:24:37 | JwtKey | This $@. | go-jose.v3.go:13:21:13:33 | "AllYourBase" | Constant Key is used as JWT Secret key |
|
||||
| golang-jwt-v5.go:27:9:27:15 | JwtKey1 | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | This $@. | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | Constant Key is used as JWT Secret key |
|
||||
edges
|
||||
| go-jose.v3.go:13:14:13:34 | type conversion | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | |
|
||||
| go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:13:14:13:34 | type conversion | provenance | |
|
||||
@@ -11,6 +14,3 @@ nodes
|
||||
| golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | semmle.label | "AllYourBase" |
|
||||
| golang-jwt-v5.go:27:9:27:15 | JwtKey1 | semmle.label | JwtKey1 |
|
||||
subpaths
|
||||
#select
|
||||
| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:24:32:24:37 | JwtKey | This $@. | go-jose.v3.go:13:21:13:33 | "AllYourBase" | Constant Key is used as JWT Secret key |
|
||||
| golang-jwt-v5.go:27:9:27:15 | JwtKey1 | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | This $@. | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | Constant Key is used as JWT Secret key |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-321-V2/HardCodedKeys.ql
|
||||
query: experimental/CWE-321-V2/HardCodedKeys.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
// NOT OK
|
||||
var JwtKey = []byte("AllYourBase")
|
||||
var JwtKey = []byte("AllYourBase") // $ Source
|
||||
|
||||
func main2(r *http.Request) {
|
||||
signedToken := r.URL.Query().Get("signedToken")
|
||||
@@ -21,7 +21,7 @@ func verifyJWT(signedToken string) {
|
||||
fmt.Println("verifying JWT")
|
||||
DecodedToken, _ := jwt.ParseSigned(signedToken)
|
||||
out := CustomerInfo{}
|
||||
if err := DecodedToken.Claims(JwtKey, &out); err != nil {
|
||||
if err := DecodedToken.Claims(JwtKey, &out); err != nil { // $ Alert
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%v\n", out)
|
||||
|
||||
@@ -16,7 +16,7 @@ type CustomerInfo struct {
|
||||
}
|
||||
|
||||
// BAD constant key
|
||||
var JwtKey1 = []byte("AllYourBase")
|
||||
var JwtKey1 = []byte("AllYourBase") // $ Source
|
||||
|
||||
func main1(r *http.Request) {
|
||||
signedToken := r.URL.Query().Get("signedToken")
|
||||
@@ -24,7 +24,7 @@ func main1(r *http.Request) {
|
||||
}
|
||||
|
||||
func LoadJwtKey(token *jwt.Token) (interface{}, error) {
|
||||
return JwtKey1, nil
|
||||
return JwtKey1, nil // $ Alert
|
||||
}
|
||||
|
||||
func verifyJWT_golangjwt(signedToken string) {
|
||||
|
||||
@@ -7,37 +7,37 @@ import (
|
||||
)
|
||||
|
||||
func myHandler1(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value, _ := strconv.Atoi(param1)
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
|
||||
func myHandler2(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value := int(param1[0])
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
|
||||
func myHandler3(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value, _ := strconv.ParseInt(param1, 10, 64)
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
|
||||
func myHandler4(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value, _ := strconv.ParseFloat(param1, 32)
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
|
||||
func myHandler5(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value, _ := strconv.ParseUint(param1, 10, 64)
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ func myHandler6(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func myHandler7(w http.ResponseWriter, r *http.Request) {
|
||||
param1 := r.URL.Query()["param1"][0]
|
||||
param1 := r.URL.Query()["param1"][0] // $ Source
|
||||
value := int(param1[0])
|
||||
if value >= 0 {
|
||||
out := 1337 / value
|
||||
out := 1337 / value // $ Alert
|
||||
fmt.Println(out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-369/DivideByZero.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#select
|
||||
| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop |
|
||||
| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop |
|
||||
| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop |
|
||||
edges
|
||||
| DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First |
|
||||
| test.go:10:1:12:1 | function declaration | test.go:11:2:11:13 | call to Take |
|
||||
@@ -7,7 +11,3 @@ edges
|
||||
| test.go:21:3:21:14 | call to runQuery | test.go:10:1:12:1 | function declaration |
|
||||
| test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery |
|
||||
| test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration |
|
||||
#select
|
||||
| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop |
|
||||
| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop |
|
||||
| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop |
|
||||
|
||||
@@ -6,8 +6,8 @@ func getUsers(db *gorm.DB, names []string) []User {
|
||||
res := make([]User, 0, len(names))
|
||||
for _, name := range names {
|
||||
var user User
|
||||
db.Where("name = ?", name).First(&user)
|
||||
db.Where("name = ?", name).First(&user) // $ Alert
|
||||
res = append(res, user)
|
||||
}
|
||||
} // $ Source
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-400/DatabaseCallInLoop.ql
|
||||
query: experimental/CWE-400/DatabaseCallInLoop.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -8,7 +8,7 @@ type User struct {
|
||||
}
|
||||
|
||||
func runQuery(db *gorm.DB) {
|
||||
db.Take(nil)
|
||||
db.Take(nil) // $ Alert
|
||||
}
|
||||
|
||||
func runRunQuery(db *gorm.DB) {
|
||||
@@ -19,9 +19,9 @@ func main() {
|
||||
var db *gorm.DB
|
||||
for i := 0; i < 10; i++ {
|
||||
runQuery(db)
|
||||
}
|
||||
} // $ Source
|
||||
|
||||
for i := 10; i > 0; i-- {
|
||||
runRunQuery(db)
|
||||
}
|
||||
} // $ Source
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -56,41 +56,41 @@ func main() {
|
||||
func DecompressHandler(w http.ResponseWriter, request *http.Request) {
|
||||
GZipOpenReaderSafe(request.PostFormValue("test"))
|
||||
ZipOpenReaderSafe(request.PostFormValue("test"))
|
||||
ZipOpenReader(request.FormValue("filepath"))
|
||||
ZipNewReader(request.Body)
|
||||
ZipNewReaderKlauspost(request.Body)
|
||||
Bzip2Dsnet(request.Body)
|
||||
ZipOpenReader(request.FormValue("filepath")) // $ Source
|
||||
ZipNewReader(request.Body) // $ Source
|
||||
ZipNewReaderKlauspost(request.Body) // $ Source
|
||||
Bzip2Dsnet(request.Body) // $ Source
|
||||
Bzip2DsnetSafe(request.Body)
|
||||
Bzip2(request.Body)
|
||||
Bzip2(request.Body) // $ Source
|
||||
Bzip2Safe(request.Body)
|
||||
Flate(request.Body)
|
||||
Flate(request.Body) // $ Source
|
||||
FlateSafe(request.Body)
|
||||
FlateKlauspost(request.Body)
|
||||
FlateKlauspost(request.Body) // $ Source
|
||||
FlateKlauspostSafe(request.Body)
|
||||
FlateDsnet(request.Body)
|
||||
FlateDsnet(request.Body) // $ Source
|
||||
FlateDsnetSafe(request.Body)
|
||||
ZlibKlauspost(request.Body)
|
||||
ZlibKlauspost(request.Body) // $ Source
|
||||
ZlibKlauspostSafe(request.Body)
|
||||
Zlib(request.Body)
|
||||
Zlib(request.Body) // $ Source
|
||||
ZlibSafe(request.Body)
|
||||
Snappy(request.Body)
|
||||
Snappy(request.Body) // $ Source
|
||||
SnappySafe(request.Body)
|
||||
SnappyKlauspost(request.Body)
|
||||
SnappyKlauspost(request.Body) // $ Source
|
||||
SnappyKlauspostSafe(request.Body)
|
||||
S2(request.Body)
|
||||
S2(request.Body) // $ Source
|
||||
S2Safe(request.Body)
|
||||
Gzip(request.Body)
|
||||
Gzip(request.Body) // $ Source
|
||||
GzipSafe(request.Body)
|
||||
GZipIoReader(request.Body, "dest")
|
||||
GzipKlauspost(request.Body)
|
||||
GZipIoReader(request.Body, "dest") // $ Source
|
||||
GzipKlauspost(request.Body) // $ Source
|
||||
GzipKlauspostSafe(request.Body)
|
||||
PzipKlauspost(request.Body)
|
||||
PzipKlauspost(request.Body) // $ Source
|
||||
PzipKlauspostSafe(request.Body)
|
||||
Zstd_Klauspost(request.Body)
|
||||
Zstd_Klauspost(request.Body) // $ Source
|
||||
Zstd_KlauspostSafe(request.Body)
|
||||
Zstd_DataDog(request.Body)
|
||||
Zstd_DataDog(request.Body) // $ Source
|
||||
Zstd_DataDogSafe(request.Body)
|
||||
Xz(request.Body)
|
||||
Xz(request.Body) // $ Source
|
||||
XzSafe(request.Body)
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ func ZipOpenReader(filename string) {
|
||||
for _, f := range zipReader.File {
|
||||
rc, _ := f.Open()
|
||||
for {
|
||||
result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc"
|
||||
result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" Alert
|
||||
if result == 0 {
|
||||
_ = rc.Close()
|
||||
break
|
||||
@@ -144,7 +144,7 @@ func ZipOpenReader(filename string) {
|
||||
for _, f := range zipKlauspostReader.File {
|
||||
rc, _ := f.Open()
|
||||
for {
|
||||
result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc"
|
||||
result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" Alert
|
||||
if result == 0 {
|
||||
_ = rc.Close()
|
||||
break
|
||||
@@ -161,7 +161,7 @@ func ZipNewReader(file io.Reader) {
|
||||
for _, file := range zipReader.File {
|
||||
fileWriter := bytes.NewBuffer([]byte{})
|
||||
fileReaderCloser, _ := file.Open()
|
||||
result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser"
|
||||
result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" Alert
|
||||
fmt.Print(result)
|
||||
}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ func ZipNewReaderKlauspost(file io.Reader) {
|
||||
fileWriter := bytes.NewBuffer([]byte{})
|
||||
// file.OpenRaw()
|
||||
fileReaderCloser, _ := file.Open()
|
||||
result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser"
|
||||
result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" Alert
|
||||
fmt.Print(result)
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ func Bzip2Dsnet(file io.Reader) {
|
||||
|
||||
bzip2Reader, _ := bzip2Dsnet.NewReader(file, &bzip2Dsnet.ReaderConfig{})
|
||||
var out []byte = make([]byte, 70)
|
||||
bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader"
|
||||
bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" Alert
|
||||
tarRead = tar.NewReader(bzip2Reader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -210,7 +210,7 @@ func Bzip2(file io.Reader) {
|
||||
|
||||
bzip2Reader := bzip2.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader"
|
||||
bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" Alert
|
||||
tarRead = tar.NewReader(bzip2Reader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -235,7 +235,7 @@ func Flate(file io.Reader) {
|
||||
|
||||
flateReader := flate.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader"
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader" Alert
|
||||
tarRead = tar.NewReader(flateReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -260,7 +260,7 @@ func FlateKlauspost(file io.Reader) {
|
||||
|
||||
flateReader := flateKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader"
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader" Alert
|
||||
tarRead = tar.NewReader(flateReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -285,7 +285,7 @@ func FlateDsnet(file io.Reader) {
|
||||
|
||||
flateReader, _ := flateDsnet.NewReader(file, &flateDsnet.ReaderConfig{})
|
||||
var out []byte = make([]byte, 70)
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader"
|
||||
flateReader.Read(out) // $ hasValueFlow="flateReader" Alert
|
||||
tarRead = tar.NewReader(flateReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -310,7 +310,7 @@ func ZlibKlauspost(file io.Reader) {
|
||||
|
||||
zlibReader, _ := zlibKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
zlibReader.Read(out) // $ hasValueFlow="zlibReader"
|
||||
zlibReader.Read(out) // $ hasValueFlow="zlibReader" Alert
|
||||
tarRead = tar.NewReader(zlibReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -335,7 +335,7 @@ func Zlib(file io.Reader) {
|
||||
|
||||
zlibReader, _ := zlib.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
zlibReader.Read(out) // $ hasValueFlow="zlibReader"
|
||||
zlibReader.Read(out) // $ hasValueFlow="zlibReader" Alert
|
||||
tarRead = tar.NewReader(zlibReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -360,8 +360,8 @@ func Snappy(file io.Reader) {
|
||||
|
||||
snappyReader := snappy.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
snappyReader.Read(out) // $ hasValueFlow="snappyReader"
|
||||
snappyReader.ReadByte() // $ hasValueFlow="snappyReader"
|
||||
snappyReader.Read(out) // $ hasValueFlow="snappyReader" Alert
|
||||
snappyReader.ReadByte() // $ hasValueFlow="snappyReader" Alert
|
||||
tarRead = tar.NewReader(snappyReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -386,10 +386,10 @@ func SnappyKlauspost(file io.Reader) {
|
||||
|
||||
snappyReader := snappyKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
snappyReader.Read(out) // $ hasValueFlow="snappyReader"
|
||||
snappyReader.Read(out) // $ hasValueFlow="snappyReader" Alert
|
||||
var buf bytes.Buffer
|
||||
snappyReader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="snappyReader"
|
||||
snappyReader.ReadByte() // $ hasValueFlow="snappyReader"
|
||||
snappyReader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="snappyReader" Alert
|
||||
snappyReader.ReadByte() // $ hasValueFlow="snappyReader" Alert
|
||||
tarRead = tar.NewReader(snappyReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -414,10 +414,10 @@ func S2(file io.Reader) {
|
||||
|
||||
s2Reader := s2.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
s2Reader.Read(out) // $ hasValueFlow="s2Reader"
|
||||
s2Reader.ReadByte() // $ hasValueFlow="s2Reader"
|
||||
s2Reader.Read(out) // $ hasValueFlow="s2Reader" Alert
|
||||
s2Reader.ReadByte() // $ hasValueFlow="s2Reader" Alert
|
||||
var buf bytes.Buffer
|
||||
s2Reader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="s2Reader"
|
||||
s2Reader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="s2Reader" Alert
|
||||
tarRead = tar.NewReader(s2Reader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -442,14 +442,14 @@ func GZipIoReader(src io.Reader, dst string) {
|
||||
dstF, _ := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
defer dstF.Close()
|
||||
newSrc := io.Reader(gzipReader)
|
||||
_, _ = io.Copy(dstF, newSrc) // $ hasValueFlow="newSrc"
|
||||
_, _ = io.Copy(dstF, newSrc) // $ hasValueFlow="newSrc" Alert
|
||||
}
|
||||
func Gzip(file io.Reader) {
|
||||
var tarRead *tar.Reader
|
||||
|
||||
gzipReader, _ := gzip.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
gzipReader.Read(out) // $ hasValueFlow="gzipReader"
|
||||
gzipReader.Read(out) // $ hasValueFlow="gzipReader" Alert
|
||||
tarRead = tar.NewReader(gzipReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -474,9 +474,9 @@ func GzipKlauspost(file io.Reader) {
|
||||
|
||||
gzipReader, _ := gzipKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
gzipReader.Read(out) // $ hasValueFlow="gzipReader"
|
||||
gzipReader.Read(out) // $ hasValueFlow="gzipReader" Alert
|
||||
var buf bytes.Buffer
|
||||
gzipReader.WriteTo(&buf) // $ hasValueFlow="gzipReader"
|
||||
gzipReader.WriteTo(&buf) // $ hasValueFlow="gzipReader" Alert
|
||||
tarRead = tar.NewReader(gzipReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -501,9 +501,9 @@ func PzipKlauspost(file io.Reader) {
|
||||
|
||||
pgzipReader, _ := pgzipKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
pgzipReader.Read(out) // $ hasValueFlow="pgzipReader"
|
||||
pgzipReader.Read(out) // $ hasValueFlow="pgzipReader" Alert
|
||||
var buf bytes.Buffer
|
||||
pgzipReader.WriteTo(&buf) // $ hasValueFlow="pgzipReader"
|
||||
pgzipReader.WriteTo(&buf) // $ hasValueFlow="pgzipReader" Alert
|
||||
tarRead = tar.NewReader(pgzipReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -528,11 +528,11 @@ func Zstd_Klauspost(file io.Reader) {
|
||||
|
||||
zstdReader, _ := zstdKlauspost.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
zstdReader.Read(out) // $ hasValueFlow="zstdReader"
|
||||
zstdReader.Read(out) // $ hasValueFlow="zstdReader" Alert
|
||||
var buf bytes.Buffer
|
||||
zstdReader.WriteTo(&buf) // $ hasValueFlow="zstdReader"
|
||||
zstdReader.WriteTo(&buf) // $ hasValueFlow="zstdReader" Alert
|
||||
var src []byte
|
||||
zstdReader.DecodeAll(src, nil) // $ hasValueFlow="zstdReader"
|
||||
zstdReader.DecodeAll(src, nil) // $ hasValueFlow="zstdReader" Alert
|
||||
tarRead = tar.NewReader(zstdReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -557,7 +557,7 @@ func Zstd_DataDog(file io.Reader) {
|
||||
|
||||
zstdReader := zstdDataDog.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
zstdReader.Read(out) // $ hasValueFlow="zstdReader"
|
||||
zstdReader.Read(out) // $ hasValueFlow="zstdReader" Alert
|
||||
tarRead = tar.NewReader(zstdReader)
|
||||
|
||||
TarDecompressor(tarRead)
|
||||
@@ -582,7 +582,7 @@ func Xz(file io.Reader) {
|
||||
|
||||
xzReader, _ := xz.NewReader(file)
|
||||
var out []byte = make([]byte, 70)
|
||||
xzReader.Read(out) // $ hasValueFlow="xzReader"
|
||||
xzReader.Read(out) // $ hasValueFlow="xzReader" Alert
|
||||
tarRead = tar.NewReader(xzReader)
|
||||
fmt.Println(io.SeekStart)
|
||||
|
||||
@@ -618,7 +618,7 @@ func TarDecompressor(tarRead *tar.Reader) {
|
||||
if cur.Typeflag != tar.TypeReg {
|
||||
continue
|
||||
}
|
||||
data, _ := io.ReadAll(tarRead) // $ hasValueFlow="tarRead"
|
||||
data, _ := io.ReadAll(tarRead) // $ hasValueFlow="tarRead" Alert
|
||||
files[cur.Name] = &fstest.MapFile{Data: data}
|
||||
}
|
||||
fmt.Print(files)
|
||||
@@ -626,7 +626,7 @@ func TarDecompressor(tarRead *tar.Reader) {
|
||||
|
||||
func TarDecompressor2(tarRead *tar.Reader) {
|
||||
var tarOut []byte = make([]byte, 70)
|
||||
tarRead.Read(tarOut) // $ hasValueFlow="tarRead"
|
||||
tarRead.Read(tarOut) // $ hasValueFlow="tarRead" Alert
|
||||
fmt.Println("do sth with output:", tarOut)
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-525/WebCacheDeception.ql
|
||||
query: experimental/CWE-525/WebCacheDeception.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -79,7 +79,7 @@ func badRoutingNet() {
|
||||
|
||||
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))))
|
||||
|
||||
http.HandleFunc("/adminusers/", ShowAdminPageCache)
|
||||
http.HandleFunc("/adminusers/", ShowAdminPageCache) // $ Alert
|
||||
err := http.ListenAndServe(":1337", nil)
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe: ", err)
|
||||
|
||||
@@ -12,12 +12,12 @@ func badRouting() {
|
||||
log.Println("We are logging in Golang!")
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) error {
|
||||
app.Get("/api/*", func(c *fiber.Ctx) error { // $ Alert
|
||||
msg := fmt.Sprintf("✋")
|
||||
return c.SendString(msg) // => ✋ register
|
||||
})
|
||||
|
||||
app.Post("/api/*", func(c *fiber.Ctx) error {
|
||||
app.Post("/api/*", func(c *fiber.Ctx) error { // $ Alert
|
||||
msg := fmt.Sprintf("✋")
|
||||
return c.SendString(msg) // => ✋ register
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
func badRoutingChi() {
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.Logger)
|
||||
r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
|
||||
r.Get("/*", func(w http.ResponseWriter, r *http.Request) { // $ Alert
|
||||
w.Write([]byte("welcome"))
|
||||
})
|
||||
http.ListenAndServe(":3000", r)
|
||||
|
||||
@@ -18,7 +18,7 @@ func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
func badHTTPRouter() {
|
||||
router := httprouter.New()
|
||||
router.GET("/test/*test", Index)
|
||||
router.GET("/test/*test", Index) // $ Alert
|
||||
router.GET("/hello/:name", Hello)
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8082", router))
|
||||
|
||||
@@ -23,10 +23,10 @@ func good() (interface{}, error) {
|
||||
}
|
||||
|
||||
func bad() interface{} {
|
||||
name2 := os.Args[1:]
|
||||
name2 := os.Args[1:] // $ Source[go/dsn-injection-local]
|
||||
// This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files.
|
||||
dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name2[0])
|
||||
db, _ := sql.Open("mysql", dbDSN)
|
||||
db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection-local]
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ func good2(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
}
|
||||
|
||||
func bad2(w http.ResponseWriter, req *http.Request) interface{} {
|
||||
name := req.FormValue("name")
|
||||
name := req.FormValue("name") // $ Source[go/dsn-injection]
|
||||
// This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files.
|
||||
dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name)
|
||||
db, _ := sql.Open("mysql", dbDSN)
|
||||
db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection]
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -60,12 +60,12 @@ func (Config) Parse([]string) error { return nil }
|
||||
|
||||
func RegexFuncModelTest(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
cfg := NewConfig()
|
||||
err := cfg.Parse(os.Args[1:]) // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files.
|
||||
err := cfg.Parse(os.Args[1:]) // $ Source[go/dsn-injection-local] // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, cfg.dsn)
|
||||
db, _ := sql.Open("mysql", dbDSN)
|
||||
db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection-local]
|
||||
return db, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-74/DsnInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: experimental/CWE-74/DsnInjectionLocal.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-807/SensitiveConditionBypass.ql
|
||||
query: experimental/CWE-807/SensitiveConditionBypass.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,7 +4,7 @@ import "net/http"
|
||||
|
||||
func example(w http.ResponseWriter, r *http.Request) {
|
||||
test2 := "test"
|
||||
if r.Header.Get("X-Password") != test2 {
|
||||
if r.Header.Get("X-Password") != test2 { // $ Alert
|
||||
login()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const test = "localhost"
|
||||
|
||||
// Should alert as authkey is sensitive
|
||||
func ex1(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Origin") != test {
|
||||
if r.Header.Get("Origin") != test { // $ Alert
|
||||
authkey := "randomDatta"
|
||||
io.WriteString(w, authkey)
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func ex1(w http.ResponseWriter, r *http.Request) {
|
||||
// Should alert as authkey is sensitive
|
||||
func ex2(w http.ResponseWriter, r *http.Request) {
|
||||
test2 := "test"
|
||||
if r.Header.Get("Origin") != test2 {
|
||||
if r.Header.Get("Origin") != test2 { // $ Alert
|
||||
authkey := "randomDatta2"
|
||||
io.WriteString(w, authkey)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func ex2(w http.ResponseWriter, r *http.Request) {
|
||||
// Should alert as login() is sensitive
|
||||
func ex3(w http.ResponseWriter, r *http.Request) {
|
||||
test2 := "test"
|
||||
if r.Header.Get("Origin") != test2 {
|
||||
if r.Header.Get("Origin") != test2 { // $ Alert
|
||||
login()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/CWE-840/ConditionalBypass.ql
|
||||
query: experimental/CWE-840/ConditionalBypass.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
func exampleHandlerBad(w http.ResponseWriter, r *http.Request) {
|
||||
// BAD: the Origin and Host headers are user controlled
|
||||
if r.Header.Get("Origin") != "http://"+r.Host {
|
||||
if r.Header.Get("Origin") != "http://"+r.Host { // $ Alert
|
||||
//do something
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
|
||||
// BAD: taken from https://www.gorillatoolkit.org/pkg/websocket
|
||||
func ex1(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Origin") != "http://"+r.Host {
|
||||
if r.Header.Get("Origin") != "http://"+r.Host { // $ Alert
|
||||
//do something
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: both operands are from remote sources
|
||||
func ex2(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Origin") != "http://"+r.Header.Get("Header") {
|
||||
if r.Header.Get("Origin") != "http://"+r.Header.Get("Header") { // $ Alert
|
||||
//do something
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import "os"
|
||||
func openFiles(filenames []string) {
|
||||
for _, filename := range filenames {
|
||||
file, err := os.Open(filename)
|
||||
defer file.Close()
|
||||
defer file.Close() // $ Alert[go/examples/deferinloop]
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/InconsistentCode/DeferInLoop.ql
|
||||
query: experimental/InconsistentCode/DeferInLoop.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,6 +4,6 @@ import "gorm.io/gorm"
|
||||
|
||||
func getUserId(db *gorm.DB, name string) int64 {
|
||||
var user User
|
||||
db.Where("name = ?", name).First(&user)
|
||||
db.Where("name = ?", name).First(&user) // $ Alert[go/examples/gorm-error-not-checked]
|
||||
return user.Id
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/InconsistentCode/GORMErrorNotChecked.ql
|
||||
query: experimental/InconsistentCode/GORMErrorNotChecked.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -3,24 +3,24 @@ package main
|
||||
func test() {
|
||||
var xs []int
|
||||
for _ = range xs {
|
||||
defer test() // not ok
|
||||
defer test() // $ Alert[go/examples/deferinloop] // not ok
|
||||
}
|
||||
|
||||
for _ = range xs {
|
||||
if true {
|
||||
defer test() // not ok
|
||||
defer test() // $ Alert[go/examples/deferinloop] // not ok
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
defer test()
|
||||
defer test() // $ Alert[go/examples/deferinloop]
|
||||
}
|
||||
|
||||
for true {
|
||||
defer test() // not ok
|
||||
defer test() // $ Alert[go/examples/deferinloop] // not ok
|
||||
}
|
||||
|
||||
for false {
|
||||
defer test() // fine but caught
|
||||
defer test() // $ Alert[go/examples/deferinloop] // fine but caught
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#select
|
||||
| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) |
|
||||
| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) |
|
||||
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string |
|
||||
| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type |
|
||||
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 |
|
||||
| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 |
|
||||
| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 |
|
||||
edges
|
||||
| WrongUsageOfUnsafe.go:17:24:17:48 | type conversion | WrongUsageOfUnsafe.go:17:13:17:49 | type conversion | provenance | |
|
||||
| WrongUsageOfUnsafe.go:34:24:34:51 | type conversion | WrongUsageOfUnsafe.go:34:13:34:52 | type conversion | provenance | |
|
||||
@@ -48,15 +60,3 @@ nodes
|
||||
| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | semmle.label | type conversion |
|
||||
| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | semmle.label | type conversion |
|
||||
subpaths
|
||||
#select
|
||||
| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) |
|
||||
| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) |
|
||||
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string |
|
||||
| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type |
|
||||
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
|
||||
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 |
|
||||
| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 |
|
||||
| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 |
|
||||
|
||||
@@ -74,7 +74,7 @@ func badIndexExpr() {
|
||||
// the address of the 3rd element of the `harmless` array,
|
||||
// and continue for 8 bytes, going out of the boundaries of
|
||||
// `harmless` and crossing into the memory occupied by `secret`.
|
||||
var leaking = (*[8]byte)(unsafe.Pointer(&harmless[2])) // BAD
|
||||
var leaking = (*[8]byte)(unsafe.Pointer(&harmless[2])) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string((*leaking)[:]))
|
||||
|
||||
@@ -108,7 +108,7 @@ func bad0() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we get the pointer to the first byte of harmless)
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless[0])) // BAD
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless[0])) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string((*leaking)[:]))
|
||||
|
||||
@@ -126,7 +126,7 @@ func bad1() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless)
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string((*leaking)[:]))
|
||||
|
||||
@@ -146,7 +146,7 @@ func bad2() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless)
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string((*leaking)[:]))
|
||||
|
||||
@@ -163,7 +163,7 @@ func bad3() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless)
|
||||
var leaking = (*[8 + 9]string)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*[8 + 9]string)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(*leaking)
|
||||
fmt.Println([17]string((*leaking)))
|
||||
@@ -186,7 +186,7 @@ func bad4() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless)
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string((*leaking)[:]))
|
||||
|
||||
@@ -208,7 +208,7 @@ func bad5() {
|
||||
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless)
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless.Data)) // BAD
|
||||
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless.Data)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(string(leaking[:]))
|
||||
|
||||
@@ -224,7 +224,7 @@ func bad6() {
|
||||
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
||||
|
||||
// Read before secret:
|
||||
var leaking = buffer_request(unsafe.Pointer(&harmless)) // BAD (see inside buffer_request func)
|
||||
var leaking = buffer_request(unsafe.Pointer(&harmless)) // $ Source // BAD (see inside buffer_request func)
|
||||
|
||||
fmt.Println((string)(leaking[:]))
|
||||
|
||||
@@ -240,7 +240,7 @@ func buffer_request(req unsafe.Pointer) [8 + 9]byte {
|
||||
// will be read, the read will also contain pieces of
|
||||
// data from `secret`.
|
||||
var buf [8 + 9]byte
|
||||
buf = *(*[8 + 9]byte)(req) // BAD (from above func)
|
||||
buf = *(*[8 + 9]byte)(req) // $ Alert // BAD (from above func)
|
||||
return buf
|
||||
}
|
||||
func bad7() {
|
||||
@@ -253,7 +253,7 @@ func bad7() {
|
||||
// (notice we read more than the length of harmless);
|
||||
// the leaking array will not contain letters,
|
||||
// but integers representing bytes from `secret`.
|
||||
var leaking = (*[4]int64)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*[4]int64)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(*leaking)
|
||||
|
||||
@@ -271,7 +271,7 @@ func bad8() {
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless);
|
||||
// the leaking data will contain some bits from `secret`.
|
||||
var leaking = (*int64)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*int64)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(*leaking)
|
||||
|
||||
@@ -289,7 +289,7 @@ func bad9() {
|
||||
// Read before secret, overflowing into secret
|
||||
// (notice we read more than the length of harmless);
|
||||
// the leaking data will contain some bits from `secret`.
|
||||
var leaking = (*int)(unsafe.Pointer(&harmless)) // BAD
|
||||
var leaking = (*int)(unsafe.Pointer(&harmless)) // $ Alert // BAD
|
||||
|
||||
fmt.Println(*leaking)
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
experimental/Unsafe/WrongUsageOfUnsafe.ql
|
||||
query: experimental/Unsafe/WrongUsageOfUnsafe.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-089/SqlInjection.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-079/StoredXss.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -8,61 +8,61 @@ import (
|
||||
|
||||
// BAD: using untrusted data in SQL queries
|
||||
func testDbMethods(bdb *orm.DB, untrustedSource *http.Request) {
|
||||
untrusted := untrustedSource.UserAgent()
|
||||
untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
|
||||
bdb.Exec(untrusted) // $ querystring=untrusted
|
||||
bdb.ExecContext(nil, untrusted) // $ querystring=untrusted
|
||||
bdb.Prepare(untrusted) // $ querystring=untrusted
|
||||
bdb.PrepareContext(nil, untrusted) // $ querystring=untrusted
|
||||
bdb.Query(untrusted) // $ querystring=untrusted
|
||||
bdb.QueryContext(nil, untrusted) // $ querystring=untrusted
|
||||
bdb.QueryRow(untrusted) // $ querystring=untrusted
|
||||
bdb.QueryRowContext(nil, untrusted) // $ querystring=untrusted
|
||||
bdb.Exec(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.ExecContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.Prepare(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.PrepareContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.Query(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.QueryContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.QueryRow(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
bdb.QueryRowContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
}
|
||||
|
||||
// BAD: using untrusted data to build SQL queries (QueryBuilder does not sanitize its arguments)
|
||||
func testQueryBuilderMethods(qb orm.QueryBuilder, untrustedSource *http.Request) {
|
||||
untrusted := untrustedSource.UserAgent()
|
||||
untrusted2 := untrustedSource.UserAgent()
|
||||
untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
untrusted2 := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
|
||||
qb.Select(untrusted) // $ querystring=untrusted
|
||||
qb.From(untrusted) // $ querystring=untrusted
|
||||
qb.InnerJoin(untrusted) // $ querystring=untrusted
|
||||
qb.LeftJoin(untrusted) // $ querystring=untrusted
|
||||
qb.RightJoin(untrusted) // $ querystring=untrusted
|
||||
qb.On(untrusted) // $ querystring=untrusted
|
||||
qb.Where(untrusted) // $ querystring=untrusted
|
||||
qb.And(untrusted) // $ querystring=untrusted
|
||||
qb.Or(untrusted) // $ querystring=untrusted
|
||||
qb.In(untrusted) // $ querystring=untrusted
|
||||
qb.OrderBy(untrusted) // $ querystring=untrusted
|
||||
qb.GroupBy(untrusted) // $ querystring=untrusted
|
||||
qb.Having(untrusted) // $ querystring=untrusted
|
||||
qb.Update(untrusted) // $ querystring=untrusted
|
||||
qb.Set(untrusted) // $ querystring=untrusted
|
||||
qb.Delete(untrusted) // $ querystring=untrusted
|
||||
qb.InsertInto(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2
|
||||
qb.Values(untrusted) // $ querystring=untrusted
|
||||
qb.Subquery(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2
|
||||
qb.Select(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.From(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.InnerJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.LeftJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.RightJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.On(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Where(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.And(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Or(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.In(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.OrderBy(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.GroupBy(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Having(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Update(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Set(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Delete(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.InsertInto(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 Alert[go/sql-injection]
|
||||
qb.Values(untrusted) // $ querystring=untrusted Alert[go/sql-injection]
|
||||
qb.Subquery(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 Alert[go/sql-injection]
|
||||
}
|
||||
|
||||
func testOrmerRaw(ormer orm.Ormer, untrustedSource *http.Request) {
|
||||
untrusted := untrustedSource.UserAgent()
|
||||
untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
untrusted2 := untrustedSource.UserAgent()
|
||||
ormer.Raw(untrusted, untrusted2) // $ querystring=untrusted // BAD: using an untrusted string as a query
|
||||
ormer.Raw(untrusted, untrusted2) // $ querystring=untrusted Alert[go/sql-injection] // BAD: using an untrusted string as a query
|
||||
ormer.Raw("FROM ? SELECT ?", untrusted, untrusted2) // $ querystring="FROM ? SELECT ?" // GOOD: untrusted string used in argument context
|
||||
}
|
||||
|
||||
func testFilterRaw(querySeter orm.QuerySeter, untrustedSource *http.Request) {
|
||||
untrusted := untrustedSource.UserAgent()
|
||||
querySeter.FilterRaw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name
|
||||
querySeter.FilterRaw("safe", untrusted) // $ querystring=untrusted // BAD: untrusted used as a SQL fragment
|
||||
untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
querySeter.FilterRaw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name
|
||||
querySeter.FilterRaw("safe", untrusted) // $ querystring=untrusted Alert[go/sql-injection] // BAD: untrusted used as a SQL fragment
|
||||
}
|
||||
|
||||
func testConditionRaw(cond orm.Condition, untrustedSource *http.Request) {
|
||||
untrusted := untrustedSource.UserAgent()
|
||||
cond.Raw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name
|
||||
cond.Raw("safe", untrusted) // $ querystring=untrusted // BAD: untrusted used as a SQL fragment
|
||||
untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection]
|
||||
cond.Raw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name
|
||||
cond.Raw("safe", untrusted) // $ querystring=untrusted Alert[go/sql-injection] // BAD: untrusted used as a SQL fragment
|
||||
}
|
||||
|
||||
type SubStruct struct {
|
||||
@@ -77,90 +77,90 @@ type MyStruct struct {
|
||||
// BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response
|
||||
func testOrmerReads(ormer orm.Ormer, sink http.ResponseWriter) {
|
||||
obj := MyStruct{}
|
||||
ormer.Read(&obj)
|
||||
sink.Write([]byte(obj.field))
|
||||
sink.Write([]byte(obj.substructs[0].field))
|
||||
ormer.Read(&obj) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(obj.field)) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(obj.substructs[0].field)) // $ Alert[go/stored-xss]
|
||||
|
||||
obj2 := MyStruct{}
|
||||
ormer.ReadForUpdate(&obj2)
|
||||
sink.Write([]byte(obj2.field))
|
||||
ormer.ReadForUpdate(&obj2) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(obj2.field)) // $ Alert[go/stored-xss]
|
||||
|
||||
obj3 := MyStruct{}
|
||||
ormer.ReadOrCreate(&obj3, "arg")
|
||||
sink.Write([]byte(obj3.field))
|
||||
ormer.ReadOrCreate(&obj3, "arg") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(obj3.field)) // $ Alert[go/stored-xss]
|
||||
}
|
||||
|
||||
// BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response
|
||||
func testFieldReads(textField *orm.TextField, jsonField *orm.JSONField, jsonbField *orm.JsonbField, sink http.ResponseWriter) {
|
||||
sink.Write([]byte(textField.Value()))
|
||||
sink.Write([]byte(textField.RawValue().(string)))
|
||||
sink.Write([]byte(textField.String()))
|
||||
sink.Write([]byte(jsonField.Value()))
|
||||
sink.Write([]byte(jsonField.RawValue().(string)))
|
||||
sink.Write([]byte(jsonField.String()))
|
||||
sink.Write([]byte(jsonbField.Value()))
|
||||
sink.Write([]byte(jsonbField.RawValue().(string)))
|
||||
sink.Write([]byte(jsonbField.String()))
|
||||
sink.Write([]byte(textField.Value())) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(textField.RawValue().(string))) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(textField.String())) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonField.Value())) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonField.RawValue().(string))) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonField.String())) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonbField.Value())) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonbField.RawValue().(string))) // $ Alert[go/stored-xss]
|
||||
sink.Write([]byte(jsonbField.String())) // $ Alert[go/stored-xss]
|
||||
}
|
||||
|
||||
// BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response
|
||||
func testQuerySeterReads(qs orm.QuerySeter, sink http.ResponseWriter) {
|
||||
var objs []*MyStruct
|
||||
qs.All(&objs)
|
||||
sink.Write([]byte(objs[0].field))
|
||||
qs.All(&objs) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(objs[0].field)) // $ Alert[go/stored-xss]
|
||||
|
||||
var obj MyStruct
|
||||
qs.One(&obj)
|
||||
sink.Write([]byte(obj.field))
|
||||
qs.One(&obj) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(obj.field)) // $ Alert[go/stored-xss]
|
||||
|
||||
var allMaps []orm.Params
|
||||
qs.Values(&allMaps)
|
||||
sink.Write([]byte(allMaps[0]["field"].(string)))
|
||||
qs.Values(&allMaps) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(allMaps[0]["field"].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var allLists []orm.ParamsList
|
||||
qs.ValuesList(&allLists)
|
||||
sink.Write([]byte(allLists[0][0].(string)))
|
||||
qs.ValuesList(&allLists) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(allLists[0][0].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneList orm.ParamsList
|
||||
qs.ValuesFlat(&oneList, "colname")
|
||||
sink.Write([]byte(oneList[0].(string)))
|
||||
qs.ValuesFlat(&oneList, "colname") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneList[0].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneRowMap orm.Params
|
||||
qs.RowsToMap(&oneRowMap, "key", "value")
|
||||
sink.Write([]byte(oneRowMap["field"].(string)))
|
||||
qs.RowsToMap(&oneRowMap, "key", "value") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneRowMap["field"].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneRowStruct MyStruct
|
||||
qs.RowsToStruct(&oneRowStruct, "key", "value")
|
||||
sink.Write([]byte(oneRowStruct.field))
|
||||
qs.RowsToStruct(&oneRowStruct, "key", "value") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneRowStruct.field)) // $ Alert[go/stored-xss]
|
||||
}
|
||||
|
||||
// BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response
|
||||
func testRawSeterReads(rs orm.RawSeter, sink http.ResponseWriter) {
|
||||
var allMaps []orm.Params
|
||||
rs.Values(&allMaps)
|
||||
sink.Write([]byte(allMaps[0]["field"].(string)))
|
||||
rs.Values(&allMaps) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(allMaps[0]["field"].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var allLists []orm.ParamsList
|
||||
rs.ValuesList(&allLists)
|
||||
sink.Write([]byte(allLists[0][0].(string)))
|
||||
rs.ValuesList(&allLists) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(allLists[0][0].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneList orm.ParamsList
|
||||
rs.ValuesFlat(&oneList, "colname")
|
||||
sink.Write([]byte(oneList[0].(string)))
|
||||
rs.ValuesFlat(&oneList, "colname") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneList[0].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneRowMap orm.Params
|
||||
rs.RowsToMap(&oneRowMap, "key", "value")
|
||||
sink.Write([]byte(oneRowMap["field"].(string)))
|
||||
rs.RowsToMap(&oneRowMap, "key", "value") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneRowMap["field"].(string))) // $ Alert[go/stored-xss]
|
||||
|
||||
var oneRowStruct MyStruct
|
||||
rs.RowsToStruct(&oneRowStruct, "key", "value")
|
||||
sink.Write([]byte(oneRowStruct.field))
|
||||
rs.RowsToStruct(&oneRowStruct, "key", "value") // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(oneRowStruct.field)) // $ Alert[go/stored-xss]
|
||||
|
||||
var strField string
|
||||
rs.QueryRow(&strField)
|
||||
sink.Write([]byte(strField))
|
||||
rs.QueryRow(&strField) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(strField)) // $ Alert[go/stored-xss]
|
||||
|
||||
var strFields []string
|
||||
rs.QueryRows(&strFields)
|
||||
sink.Write([]byte(strFields[0]))
|
||||
rs.QueryRows(&strFields) // $ Source[go/stored-xss]
|
||||
sink.Write([]byte(strFields[0])) // $ Alert[go/stored-xss]
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-079/ReflectedXss.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -10,7 +10,7 @@ var hidden string
|
||||
|
||||
func hideUserData(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
hidden = r.URL.Path
|
||||
hidden = r.URL.Path // $ Source
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -18,10 +18,10 @@ func hideUserData(next http.Handler) http.Handler {
|
||||
func main() {
|
||||
r := chi.NewRouter()
|
||||
r.With(hideUserData).Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(hidden))
|
||||
w.Write([]byte(chi.URLParam(r, "someParam")))
|
||||
w.Write([]byte(chi.URLParamFromCtx(r.Context(), "someKey")))
|
||||
w.Write([]byte(chi.RouteContext(r.Context()).URLParam("someOtherKey")))
|
||||
w.Write([]byte(hidden)) // $ Alert
|
||||
w.Write([]byte(chi.URLParam(r, "someParam"))) // $ Alert
|
||||
w.Write([]byte(chi.URLParamFromCtx(r.Context(), "someKey"))) // $ Alert
|
||||
w.Write([]byte(chi.RouteContext(r.Context()).URLParam("someOtherKey"))) // $ Alert
|
||||
})
|
||||
http.ListenAndServe(":3000", r)
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-601/OpenUrlRedirect.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-079/ReflectedXss.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-022/TaintedPath.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -12,81 +12,81 @@ import (
|
||||
// All are XSS vulnerabilities, except as specifically noted.
|
||||
|
||||
func testParam(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.HTML(200, param)
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, param) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testParamValues(ctx echo.Context) error {
|
||||
param := ctx.ParamValues()[0]
|
||||
ctx.HTML(200, param)
|
||||
param := ctx.ParamValues()[0] // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, param) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testQueryParam(ctx echo.Context) error {
|
||||
param := ctx.QueryParam("someParam")
|
||||
ctx.HTML(200, param)
|
||||
param := ctx.QueryParam("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, param) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testQueryParams(ctx echo.Context) error {
|
||||
param := ctx.QueryParams()["someParam"][0]
|
||||
ctx.HTML(200, param)
|
||||
param := ctx.QueryParams()["someParam"][0] // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, param) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testQueryString(ctx echo.Context) error {
|
||||
qstr := ctx.QueryString()
|
||||
ctx.HTML(200, qstr)
|
||||
qstr := ctx.QueryString() // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, qstr) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testFormValue(ctx echo.Context) error {
|
||||
val := ctx.FormValue("someField")
|
||||
ctx.HTML(200, val)
|
||||
val := ctx.FormValue("someField") // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, val) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testFormParams(ctx echo.Context) error {
|
||||
params, _ := ctx.FormParams()
|
||||
ctx.HTML(200, params["someField"][0])
|
||||
params, _ := ctx.FormParams() // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, params["someField"][0]) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testFormFile(ctx echo.Context) error {
|
||||
fileHeader, _ := ctx.FormFile("someFilename")
|
||||
fileHeader, _ := ctx.FormFile("someFilename") // $ Source[go/reflected-xss]
|
||||
file, _ := fileHeader.Open()
|
||||
buffer := make([]byte, 100)
|
||||
file.Read(buffer)
|
||||
ctx.HTMLBlob(200, buffer)
|
||||
ctx.HTMLBlob(200, buffer) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testMultipartFormValue(ctx echo.Context) error {
|
||||
form, _ := ctx.MultipartForm()
|
||||
ctx.HTML(200, form.Value["someField"][0])
|
||||
form, _ := ctx.MultipartForm() // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, form.Value["someField"][0]) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testMultipartFormFile(ctx echo.Context) error {
|
||||
form, _ := ctx.MultipartForm()
|
||||
form, _ := ctx.MultipartForm() // $ Source[go/reflected-xss]
|
||||
fileHeader := form.File["someFilename"][0]
|
||||
file, _ := fileHeader.Open()
|
||||
buffer := make([]byte, 100)
|
||||
file.Read(buffer)
|
||||
ctx.HTMLBlob(200, buffer)
|
||||
ctx.HTMLBlob(200, buffer) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testCookie(ctx echo.Context) error {
|
||||
val, _ := ctx.Cookie("someKey")
|
||||
ctx.HTML(200, val.Value)
|
||||
val, _ := ctx.Cookie("someKey") // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, val.Value) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testCookies(ctx echo.Context) error {
|
||||
cookies := ctx.Cookies()
|
||||
ctx.HTML(200, cookies[0].Value)
|
||||
cookies := ctx.Cookies() // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, cookies[0].Value) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ type myStruct struct {
|
||||
|
||||
func testBind(ctx echo.Context) error {
|
||||
data := myStruct{}
|
||||
ctx.Bind(&data)
|
||||
ctx.HTML(200, data.s)
|
||||
ctx.Bind(&data) // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, data.s) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -110,8 +110,8 @@ func testGetSetEmpty(ctx echo.Context) error {
|
||||
}
|
||||
|
||||
func testGetSet(ctx echo.Context) error {
|
||||
ctx.Set("someKey", ctx.Param("someParam"))
|
||||
ctx.HTML(200, ctx.Get("someKey").(string)) // BAD, the context is tainted
|
||||
ctx.Set("someKey", ctx.Param("someParam")) // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, ctx.Get("someKey").(string)) // $ Alert[go/reflected-xss] // BAD, the context is tainted
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -121,20 +121,20 @@ func testGetSet(ctx echo.Context) error {
|
||||
// All are XSS vulnerabilities, except as specifically noted.
|
||||
|
||||
func testHTML(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.HTML(200, param)
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.HTML(200, param) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testHTMLBlob(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.HTMLBlob(200, []byte(param))
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.HTMLBlob(200, []byte(param)) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testBlob(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.Blob(200, "text/html", []byte(param)) // BAD, the content-type is HTML
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.Blob(200, "text/html", []byte(param)) // $ Alert[go/reflected-xss] // BAD, the content-type is HTML
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -145,9 +145,9 @@ func testBlobSafe(ctx echo.Context) error {
|
||||
}
|
||||
|
||||
func testStream(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
reader := strings.NewReader(param)
|
||||
ctx.Stream(200, "text/html", reader) // BAD, the content-type is HTML
|
||||
ctx.Stream(200, "text/html", reader) // $ Alert[go/reflected-xss] // BAD, the content-type is HTML
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -161,28 +161,28 @@ func testStreamSafe(ctx echo.Context) error {
|
||||
// Section: testing output methods defined on Response (XSS vulnerability)
|
||||
|
||||
func testResponseWrite(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.Response().Write([]byte(param))
|
||||
param := ctx.Param("someParam") // $ Source[go/reflected-xss]
|
||||
ctx.Response().Write([]byte(param)) // $ Alert[go/reflected-xss]
|
||||
return nil
|
||||
}
|
||||
|
||||
// Section: test detecting an open redirect using the Context.Redirect function:
|
||||
|
||||
func testRedirect(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
ctx.Redirect(301, param)
|
||||
param := ctx.Param("someParam") // $ Source[go/unvalidated-url-redirection]
|
||||
ctx.Redirect(301, param) // $ Alert[go/unvalidated-url-redirection]
|
||||
return nil
|
||||
}
|
||||
|
||||
func testLocalRedirects(ctx echo.Context) error {
|
||||
param := ctx.Param("someParam")
|
||||
param := ctx.Param("someParam") // $ Source[go/unvalidated-url-redirection]
|
||||
param2 := param
|
||||
param3 := param
|
||||
// Gratuitous copy because sanitization of uses propagates to subsequent uses
|
||||
// GOOD: local redirects are unproblematic
|
||||
ctx.Redirect(301, "/local"+param)
|
||||
// BAD: this could be a non-local redirect
|
||||
ctx.Redirect(301, "/"+param2)
|
||||
ctx.Redirect(301, "/"+param2) // $ Alert[go/unvalidated-url-redirection]
|
||||
// GOOD: localhost redirects are unproblematic
|
||||
ctx.Redirect(301, "//localhost/"+param3)
|
||||
return nil
|
||||
@@ -221,12 +221,12 @@ func testNonExploitableFields(ctx echo.Context) error {
|
||||
func fsOpsTest() {
|
||||
e := echo.New()
|
||||
e.GET("/", func(c echo.Context) error {
|
||||
filepath := c.QueryParam("filePath")
|
||||
return c.File(filepath) // $ FileSystemAccess=filepath
|
||||
filepath := c.QueryParam("filePath") // $ Source[go/path-injection]
|
||||
return c.File(filepath) // $ FileSystemAccess=filepath Alert[go/path-injection]
|
||||
})
|
||||
e.GET("/attachment", func(c echo.Context) error {
|
||||
filepath := c.QueryParam("filePath")
|
||||
return c.Attachment(filepath, "file name in response") // $ FileSystemAccess=filepath
|
||||
filepath := c.QueryParam("filePath") // $ Source[go/path-injection]
|
||||
return c.Attachment(filepath, "file name in response") // $ FileSystemAccess=filepath Alert[go/path-injection]
|
||||
})
|
||||
_ = e.Start(":1323")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#select
|
||||
| main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value |
|
||||
edges
|
||||
| main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | provenance | |
|
||||
nodes
|
||||
| main.go:18:46:18:48 | definition of req | semmle.label | definition of req |
|
||||
| main.go:21:28:21:31 | name | semmle.label | name |
|
||||
subpaths
|
||||
#select
|
||||
| main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Security/CWE-117/LogInjection.ql
|
||||
query: Security/CWE-117/LogInjection.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -15,10 +15,10 @@ import (
|
||||
|
||||
type Greeter struct{}
|
||||
|
||||
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="definition of req"
|
||||
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="definition of req" Source
|
||||
// var access
|
||||
name := req.Name
|
||||
fmt.Println("Name :: %s", name)
|
||||
fmt.Println("Name :: %s", name) // $ Alert
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
reverseRead
|
||||
| EndToEnd.go:30:35:30:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:30:35:30:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:36:18:36:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:36:18:36:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:44:18:44:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:44:18:44:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:51:20:51:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:51:20:51:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:58:18:58:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:58:18:58:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:64:26:64:26 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:64:26:64:33 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:69:22:69:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:69:22:69:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:74:22:74:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:74:22:74:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:79:35:79:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:79:35:79:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:84:22:84:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:84:22:84:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:89:21:89:21 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:89:21:89:28 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:94:20:94:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:94:20:94:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:31:35:31:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:31:35:31:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:37:18:37:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:37:18:37:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:45:18:45:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:45:18:45:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:52:20:52:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:52:20:52:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:59:18:59:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:59:18:59:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:65:26:65:26 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:65:26:65:33 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:70:22:70:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:70:22:70:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:75:22:75:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:75:22:75:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:80:35:80:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:80:35:80:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:85:22:85:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:85:22:85:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:90:21:90:21 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:90:21:90:28 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:95:20:95:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| EndToEnd.go:95:20:95:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
| Revel.go:26:7:26:7 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| Revel.go:27:7:27:7 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. |
|
||||
| Revel.go:27:7:27:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||
|
||||
@@ -3,10 +3,11 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
staticControllers "github.com/revel/modules/static/app/controllers"
|
||||
"github.com/revel/revel"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
staticControllers "github.com/revel/modules/static/app/controllers"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// Use typical inheritence pattern, per github.com/revel/examples/booking:
|
||||
@@ -33,8 +34,8 @@ func (c MyRoute) Handler1() revel.Result {
|
||||
func (c MyRoute) Handler2() revel.Result {
|
||||
// BAD: the RenderBinary function copies an `io.Reader` to the user's browser.
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(c.Params.Form.Get("someField"))
|
||||
return c.RenderBinary(buf, "index.html", revel.Inline, time.Now()) // $ responsebody='buf'
|
||||
buf.WriteString(c.Params.Form.Get("someField")) // $ Source[go/reflected-xss]
|
||||
return c.RenderBinary(buf, "index.html", revel.Inline, time.Now()) // $ responsebody='buf' Alert[go/reflected-xss]
|
||||
}
|
||||
|
||||
func (c MyRoute) Handler3() revel.Result {
|
||||
@@ -55,18 +56,18 @@ func (c MyRoute) Handler4() revel.Result {
|
||||
func (c MyRoute) Handler5() revel.Result {
|
||||
// BAD: returning an arbitrary file (but this is detected at the os.Open call, not
|
||||
// due to modelling Revel)
|
||||
f, _ := os.Open(c.Params.Form.Get("someField"))
|
||||
f, _ := os.Open(c.Params.Form.Get("someField")) // $ Alert[go/path-injection]
|
||||
return c.RenderFile(f, revel.Inline)
|
||||
}
|
||||
|
||||
func (c MyRoute) Handler6() revel.Result {
|
||||
// BAD: returning an arbitrary file (detected as a user-controlled file-op, not XSS)
|
||||
return c.RenderFileName(c.Params.Form.Get("someField"), revel.Inline)
|
||||
return c.RenderFileName(c.Params.Form.Get("someField"), revel.Inline) // $ Alert[go/path-injection]
|
||||
}
|
||||
|
||||
func (c MyRoute) Handler7() revel.Result {
|
||||
// BAD: straightforward XSS
|
||||
return c.RenderHTML(c.Params.Form.Get("someField")) // $ responsebody='call to Get'
|
||||
return c.RenderHTML(c.Params.Form.Get("someField")) // $ responsebody='call to Get' Alert[go/reflected-xss]
|
||||
}
|
||||
|
||||
func (c MyRoute) Handler8() revel.Result {
|
||||
@@ -91,5 +92,5 @@ func (c MyRoute) Handler11() revel.Result {
|
||||
|
||||
func (c MyRoute) Handler12() revel.Result {
|
||||
// BAD: open redirect
|
||||
return c.Redirect(c.Params.Form.Get("someField"))
|
||||
return c.Redirect(c.Params.Form.Get("someField")) // $ Alert[go/unvalidated-url-redirection]
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#select
|
||||
| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value |
|
||||
| EndToEnd.go:95:20:95:49 | call to Get | EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:95:20:95:27 | selection of Params | user-provided value |
|
||||
edges
|
||||
| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | provenance | Config |
|
||||
| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Config |
|
||||
| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Src:MaD:2 Config |
|
||||
| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Src:MaD:2 Config |
|
||||
| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Config |
|
||||
| EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | provenance | Config Sink:MaD:1 |
|
||||
| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | provenance | Config |
|
||||
| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Config |
|
||||
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Src:MaD:2 Config |
|
||||
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Src:MaD:2 Config |
|
||||
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Config |
|
||||
| EndToEnd.go:95:20:95:32 | selection of Form | EndToEnd.go:95:20:95:49 | call to Get | provenance | Config Sink:MaD:1 |
|
||||
models
|
||||
| 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual |
|
||||
| 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual |
|
||||
nodes
|
||||
| EndToEnd.go:94:20:94:27 | implicit dereference | semmle.label | implicit dereference |
|
||||
| EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] |
|
||||
| EndToEnd.go:94:20:94:32 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get |
|
||||
| EndToEnd.go:95:20:95:27 | implicit dereference | semmle.label | implicit dereference |
|
||||
| EndToEnd.go:95:20:95:27 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] |
|
||||
| EndToEnd.go:95:20:95:32 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:95:20:95:49 | call to Get | semmle.label | call to Get |
|
||||
subpaths
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-601/OpenUrlRedirect.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#select
|
||||
| EndToEnd.go:37:24:37:26 | buf | EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:37:24:37:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:36:18:36:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | |
|
||||
| EndToEnd.go:69:22:69:51 | call to Get | EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:69:22:69:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | |
|
||||
| EndToEnd.go:38:24:38:26 | buf | EndToEnd.go:37:18:37:25 | selection of Params | EndToEnd.go:38:24:38:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:37:18:37:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | |
|
||||
| EndToEnd.go:70:22:70:51 | call to Get | EndToEnd.go:70:22:70:29 | selection of Params | EndToEnd.go:70:22:70:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:70:22:70:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | |
|
||||
| Revel.go:70:22:70:35 | selection of Query | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | Cross-site scripting vulnerability due to $@. The value is $@. | Revel.go:70:22:70:29 | selection of Params | user-provided value | views/myAppController/rawRead.html:1:1:2:9 | {{raw .Foo}}\n{{.Bar}}\n | instantiated as a raw template |
|
||||
| examples/booking/app/init.go:36:44:36:53 | selection of Path | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:36:44:36:48 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | |
|
||||
| examples/booking/app/init.go:40:49:40:58 | selection of Path | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:40:49:40:53 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | |
|
||||
edges
|
||||
| EndToEnd.go:36:2:36:4 | buf [postupdate] | EndToEnd.go:37:24:37:26 | buf | provenance | |
|
||||
| EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:36:18:36:30 | selection of Form | provenance | Src:MaD:1 |
|
||||
| EndToEnd.go:36:18:36:30 | selection of Form | EndToEnd.go:36:18:36:47 | call to Get | provenance | MaD:4 |
|
||||
| EndToEnd.go:36:18:36:47 | call to Get | EndToEnd.go:36:2:36:4 | buf [postupdate] | provenance | MaD:3 |
|
||||
| EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:34 | selection of Form | provenance | Src:MaD:1 |
|
||||
| EndToEnd.go:69:22:69:34 | selection of Form | EndToEnd.go:69:22:69:51 | call to Get | provenance | MaD:4 |
|
||||
| EndToEnd.go:37:2:37:4 | buf [postupdate] | EndToEnd.go:38:24:38:26 | buf | provenance | |
|
||||
| EndToEnd.go:37:18:37:25 | selection of Params | EndToEnd.go:37:18:37:30 | selection of Form | provenance | Src:MaD:1 |
|
||||
| EndToEnd.go:37:18:37:30 | selection of Form | EndToEnd.go:37:18:37:47 | call to Get | provenance | MaD:4 |
|
||||
| EndToEnd.go:37:18:37:47 | call to Get | EndToEnd.go:37:2:37:4 | buf [postupdate] | provenance | MaD:3 |
|
||||
| EndToEnd.go:70:22:70:29 | selection of Params | EndToEnd.go:70:22:70:34 | selection of Form | provenance | Src:MaD:1 |
|
||||
| EndToEnd.go:70:22:70:34 | selection of Form | EndToEnd.go:70:22:70:51 | call to Get | provenance | MaD:4 |
|
||||
| Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | provenance | Src:MaD:1 |
|
||||
| examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | provenance | Src:MaD:2 |
|
||||
| examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | provenance | Src:MaD:2 |
|
||||
@@ -20,14 +20,14 @@ models
|
||||
| 3 | Summary: io; StringWriter; true; WriteString; ; ; Argument[0]; Argument[receiver]; taint; manual |
|
||||
| 4 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual |
|
||||
nodes
|
||||
| EndToEnd.go:36:2:36:4 | buf [postupdate] | semmle.label | buf [postupdate] |
|
||||
| EndToEnd.go:36:18:36:25 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:36:18:36:30 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:36:18:36:47 | call to Get | semmle.label | call to Get |
|
||||
| EndToEnd.go:37:24:37:26 | buf | semmle.label | buf |
|
||||
| EndToEnd.go:69:22:69:29 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:69:22:69:34 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:69:22:69:51 | call to Get | semmle.label | call to Get |
|
||||
| EndToEnd.go:37:2:37:4 | buf [postupdate] | semmle.label | buf [postupdate] |
|
||||
| EndToEnd.go:37:18:37:25 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:37:18:37:30 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:37:18:37:47 | call to Get | semmle.label | call to Get |
|
||||
| EndToEnd.go:38:24:38:26 | buf | semmle.label | buf |
|
||||
| EndToEnd.go:70:22:70:29 | selection of Params | semmle.label | selection of Params |
|
||||
| EndToEnd.go:70:22:70:34 | selection of Form | semmle.label | selection of Form |
|
||||
| EndToEnd.go:70:22:70:51 | call to Get | semmle.label | call to Get |
|
||||
| Revel.go:70:22:70:29 | selection of Params | semmle.label | selection of Params |
|
||||
| Revel.go:70:22:70:35 | selection of Query | semmle.label | selection of Query |
|
||||
| examples/booking/app/init.go:36:44:36:48 | selection of URL | semmle.label | selection of URL |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user