mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into post-release-prep/codeql-cli-2.23.5
This commit is contained in:
16
.github/workflows/build-ripunzip.yml
vendored
16
.github/workflows/build-ripunzip.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build runzip
|
||||
name: Build ripunzip
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -6,24 +6,28 @@ on:
|
||||
ripunzip-version:
|
||||
description: "what reference to checktout from google/runzip"
|
||||
required: false
|
||||
default: v2.0.2
|
||||
openssl-version:
|
||||
description: "what reference to checkout from openssl/openssl for Linux"
|
||||
required: false
|
||||
default: openssl-3.5.0
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/build-ripunzip.yml
|
||||
env:
|
||||
RIPUNZIP_DEFAULT: v2.0.3
|
||||
OPENSSL_DEFAULT: openssl-3.6.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macos-13, windows-2022]
|
||||
os: [ubuntu-24.04, macos-15, windows-2025]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: google/ripunzip
|
||||
ref: ${{ inputs.ripunzip-version }}
|
||||
ref: ${{ inputs.ripunzip-version || env.RIPUNZIP_DEFAULT }}
|
||||
# we need to avoid ripunzip dynamically linking into libssl
|
||||
# see https://github.com/sfackler/rust-openssl/issues/183
|
||||
- if: runner.os == 'Linux'
|
||||
@@ -32,7 +36,7 @@ jobs:
|
||||
with:
|
||||
repository: openssl/openssl
|
||||
path: openssl
|
||||
ref: ${{ inputs.openssl-version }}
|
||||
ref: ${{ inputs.openssl-version || env.OPENSSL_DEFAULT }}
|
||||
- if: runner.os == 'Linux'
|
||||
name: build and install openssl with fPIC
|
||||
shell: bash
|
||||
|
||||
16
CODEOWNERS
16
CODEOWNERS
@@ -5,19 +5,29 @@
|
||||
/actions/ @github/codeql-dynamic
|
||||
/cpp/ @github/codeql-c-analysis
|
||||
/csharp/ @github/codeql-csharp
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor @github/code-scanning-language-coverage
|
||||
/go/ @github/codeql-go
|
||||
/go/codeql-tools/ @github/codeql-go @github/code-scanning-language-coverage
|
||||
/go/downgrades/ @github/codeql-go @github/code-scanning-language-coverage
|
||||
/go/extractor/ @github/codeql-go @github/code-scanning-language-coverage
|
||||
/go/extractor-smoke-test/ @github/codeql-go @github/code-scanning-language-coverage
|
||||
/go/ql/test/extractor-tests/ @github/codeql-go @github/code-scanning-language-coverage
|
||||
/java/ @github/codeql-java
|
||||
/javascript/ @github/codeql-javascript
|
||||
/javascript/extractor/ @github/codeql-javascript @github/code-scanning-language-coverage
|
||||
/python/ @github/codeql-python
|
||||
/python/extractor/ @github/codeql-python @github/code-scanning-language-coverage
|
||||
/ql/ @github/codeql-ql-for-ql-reviewers
|
||||
/ruby/ @github/codeql-ruby
|
||||
/ruby/extractor/ @github/codeql-ruby @github/code-scanning-language-coverage
|
||||
/rust/ @github/codeql-rust
|
||||
/rust/extractor/ @github/codeql-rust @github/code-scanning-language-coverage
|
||||
/shared/ @github/codeql-shared-libraries-reviewers
|
||||
/swift/ @github/codeql-swift
|
||||
/swift/extractor/ @github/codeql-swift @github/code-scanning-language-coverage
|
||||
/misc/codegen/ @github/codeql-swift
|
||||
/java/kotlin-extractor/ @github/codeql-kotlin
|
||||
/java/kotlin-extractor/ @github/codeql-kotlin @github/code-scanning-language-coverage
|
||||
/java/ql/test-kotlin1/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin2/ @github/codeql-kotlin
|
||||
|
||||
|
||||
2437
cpp/downgrades/2121ffec11fac265524955fee1775217364d4ca4/old.dbscheme
Normal file
2437
cpp/downgrades/2121ffec11fac265524955fee1775217364d4ca4/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 decltype qualifier issue
|
||||
compatibility: full
|
||||
9
cpp/ql/lib/ext/cctype.model.yml
Normal file
9
cpp/ql/lib/ext/cctype.model.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "tolower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["std", "", False, "tolower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["", "", False, "toupper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["std", "", False, "toupper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
7
cpp/ql/lib/ext/iconv.model.yml
Normal file
7
cpp/ql/lib/ext/iconv.model.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "iconv", "", "", "Argument[**1]", "Argument[**3]", "value", "manual"]
|
||||
|
||||
@@ -144,14 +144,14 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
|
||||
class NameQualifyingElement extends Element, @namequalifyingelement {
|
||||
/**
|
||||
* Gets a name qualifier for which this is the qualifying namespace or
|
||||
* user-defined type. For example: class `X` is the
|
||||
* user-defined type, or decltype. For example: class `X` is the
|
||||
* `NameQualifyingElement` and `X::` is the `NameQualifier`.
|
||||
*/
|
||||
NameQualifier getANameQualifier() {
|
||||
namequalifiers(unresolveElement(result), _, underlyingElement(this), _)
|
||||
}
|
||||
|
||||
/** Gets the name of this namespace or user-defined type. */
|
||||
/** Gets the name of this namespace, user-defined type, or decltype. */
|
||||
string getName() { none() }
|
||||
}
|
||||
|
||||
|
||||
@@ -1146,7 +1146,7 @@ class DerivedType extends Type, @derivedtype {
|
||||
* decltype(a) b;
|
||||
* ```
|
||||
*/
|
||||
class Decltype extends Type {
|
||||
class Decltype extends Type, NameQualifyingElement {
|
||||
Decltype() { decltypes(underlyingElement(this), _, 0, _, _) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Decltype" }
|
||||
@@ -1187,7 +1187,7 @@ class Decltype extends Type {
|
||||
|
||||
override string toString() { result = "decltype(...)" }
|
||||
|
||||
override string getName() { none() }
|
||||
override string getName() { result = "decltype(...)" }
|
||||
|
||||
override int getSize() { result = this.getBaseType().getSize() }
|
||||
|
||||
@@ -1247,7 +1247,7 @@ class TypeofType extends Type {
|
||||
|
||||
override string toString() { result = "typeof(...)" }
|
||||
|
||||
override string getName() { none() }
|
||||
override string getName() { result = "typeof(...)" }
|
||||
|
||||
override int getSize() { result = this.getBaseType().getSize() }
|
||||
|
||||
@@ -1311,8 +1311,6 @@ class TypeofTypeType extends TypeofType {
|
||||
Type getType() { type_operators(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeofTypeType" }
|
||||
|
||||
override string toString() { result = "typeof(...)" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1394,7 +1392,7 @@ class IntrinsicTransformedType extends Type {
|
||||
|
||||
override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
|
||||
|
||||
override string getName() { none() }
|
||||
override string getName() { result = this.getIntrinsicName() + "(...)" }
|
||||
|
||||
override int getSize() { result = this.getBaseType().getSize() }
|
||||
|
||||
|
||||
@@ -703,6 +703,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
override predicate comparesLt(
|
||||
Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue
|
||||
) {
|
||||
@@ -713,6 +714,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) {
|
||||
exists(GuardValue partValue, GuardCondition part |
|
||||
this.(Cpp::BinaryLogicalOperation)
|
||||
@@ -738,6 +740,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
override predicate comparesEq(
|
||||
Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue
|
||||
) {
|
||||
@@ -757,6 +760,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) {
|
||||
exists(GuardValue partValue, GuardCondition part |
|
||||
this.(Cpp::BinaryLogicalOperation)
|
||||
|
||||
@@ -656,6 +656,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
|
||||
* Normalize the `n`'th parameter of `f` by replacing template names
|
||||
* with `class:N` (where `N` is the index of the template).
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
|
||||
// If there is a declaring type then we start by expanding the function templates
|
||||
exists(Class template |
|
||||
@@ -727,6 +728,7 @@ private string getSignatureWithoutClassTemplateNames(
|
||||
* - The `remaining` number of template arguments in `partiallyNormalizedSignature`
|
||||
* with their index in `nameArgs`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private string getSignatureWithoutFunctionTemplateNames(
|
||||
string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining
|
||||
) {
|
||||
@@ -770,6 +772,7 @@ private string getSignatureWithoutFunctionTemplateNames(
|
||||
* ```
|
||||
* In this case, `normalizedSignature` will be `"(const func:0 &,int,class:1,class:0 *)"`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate elementSpecWithArguments(
|
||||
string signature, string type, string name, string normalizedSignature, string typeArgs,
|
||||
string nameArgs
|
||||
@@ -789,6 +792,35 @@ private string getSignatureParameterName(string signature, string type, string n
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `Function` identified by the `(namespace, type, name)` components.
|
||||
*
|
||||
* If `subtypes` is `true` then the result may be an override of the function
|
||||
* identified by the components.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Function getFunction(string namespace, string type, boolean subtypes, string name) {
|
||||
elementSpec(namespace, type, subtypes, name, _, _) and
|
||||
(
|
||||
funcHasQualifiedName(result, namespace, name) and
|
||||
subtypes = false and
|
||||
type = ""
|
||||
or
|
||||
exists(Class namedClass, Class classWithMethod |
|
||||
hasClassAndName(classWithMethod, result, name) and
|
||||
classHasQualifiedName(namedClass, namespace, type)
|
||||
|
|
||||
// member declared in the named type or a subtype of it
|
||||
subtypes = true and
|
||||
classWithMethod = namedClass.getADerivedClass*()
|
||||
or
|
||||
// member declared directly in the named type
|
||||
subtypes = false and
|
||||
classWithMethod = namedClass
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the suffix containing the entries in `signature` starting at entry
|
||||
* `i` matches the suffix containing the parameters of `func` starting at entry `i`.
|
||||
@@ -812,13 +844,17 @@ private string getSignatureParameterName(string signature, string type, string n
|
||||
* is `func:n` then the signature name is compared with the `n`'th name
|
||||
* in `name`.
|
||||
*/
|
||||
private predicate signatureMatches(Function func, string signature, string type, string name, int i) {
|
||||
pragma[nomagic]
|
||||
private predicate signatureMatches(
|
||||
Function func, string namespace, string signature, string type, string name, int i
|
||||
) {
|
||||
func = getFunction(namespace, type, _, name) and
|
||||
exists(string s |
|
||||
s = getSignatureParameterName(signature, type, name, i) and
|
||||
s = getParameterTypeName(func, i)
|
||||
) and
|
||||
if exists(getParameterTypeName(func, i + 1))
|
||||
then signatureMatches(func, signature, type, name, i + 1)
|
||||
then signatureMatches(func, namespace, signature, type, name, i + 1)
|
||||
else i = count(signature.indexOf(","))
|
||||
}
|
||||
|
||||
@@ -833,7 +869,7 @@ module ExternalFlowDebug {
|
||||
*
|
||||
* Exposed for testing purposes.
|
||||
*/
|
||||
predicate signatureMatches_debug = signatureMatches/5;
|
||||
predicate signatureMatches_debug = signatureMatches/6;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -883,6 +919,7 @@ private predicate parseParens(string s, string betweenParens) { s = "(" + betwee
|
||||
* - `signatureWithoutParens` equals `signature`, but with the surrounding
|
||||
* parentheses removed.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate elementSpecWithArguments0(
|
||||
string signature, string type, string name, string signatureWithoutParens, string typeArgs,
|
||||
string nameArgs
|
||||
@@ -909,7 +946,7 @@ private predicate elementSpecMatchesSignature(
|
||||
) {
|
||||
elementSpec(namespace, pragma[only_bind_into](type), subtypes, pragma[only_bind_into](name),
|
||||
pragma[only_bind_into](signature), _) and
|
||||
signatureMatches(func, signature, type, name, 0)
|
||||
signatureMatches(func, namespace, signature, type, name, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,7 +990,7 @@ private predicate funcHasQualifiedName(Function func, string namespace, string n
|
||||
* Holds if `namedClass` is in namespace `namespace` and has
|
||||
* name `type` (excluding any template parameters).
|
||||
*/
|
||||
bindingset[type, namespace]
|
||||
bindingset[type]
|
||||
pragma[inline_late]
|
||||
private predicate classHasQualifiedName(Class namedClass, string namespace, string type) {
|
||||
exists(string typeWithoutArgs |
|
||||
@@ -969,17 +1006,14 @@ private predicate classHasQualifiedName(Class namedClass, string namespace, stri
|
||||
* are also returned.
|
||||
* 3. The element has name `name`
|
||||
* 4. If `signature` is non-empty, then the element has a list of parameter types described by `signature`.
|
||||
*
|
||||
* NOTE: `namespace` is currently not used (since we don't properly extract modules yet).
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Element interpretElement0(
|
||||
string namespace, string type, boolean subtypes, string name, string signature
|
||||
) {
|
||||
result = getFunction(namespace, type, subtypes, name) and
|
||||
(
|
||||
// Non-member functions
|
||||
funcHasQualifiedName(result, namespace, name) and
|
||||
subtypes = false and
|
||||
type = "" and
|
||||
(
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
|
||||
@@ -989,52 +1023,36 @@ private Element interpretElement0(
|
||||
)
|
||||
or
|
||||
// Member functions
|
||||
exists(Class namedClass, Class classWithMethod |
|
||||
hasClassAndName(classWithMethod, result, name) and
|
||||
classHasQualifiedName(namedClass, namespace, type)
|
||||
|
|
||||
(
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
|
||||
or
|
||||
signature = "" and
|
||||
elementSpec(namespace, type, subtypes, name, "", _)
|
||||
) and
|
||||
(
|
||||
// member declared in the named type or a subtype of it
|
||||
subtypes = true and
|
||||
classWithMethod = namedClass.getADerivedClass*()
|
||||
or
|
||||
// member declared directly in the named type
|
||||
subtypes = false and
|
||||
classWithMethod = namedClass
|
||||
)
|
||||
)
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
|
||||
or
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
// Member variables
|
||||
signature = "" and
|
||||
exists(Class namedClass, Class classWithMember, MemberVariable member |
|
||||
member.getName() = name and
|
||||
member = classWithMember.getAMember() and
|
||||
namedClass.hasQualifiedName(namespace, type) and
|
||||
result = member
|
||||
|
|
||||
// field declared in the named type or a subtype of it (or an extension of any)
|
||||
subtypes = true and
|
||||
classWithMember = namedClass.getADerivedClass*()
|
||||
or
|
||||
// field declared directly in the named type (or an extension of it)
|
||||
subtypes = false and
|
||||
classWithMember = namedClass
|
||||
)
|
||||
or
|
||||
// Global or namespace variables
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
signature = "" and
|
||||
type = "" and
|
||||
subtypes = false and
|
||||
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
|
||||
elementSpec(namespace, type, subtypes, name, signature, _)
|
||||
)
|
||||
or
|
||||
// Member variables
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
signature = "" and
|
||||
exists(Class namedClass, Class classWithMember, MemberVariable member |
|
||||
member.getName() = name and
|
||||
member = classWithMember.getAMember() and
|
||||
namedClass.hasQualifiedName(namespace, type) and
|
||||
result = member
|
||||
|
|
||||
// field declared in the named type or a subtype of it (or an extension of any)
|
||||
subtypes = true and
|
||||
classWithMember = namedClass.getADerivedClass*()
|
||||
or
|
||||
// field declared directly in the named type (or an extension of it)
|
||||
subtypes = false and
|
||||
classWithMember = namedClass
|
||||
)
|
||||
or
|
||||
// Global or namespace variables
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
signature = "" and
|
||||
type = "" and
|
||||
subtypes = false and
|
||||
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
|
||||
}
|
||||
|
||||
cached
|
||||
|
||||
@@ -12,8 +12,8 @@ import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
|
||||
* `__builtin___memcpy_chk`.
|
||||
* The standard functions `memcpy`, `memmove` and `bcopy`; and variants such as
|
||||
* `__builtin___memcpy_chk` and `__builtin___memmove_chk`.
|
||||
*/
|
||||
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
|
||||
AliasFunction, NonCppThrowingFunction
|
||||
@@ -27,7 +27,9 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
|
||||
// bcopy(src, dest, num)
|
||||
// mempcpy(dest, src, num)
|
||||
// memccpy(dest, src, c, n)
|
||||
this.hasGlobalName(["bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk"])
|
||||
this.hasGlobalName([
|
||||
"bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk", "__builtin___memmove_chk"
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,8 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
|
||||
this.hasGlobalOrStdName("wmemset")
|
||||
or
|
||||
this.hasGlobalName([
|
||||
bzero(), "__builtin_memset", "__builtin_memset_chk", "RtlZeroMemory", "RtlSecureZeroMemory"
|
||||
bzero(), "__builtin_memset", "__builtin_memset_chk", "__builtin___memset_chk",
|
||||
"RtlZeroMemory", "RtlSecureZeroMemory"
|
||||
])
|
||||
}
|
||||
|
||||
@@ -32,7 +33,7 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
|
||||
or
|
||||
this.hasGlobalOrStdName("wmemset")
|
||||
or
|
||||
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk"])
|
||||
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk", "__builtin___memset_chk"])
|
||||
) and
|
||||
result = 1
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
|
||||
"_mbsncat", // _mbsncat(dst, src, max_amount)
|
||||
"_mbsncat_l", // _mbsncat_l(dst, src, max_amount, locale)
|
||||
"_mbsnbcat", // _mbsnbcat(dest, src, count)
|
||||
"_mbsnbcat_l" // _mbsnbcat_l(dest, src, count, locale)
|
||||
"_mbsnbcat_l", // _mbsnbcat_l(dest, src, count, locale)
|
||||
"__builtin___strcat_chk", // __builtin___strcat_chk (dest, src, magic)
|
||||
"__builtin___strncat_chk" // __builtin___strncat_chk (dest, src, max_amount, magic)
|
||||
])
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
(
|
||||
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
|
||||
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l", "__builtin___strncat_chk"] and
|
||||
input.isParameter(2)
|
||||
or
|
||||
this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
|
||||
|
||||
@@ -36,7 +36,11 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
|
||||
"_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount)
|
||||
"stpcpy", // stpcpy(dest, src)
|
||||
"stpncpy", // stpncpy(dest, src, max_amount)
|
||||
"strlcpy" // strlcpy(dst, src, dst_size)
|
||||
"strlcpy", // strlcpy(dst, src, dst_size)
|
||||
"__builtin___strcpy_chk", // __builtin___strcpy_chk (dest, src, magic)
|
||||
"__builtin___stpcpy_chk", // __builtin___stpcpy_chk (dest, src, magic)
|
||||
"__builtin___stpncpy_chk", // __builtin___stpncpy_chk(dest, src, max_amount, magic)
|
||||
"__builtin___strncpy_chk" // __builtin___strncpy_chk (dest, src, max_amount, magic)
|
||||
])
|
||||
or
|
||||
(
|
||||
|
||||
@@ -1327,7 +1327,8 @@ specialnamequalifyingelements(
|
||||
@namequalifiableelement = @expr | @namequalifier;
|
||||
@namequalifyingelement = @namespace
|
||||
| @specialnamequalifyingelement
|
||||
| @usertype;
|
||||
| @usertype
|
||||
| @decltype;
|
||||
|
||||
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 decltype qualifier issue
|
||||
compatibility: full
|
||||
@@ -7988,6 +7988,26 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| taint.cpp:841:21:841:35 | call to indirect_source | taint.cpp:843:16:843:17 | fp | |
|
||||
| taint.cpp:842:11:842:12 | ref arg fp | taint.cpp:843:16:843:17 | fp | |
|
||||
| taint.cpp:842:15:842:16 | | taint.cpp:842:11:842:12 | ref arg fp | TAINT |
|
||||
| taint.cpp:851:10:851:15 | call to source | taint.cpp:852:18:852:18 | s | |
|
||||
| taint.cpp:851:10:851:15 | call to source | taint.cpp:854:18:854:18 | s | |
|
||||
| taint.cpp:852:10:852:16 | call to toupper | taint.cpp:853:7:853:7 | u | |
|
||||
| taint.cpp:854:10:854:16 | call to tolower | taint.cpp:855:7:855:7 | l | |
|
||||
| taint.cpp:861:24:861:27 | size | taint.cpp:866:16:866:19 | size | |
|
||||
| taint.cpp:862:12:862:26 | call to indirect_source | taint.cpp:866:12:866:12 | s | |
|
||||
| taint.cpp:863:7:863:9 | out | taint.cpp:864:12:864:14 | out | |
|
||||
| taint.cpp:864:12:864:14 | out | taint.cpp:866:23:866:23 | p | |
|
||||
| taint.cpp:864:12:864:14 | out | taint.cpp:867:8:867:8 | p | |
|
||||
| taint.cpp:865:9:865:16 | size_out | taint.cpp:866:27:866:34 | size_out | |
|
||||
| taint.cpp:866:11:866:12 | ref arg & ... | taint.cpp:866:12:866:12 | s [inner post update] | |
|
||||
| taint.cpp:866:12:866:12 | s | taint.cpp:866:11:866:12 | & ... | |
|
||||
| taint.cpp:866:15:866:19 | ref arg & ... | taint.cpp:866:16:866:19 | size [inner post update] | |
|
||||
| taint.cpp:866:16:866:19 | size | taint.cpp:866:15:866:19 | & ... | |
|
||||
| taint.cpp:866:22:866:23 | ref arg & ... | taint.cpp:866:23:866:23 | p [inner post update] | |
|
||||
| taint.cpp:866:22:866:23 | ref arg & ... | taint.cpp:867:8:867:8 | p | |
|
||||
| taint.cpp:866:23:866:23 | p | taint.cpp:866:22:866:23 | & ... | |
|
||||
| taint.cpp:866:26:866:34 | ref arg & ... | taint.cpp:866:27:866:34 | size_out [inner post update] | |
|
||||
| taint.cpp:866:27:866:34 | size_out | taint.cpp:866:26:866:34 | & ... | |
|
||||
| taint.cpp:867:8:867:8 | p | taint.cpp:867:7:867:8 | * ... | TAINT |
|
||||
| thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | |
|
||||
| thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | |
|
||||
| thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | |
|
||||
|
||||
@@ -842,4 +842,27 @@ int f7(void)
|
||||
fprintf(fp, "");
|
||||
indirect_sink(fp); // $ ir MISSING: ast
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toupper(int);
|
||||
int tolower(int);
|
||||
|
||||
void test_toupper_and_tolower() {
|
||||
int s = source();
|
||||
int u = toupper(s);
|
||||
sink(u); // $ ir MISSING: ast
|
||||
int l = tolower(s);
|
||||
sink(l); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
typedef int iconv_t;
|
||||
size_t iconv(iconv_t cd, char **, size_t *, char **, size_t *);
|
||||
|
||||
void test_iconv(size_t size) {
|
||||
char* s = indirect_source();
|
||||
char out[10];
|
||||
char* p = out;
|
||||
size_t size_out;
|
||||
iconv(0, &s, &size, &p, &size_out);
|
||||
sink(*p); // $ ast,ir
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ import cpp
|
||||
import semmle.code.cpp.dataflow.ExternalFlow
|
||||
import ExternalFlowDebug
|
||||
|
||||
query predicate signatureMatches = signatureMatches_debug/5;
|
||||
query predicate signatureMatches = signatureMatches_debug/6;
|
||||
|
||||
query predicate getSignatureParameterName = getSignatureParameterName_debug/4;
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var compilerCall = compilationData.CompilerCall;
|
||||
var diagnosticName = compilerCall.GetDiagnosticName();
|
||||
logger.LogInfo($" Processing compilation {diagnosticName} at {compilerCall.ProjectDirectory}");
|
||||
var compilerArgs = compilerCall.GetArguments();
|
||||
var compilerArgs = reader.ReadArguments(compilerCall);
|
||||
|
||||
var compilationIdentifierPath = string.Empty;
|
||||
try
|
||||
|
||||
@@ -4,16 +4,16 @@ source https://api.nuget.org/v3/index.json
|
||||
# behave like nuget in choosing transitive dependency versions
|
||||
strategy: max
|
||||
|
||||
nuget Basic.CompilerLog.Util 0.9.8
|
||||
nuget Basic.CompilerLog.Util 0.9.21
|
||||
nuget Mono.Posix.NETStandard
|
||||
nuget Newtonsoft.Json
|
||||
nuget xunit
|
||||
nuget xunit.runner.visualstudio
|
||||
nuget xunit.runner.utility
|
||||
nuget Microsoft.NET.Test.Sdk
|
||||
nuget Microsoft.CodeAnalysis.CSharp 4.12.0
|
||||
nuget Microsoft.CodeAnalysis 4.12.0
|
||||
nuget Microsoft.Build 17.12.6
|
||||
nuget Microsoft.CodeAnalysis.CSharp 4.14.0
|
||||
nuget Microsoft.CodeAnalysis 4.14.0
|
||||
nuget Microsoft.Build 17.14.28
|
||||
nuget Microsoft.Win32.Primitives
|
||||
nuget System.Net.Primitives
|
||||
nuget System.Security.Principal
|
||||
|
||||
273
csharp/paket.lock
generated
273
csharp/paket.lock
generated
@@ -3,143 +3,148 @@ STRATEGY: MAX
|
||||
RESTRICTION: == net9.0
|
||||
NUGET
|
||||
remote: https://api.nuget.org/v3/index.json
|
||||
Basic.CompilerLog.Util (0.9.8)
|
||||
MessagePack (>= 2.5.187)
|
||||
Microsoft.CodeAnalysis (>= 4.12)
|
||||
Microsoft.CodeAnalysis.CSharp (>= 4.12)
|
||||
Microsoft.CodeAnalysis.VisualBasic (>= 4.12)
|
||||
Microsoft.Extensions.ObjectPool (>= 9.0.2)
|
||||
MSBuild.StructuredLogger (>= 2.2.243)
|
||||
System.Buffers (>= 4.6)
|
||||
Basic.CompilerLog.Util (0.9.21)
|
||||
MessagePack (>= 3.1.4)
|
||||
Microsoft.Bcl.Memory (>= 9.0.10)
|
||||
Microsoft.CodeAnalysis (>= 4.8)
|
||||
Microsoft.CodeAnalysis.CSharp (>= 4.8)
|
||||
Microsoft.CodeAnalysis.VisualBasic (>= 4.8)
|
||||
Microsoft.Extensions.ObjectPool (>= 9.0.10)
|
||||
MSBuild.StructuredLogger (>= 2.3.71)
|
||||
NaturalSort.Extension (>= 4.4)
|
||||
Humanizer.Core (2.14.1)
|
||||
MessagePack (3.0.300)
|
||||
MessagePack.Annotations (>= 3.0.300)
|
||||
MessagePackAnalyzer (>= 3.0.300)
|
||||
MessagePack (3.1.4)
|
||||
MessagePack.Annotations (>= 3.1.4)
|
||||
MessagePackAnalyzer (>= 3.1.4)
|
||||
Microsoft.NET.StringTools (>= 17.11.4)
|
||||
MessagePack.Annotations (3.0.300)
|
||||
MessagePackAnalyzer (3.0.300)
|
||||
Microsoft.Bcl.AsyncInterfaces (9.0)
|
||||
Microsoft.Build (17.12.6)
|
||||
Microsoft.Build.Framework (>= 17.12.6)
|
||||
Microsoft.NET.StringTools (>= 17.12.6)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Configuration.ConfigurationManager (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
System.Reflection.MetadataLoadContext (>= 8.0)
|
||||
Microsoft.Build.Framework (17.12.6)
|
||||
Microsoft.Build.Utilities.Core (17.12.6)
|
||||
Microsoft.Build.Framework (>= 17.12.6)
|
||||
Microsoft.NET.StringTools (>= 17.12.6)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Configuration.ConfigurationManager (>= 8.0)
|
||||
Microsoft.CodeAnalysis (4.12)
|
||||
MessagePack.Annotations (3.1.4)
|
||||
MessagePackAnalyzer (3.1.4)
|
||||
Microsoft.Bcl.AsyncInterfaces (9.0.10)
|
||||
Microsoft.Bcl.Memory (9.0.10)
|
||||
Microsoft.Build (17.14.28)
|
||||
Microsoft.Build.Framework (>= 17.14.28)
|
||||
Microsoft.NET.StringTools (>= 17.14.28)
|
||||
System.Configuration.ConfigurationManager (>= 9.0)
|
||||
System.Diagnostics.EventLog (>= 9.0)
|
||||
System.Reflection.MetadataLoadContext (>= 9.0)
|
||||
System.Security.Cryptography.ProtectedData (>= 9.0)
|
||||
Microsoft.Build.Framework (17.14.28)
|
||||
Microsoft.Build.Utilities.Core (17.14.28)
|
||||
Microsoft.Build.Framework (>= 17.14.28)
|
||||
Microsoft.NET.StringTools (>= 17.14.28)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Configuration.ConfigurationManager (>= 9.0)
|
||||
System.Diagnostics.EventLog (>= 9.0)
|
||||
System.Security.Cryptography.ProtectedData (>= 9.0)
|
||||
Microsoft.CodeAnalysis (4.14)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.Bcl.AsyncInterfaces (>= 8.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (4.12)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.12)
|
||||
Microsoft.Bcl.AsyncInterfaces (>= 9.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (4.14)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.14)
|
||||
System.Buffers (>= 4.5.1)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Composition (>= 8.0)
|
||||
System.IO.Pipelines (>= 8.0)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Composition (>= 9.0)
|
||||
System.IO.Pipelines (>= 9.0)
|
||||
System.Memory (>= 4.5.5)
|
||||
System.Numerics.Vectors (>= 4.5)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
System.Runtime.CompilerServices.Unsafe (>= 6.0)
|
||||
System.Text.Encoding.CodePages (>= 7.0)
|
||||
System.Threading.Channels (>= 7.0)
|
||||
System.Threading.Tasks.Extensions (>= 4.5.4)
|
||||
Microsoft.CodeAnalysis.Analyzers (3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.CSharp (4.12)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (4.12)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
Microsoft.CodeAnalysis.CSharp (4.14)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (4.14)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
Microsoft.CodeAnalysis.CSharp (4.12)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.12)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Composition (>= 8.0)
|
||||
System.IO.Pipelines (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
Microsoft.CodeAnalysis.CSharp (4.14)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.14)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Composition (>= 9.0)
|
||||
System.IO.Pipelines (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
System.Threading.Channels (>= 7.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic (4.12)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.12)
|
||||
Microsoft.CodeAnalysis.VisualBasic (4.14)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.14)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
Microsoft.CodeAnalysis.VisualBasic (4.12)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.12)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Composition (>= 8.0)
|
||||
System.IO.Pipelines (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
Microsoft.CodeAnalysis.VisualBasic (4.14)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.14)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Composition (>= 9.0)
|
||||
System.IO.Pipelines (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
System.Threading.Channels (>= 7.0)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.12)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (4.14)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
|
||||
Microsoft.CodeAnalysis.Common (4.12)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
System.Composition (>= 8.0)
|
||||
System.IO.Pipelines (>= 8.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (4.14)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Composition (>= 9.0)
|
||||
System.IO.Pipelines (>= 9.0)
|
||||
System.Reflection.Metadata (>= 9.0)
|
||||
System.Threading.Channels (>= 7.0)
|
||||
Microsoft.CodeCoverage (17.12)
|
||||
Microsoft.Extensions.ObjectPool (9.0.3)
|
||||
Microsoft.NET.StringTools (17.12.6)
|
||||
Microsoft.NET.Test.Sdk (17.12)
|
||||
Microsoft.CodeCoverage (>= 17.12)
|
||||
Microsoft.TestPlatform.TestHost (>= 17.12)
|
||||
Microsoft.CodeCoverage (18.0)
|
||||
Microsoft.Extensions.ObjectPool (9.0.10)
|
||||
Microsoft.NET.StringTools (17.14.28)
|
||||
Microsoft.NET.Test.Sdk (18.0)
|
||||
Microsoft.CodeCoverage (>= 18.0)
|
||||
Microsoft.TestPlatform.TestHost (>= 18.0)
|
||||
Microsoft.NETCore.Platforms (7.0.4)
|
||||
Microsoft.NETCore.Targets (5.0)
|
||||
Microsoft.TestPlatform.ObjectModel (17.12)
|
||||
System.Reflection.Metadata (>= 1.6)
|
||||
Microsoft.TestPlatform.TestHost (17.12)
|
||||
Microsoft.TestPlatform.ObjectModel (>= 17.12)
|
||||
Newtonsoft.Json (>= 13.0.1)
|
||||
Microsoft.TestPlatform.ObjectModel (18.0)
|
||||
System.Reflection.Metadata (>= 8.0)
|
||||
Microsoft.TestPlatform.TestHost (18.0)
|
||||
Microsoft.TestPlatform.ObjectModel (>= 18.0)
|
||||
Newtonsoft.Json (>= 13.0.3)
|
||||
Microsoft.Win32.Primitives (4.3)
|
||||
Microsoft.NETCore.Platforms (>= 1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1)
|
||||
System.Runtime (>= 4.3)
|
||||
Mono.Posix.NETStandard (1.0)
|
||||
MSBuild.StructuredLogger (2.2.386)
|
||||
MSBuild.StructuredLogger (2.3.71)
|
||||
Microsoft.Build.Framework (>= 17.5)
|
||||
Microsoft.Build.Utilities.Core (>= 17.5)
|
||||
System.Collections.Immutable (>= 8.0)
|
||||
Newtonsoft.Json (13.0.3)
|
||||
System.Buffers (4.6)
|
||||
System.Collections.Immutable (9.0)
|
||||
System.Composition (9.0)
|
||||
System.Composition.AttributedModel (>= 9.0)
|
||||
System.Composition.Convention (>= 9.0)
|
||||
System.Composition.Hosting (>= 9.0)
|
||||
System.Composition.Runtime (>= 9.0)
|
||||
System.Composition.TypedParts (>= 9.0)
|
||||
System.Composition.AttributedModel (9.0)
|
||||
System.Composition.Convention (9.0)
|
||||
System.Composition.AttributedModel (>= 9.0)
|
||||
System.Composition.Hosting (9.0)
|
||||
System.Composition.Runtime (>= 9.0)
|
||||
System.Composition.Runtime (9.0)
|
||||
System.Composition.TypedParts (9.0)
|
||||
System.Composition.AttributedModel (>= 9.0)
|
||||
System.Composition.Hosting (>= 9.0)
|
||||
System.Composition.Runtime (>= 9.0)
|
||||
System.Configuration.ConfigurationManager (9.0)
|
||||
System.Diagnostics.EventLog (>= 9.0)
|
||||
System.Security.Cryptography.ProtectedData (>= 9.0)
|
||||
System.Diagnostics.EventLog (9.0)
|
||||
NaturalSort.Extension (4.4)
|
||||
Newtonsoft.Json (13.0.4)
|
||||
System.Buffers (4.6.1)
|
||||
System.Collections.Immutable (9.0.10)
|
||||
System.Composition (9.0.10)
|
||||
System.Composition.AttributedModel (>= 9.0.10)
|
||||
System.Composition.Convention (>= 9.0.10)
|
||||
System.Composition.Hosting (>= 9.0.10)
|
||||
System.Composition.Runtime (>= 9.0.10)
|
||||
System.Composition.TypedParts (>= 9.0.10)
|
||||
System.Composition.AttributedModel (9.0.10)
|
||||
System.Composition.Convention (9.0.10)
|
||||
System.Composition.AttributedModel (>= 9.0.10)
|
||||
System.Composition.Hosting (9.0.10)
|
||||
System.Composition.Runtime (>= 9.0.10)
|
||||
System.Composition.Runtime (9.0.10)
|
||||
System.Composition.TypedParts (9.0.10)
|
||||
System.Composition.AttributedModel (>= 9.0.10)
|
||||
System.Composition.Hosting (>= 9.0.10)
|
||||
System.Composition.Runtime (>= 9.0.10)
|
||||
System.Configuration.ConfigurationManager (9.0.10)
|
||||
System.Diagnostics.EventLog (>= 9.0.10)
|
||||
System.Security.Cryptography.ProtectedData (>= 9.0.10)
|
||||
System.Diagnostics.EventLog (9.0.10)
|
||||
System.IO (4.3)
|
||||
Microsoft.NETCore.Platforms (>= 1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1)
|
||||
@@ -157,55 +162,55 @@ NUGET
|
||||
System.Threading.Tasks (>= 4.3)
|
||||
System.IO.FileSystem.Primitives (4.3)
|
||||
System.Runtime (>= 4.3)
|
||||
System.IO.Pipelines (9.0)
|
||||
System.Memory (4.6)
|
||||
System.IO.Pipelines (9.0.10)
|
||||
System.Memory (4.6.3)
|
||||
System.Net.Primitives (4.3.1)
|
||||
Microsoft.NETCore.Platforms (>= 1.1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1.3)
|
||||
System.Runtime (>= 4.3.1)
|
||||
System.Runtime.Handles (>= 4.3)
|
||||
System.Numerics.Vectors (4.6)
|
||||
System.Reflection.Metadata (9.0)
|
||||
System.Reflection.MetadataLoadContext (9.0)
|
||||
System.Numerics.Vectors (4.6.1)
|
||||
System.Reflection.Metadata (9.0.10)
|
||||
System.Reflection.MetadataLoadContext (9.0.10)
|
||||
System.Runtime (4.3.1)
|
||||
Microsoft.NETCore.Platforms (>= 1.1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1.3)
|
||||
System.Runtime.CompilerServices.Unsafe (6.1)
|
||||
System.Runtime.CompilerServices.Unsafe (6.1.2)
|
||||
System.Runtime.Handles (4.3)
|
||||
Microsoft.NETCore.Platforms (>= 1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1)
|
||||
System.Runtime (>= 4.3)
|
||||
System.Security.Cryptography.ProtectedData (9.0)
|
||||
System.Security.Cryptography.ProtectedData (9.0.10)
|
||||
System.Security.Principal (4.3)
|
||||
System.Runtime (>= 4.3)
|
||||
System.Text.Encoding (4.3)
|
||||
Microsoft.NETCore.Platforms (>= 1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1)
|
||||
System.Runtime (>= 4.3)
|
||||
System.Text.Encoding.CodePages (9.0)
|
||||
System.Threading.Channels (9.0)
|
||||
System.Text.Encoding.CodePages (9.0.10)
|
||||
System.Threading.Channels (9.0.10)
|
||||
System.Threading.Tasks (4.3)
|
||||
Microsoft.NETCore.Platforms (>= 1.1)
|
||||
Microsoft.NETCore.Targets (>= 1.1)
|
||||
System.Runtime (>= 4.3)
|
||||
System.Threading.Tasks.Extensions (4.6)
|
||||
System.Threading.Tasks.Extensions (4.6.3)
|
||||
System.Threading.ThreadPool (4.3)
|
||||
System.Runtime (>= 4.3)
|
||||
System.Runtime.Handles (>= 4.3)
|
||||
xunit (2.9.2)
|
||||
xunit.analyzers (>= 1.16)
|
||||
xunit.assert (>= 2.9.2)
|
||||
xunit.core (2.9.2)
|
||||
xunit (2.9.3)
|
||||
xunit.analyzers (>= 1.18)
|
||||
xunit.assert (>= 2.9.3)
|
||||
xunit.core (2.9.3)
|
||||
xunit.abstractions (2.0.3)
|
||||
xunit.analyzers (1.17)
|
||||
xunit.assert (2.9.2)
|
||||
xunit.core (2.9.2)
|
||||
xunit.extensibility.core (2.9.2)
|
||||
xunit.extensibility.execution (2.9.2)
|
||||
xunit.extensibility.core (2.9.2)
|
||||
xunit.analyzers (1.24)
|
||||
xunit.assert (2.9.3)
|
||||
xunit.core (2.9.3)
|
||||
xunit.extensibility.core (2.9.3)
|
||||
xunit.extensibility.execution (2.9.3)
|
||||
xunit.extensibility.core (2.9.3)
|
||||
xunit.abstractions (>= 2.0.3)
|
||||
xunit.extensibility.execution (2.9.2)
|
||||
xunit.extensibility.core (2.9.2)
|
||||
xunit.runner.utility (2.9.2)
|
||||
xunit.extensibility.execution (2.9.3)
|
||||
xunit.extensibility.core (2.9.3)
|
||||
xunit.runner.utility (2.9.3)
|
||||
xunit.abstractions (>= 2.0.3)
|
||||
xunit.runner.visualstudio (2.8.2)
|
||||
xunit.runner.visualstudio (3.1.5)
|
||||
|
||||
104
csharp/paket.main.bzl
generated
104
csharp/paket.main.bzl
generated
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@ ql/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-117/LogForging.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-119/LocalUnvalidatedArithmetic.ql
|
||||
@@ -33,6 +34,7 @@ ql/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.q
|
||||
ql/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/RequireSSL.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-730/ReDoS.ql
|
||||
|
||||
@@ -120,6 +120,7 @@ ql/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-117/LogForging.ql
|
||||
@@ -140,6 +141,7 @@ ql/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.q
|
||||
ql/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/RequireSSL.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-639/InsecureDirectObjectReference.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql
|
||||
|
||||
@@ -23,6 +23,7 @@ ql/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-117/LogForging.ql
|
||||
@@ -43,6 +44,7 @@ ql/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.q
|
||||
ql/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-614/RequireSSL.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-639/InsecureDirectObjectReference.ql
|
||||
ql/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql
|
||||
|
||||
@@ -84,9 +84,7 @@ ql/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql
|
||||
ql/csharp/ql/src/definitions.ql
|
||||
ql/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql
|
||||
ql/csharp/ql/src/experimental/CWE-918/RequestForgery.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql
|
||||
ql/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
| [...]/csharp/tools/[...]/MessagePack.Annotations.dll |
|
||||
| [...]/csharp/tools/[...]/MessagePack.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Bcl.AsyncInterfaces.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Bcl.Memory.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Build.Framework.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Build.Utilities.Core.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Build.dll |
|
||||
@@ -20,6 +21,7 @@
|
||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll |
|
||||
| [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll |
|
||||
| [...]/csharp/tools/[...]/NaturalSort.Extension.dll |
|
||||
| [...]/csharp/tools/[...]/Newtonsoft.Json.dll |
|
||||
| [...]/csharp/tools/[...]/StructuredLogger.dll |
|
||||
| [...]/csharp/tools/[...]/System.AppContext.dll |
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* `ControlFlowElement.controlsBlock` has been deprecated in favor of the Guards library.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Updated *roslyn* and *binlog* dependencies in the extractor, which may improve database and analysis quality.
|
||||
@@ -33,8 +33,6 @@ module Stages {
|
||||
|
||||
cached
|
||||
private predicate forceCachingInSameStageRev() {
|
||||
any(ControlFlowElement cfe).controlsBlock(_, _, _)
|
||||
or
|
||||
exists(GuardedExpr ge)
|
||||
or
|
||||
forceCachingInSameStageRev()
|
||||
|
||||
@@ -87,148 +87,20 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
result.getAControlFlowNode()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate immediatelyControlsBlockSplit0(
|
||||
ConditionBlock cb, BasicBlock succ, ConditionalSuccessor s
|
||||
) {
|
||||
// Only calculate dominance by explicit recursion for split nodes;
|
||||
// all other nodes can use regular CFG dominance
|
||||
this instanceof Impl::SplitAstNode and
|
||||
cb.getLastNode() = this.getAControlFlowNode() and
|
||||
succ = cb.getASuccessor(s)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate immediatelyControlsBlockSplit1(
|
||||
ConditionBlock cb, BasicBlock succ, ConditionalSuccessor s, BasicBlock pred, SuccessorType t
|
||||
) {
|
||||
this.immediatelyControlsBlockSplit0(cb, succ, s) and
|
||||
pred = succ.getAPredecessorByType(t) and
|
||||
pred != cb
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate immediatelyControlsBlockSplit2(
|
||||
ConditionBlock cb, BasicBlock succ, ConditionalSuccessor s, BasicBlock pred, SuccessorType t
|
||||
) {
|
||||
this.immediatelyControlsBlockSplit1(cb, succ, s, pred, t) and
|
||||
(
|
||||
succ.dominates(pred)
|
||||
or
|
||||
// `pred` might be another split of this element
|
||||
pred.getLastNode().getAstNode() = this and
|
||||
t = s
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if basic block `succ` is immediately controlled by this control flow
|
||||
* element with conditional value `s`. That is, `succ` can only be reached from
|
||||
* the callable entry point by going via the `s` edge out of *some* basic block
|
||||
* `pred` ending with this element, and `pred` is an immediate predecessor
|
||||
* of `succ`.
|
||||
* DEPRECATED: Use `Guard` class instead.
|
||||
*
|
||||
* Moreover, this control flow element corresponds to multiple control flow nodes,
|
||||
* which is why
|
||||
*
|
||||
* ```ql
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.immediatelyControls(succ, s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* does not work.
|
||||
*
|
||||
* `cb` records all of the possible condition blocks for this control flow element
|
||||
* that a path from the callable entry point to `succ` may go through.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate immediatelyControlsBlockSplit(
|
||||
BasicBlock succ, ConditionalSuccessor s, ConditionBlock cb
|
||||
) {
|
||||
this.immediatelyControlsBlockSplit0(cb, succ, s) and
|
||||
forall(BasicBlock pred, SuccessorType t |
|
||||
this.immediatelyControlsBlockSplit1(cb, succ, s, pred, t)
|
||||
|
|
||||
this.immediatelyControlsBlockSplit2(cb, succ, s, pred, t)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate controlsJoinBlockPredecessor(
|
||||
JoinBlock controlled, ConditionalSuccessor s, int i, ConditionBlock cb
|
||||
) {
|
||||
this.controlsBlockSplit(controlled.getJoinBlockPredecessor(i), s, cb)
|
||||
}
|
||||
|
||||
private predicate controlsJoinBlockSplit(JoinBlock controlled, ConditionalSuccessor s, int i) {
|
||||
i = -1 and
|
||||
this.controlsJoinBlockPredecessor(controlled, s, _, _)
|
||||
or
|
||||
this.controlsJoinBlockSplit(controlled, s, i - 1) and
|
||||
(
|
||||
this.controlsJoinBlockPredecessor(controlled, s, i, _)
|
||||
or
|
||||
controlled.dominates(controlled.getJoinBlockPredecessor(i))
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private predicate controlsBlockSplit(
|
||||
BasicBlock controlled, ConditionalSuccessor s, ConditionBlock cb
|
||||
) {
|
||||
Stages::GuardsStage::forceCachingInSameStage() and
|
||||
this.immediatelyControlsBlockSplit(controlled, s, cb)
|
||||
or
|
||||
// Equivalent with
|
||||
//
|
||||
// ```ql
|
||||
// exists(JoinBlockPredecessor pred | pred = controlled.getAPredecessor() |
|
||||
// this.controlsBlockSplit(pred, s)
|
||||
// ) and
|
||||
// forall(JoinBlockPredecessor pred | pred = controlled.getAPredecessor() |
|
||||
// this.controlsBlockSplit(pred, s)
|
||||
// or
|
||||
// controlled.dominates(pred)
|
||||
// )
|
||||
// ```
|
||||
//
|
||||
// but uses no universal recursion for better performance.
|
||||
exists(int last |
|
||||
last = max(int i | exists(controlled.(JoinBlock).getJoinBlockPredecessor(i)))
|
||||
|
|
||||
this.controlsJoinBlockSplit(controlled, s, last)
|
||||
) and
|
||||
this.controlsJoinBlockPredecessor(controlled, s, _, cb)
|
||||
or
|
||||
not controlled instanceof JoinBlock and
|
||||
this.controlsBlockSplit(controlled.getAPredecessor(), s, cb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if basic block `controlled` is controlled by this control flow element
|
||||
* with conditional value `s`. That is, `controlled` can only be reached from
|
||||
* the callable entry point by going via the `s` edge out of *some* basic block
|
||||
* ending with this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
*
|
||||
* ```ql
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.controls(controlled, s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* as control flow splitting is taken into account.
|
||||
*
|
||||
* `cb` records all of the possible condition blocks for this control flow element
|
||||
* that a path from the callable entry point to `controlled` may go through.
|
||||
*/
|
||||
predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s, ConditionBlock cb) {
|
||||
this.controlsBlockSplit(controlled, s, cb)
|
||||
or
|
||||
deprecated predicate controlsBlock(
|
||||
BasicBlock controlled, ConditionalSuccessor s, ConditionBlock cb
|
||||
) {
|
||||
cb.getLastNode() = this.getAControlFlowNode() and
|
||||
cb.edgeDominates(controlled, s)
|
||||
}
|
||||
|
||||
@@ -49,8 +49,15 @@ private module GuardsInput implements
|
||||
override predicate isNull() { any() }
|
||||
}
|
||||
|
||||
private class BooleanConstant extends ConstantExpr instanceof BoolLiteral {
|
||||
override boolean asBooleanValue() { result = super.getBoolValue() }
|
||||
private predicate boolConst(Expr e, boolean b) {
|
||||
e.getType() instanceof BoolType and
|
||||
e.getValue() = b.toString()
|
||||
}
|
||||
|
||||
private class BooleanConstant extends ConstantExpr {
|
||||
BooleanConstant() { boolConst(this, _) }
|
||||
|
||||
override boolean asBooleanValue() { boolConst(this, result) }
|
||||
}
|
||||
|
||||
private predicate intConst(Expr e, int i) {
|
||||
|
||||
@@ -2583,10 +2583,10 @@ class NodeRegion instanceof ControlFlow::BasicBlock {
|
||||
* Holds if the nodes in `nr` are unreachable when the call context is `call`.
|
||||
*/
|
||||
predicate isUnreachableInCall(NodeRegion nr, DataFlowCall call) {
|
||||
exists(ExplicitParameterNode paramNode, Guard guard, ControlFlow::BooleanSuccessor bs |
|
||||
viableConstantBooleanParamArg(paramNode, bs.getValue().booleanNot(), call) and
|
||||
exists(ExplicitParameterNode paramNode, Guard guard, GuardValue val |
|
||||
viableConstantParamArg(paramNode, val.getDualValue(), call) and
|
||||
paramNode.getSsaDefinition().getARead() = guard and
|
||||
guard.controlsBlock(nr, bs, _)
|
||||
guard.valueControls(nr, val)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2904,33 +2904,19 @@ class CastNode extends Node {
|
||||
|
||||
class DataFlowExpr = Expr;
|
||||
|
||||
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
e.getType() instanceof BoolType and
|
||||
e.getValue() = val.toString()
|
||||
or
|
||||
exists(Ssa::ExplicitDefinition def, Expr src |
|
||||
e = def.getARead() and
|
||||
src = def.getADefinition().getSource() and
|
||||
constantBooleanExpr(src, val)
|
||||
)
|
||||
}
|
||||
/** An argument that always has the same value. */
|
||||
private class ConstantArgumentNode extends ExprNode {
|
||||
ConstantArgumentNode() { Guards::InternalUtil::exprHasValue(this.(ArgumentNode).asExpr(), _) }
|
||||
|
||||
/** An argument that always has the same Boolean value. */
|
||||
private class ConstantBooleanArgumentNode extends ExprNode {
|
||||
ConstantBooleanArgumentNode() { constantBooleanExpr(this.(ArgumentNode).asExpr(), _) }
|
||||
|
||||
/** Gets the Boolean value of this expression. */
|
||||
boolean getBooleanValue() { constantBooleanExpr(this.getExpr(), result) }
|
||||
/** Gets the value of this expression. */
|
||||
GuardValue getValue() { Guards::InternalUtil::exprHasValue(this.getExpr(), result) }
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableConstantBooleanParamArg(
|
||||
ParameterNode paramNode, boolean b, DataFlowCall call
|
||||
) {
|
||||
exists(ConstantBooleanArgumentNode arg |
|
||||
private predicate viableConstantParamArg(ParameterNode paramNode, GuardValue val, DataFlowCall call) {
|
||||
exists(ConstantArgumentNode arg |
|
||||
viableParamArg(call, paramNode, arg) and
|
||||
b = arg.getBooleanValue()
|
||||
val = arg.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* Provides classes and predicates for detecting insecure cookies.
|
||||
* Definitions for detecting insecure and non-HttpOnly cookies.
|
||||
*/
|
||||
deprecated module;
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
private import semmle.code.csharp.frameworks.system.Web
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
|
||||
/**
|
||||
* Holds if the expression is a variable with a sensitive name.
|
||||
* Holds if the expression is a sensitive string literal or a variable with a sensitive name.
|
||||
*/
|
||||
predicate isCookieWithSensitiveName(Expr cookieExpr) {
|
||||
exists(DataFlow::Node sink |
|
||||
@@ -17,7 +17,7 @@ predicate isCookieWithSensitiveName(Expr cookieExpr) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for tracking if a variable with a sensitive name is used as an argument.
|
||||
* Configuration for tracking if a sensitive string literal or a variable with a sensitive name is used as an argument.
|
||||
*/
|
||||
private module AuthCookieNameConfig implements DataFlow::ConfigSig {
|
||||
private predicate isAuthVariable(Expr expr) {
|
||||
@@ -33,7 +33,15 @@ private module AuthCookieNameConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { exists(Call c | sink.asExpr() = c.getAnArgument()) }
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(Call c |
|
||||
sink.asExpr() = c.getAnArgument() and
|
||||
(
|
||||
c.getTarget() = any(MicrosoftAspNetCoreHttpResponseCookies cls).getAppendMethod() or
|
||||
c.(ObjectCreation).getType() instanceof SystemWebHttpCookie
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,13 +127,13 @@ private signature string propertyName();
|
||||
|
||||
/**
|
||||
* Configuration for tracking if a callback used in `OnAppendCookie` sets a cookie property to `true`.
|
||||
*
|
||||
* ` getPropertyName` specifies the cookie property name to track.
|
||||
*/
|
||||
private module OnAppendCookieTrackingConfig<propertyName/0 getPropertyName> implements
|
||||
DataFlow::ConfigSig
|
||||
{
|
||||
/**
|
||||
* Specifies the cookie property name to track.
|
||||
*/
|
||||
/** Source is the parameter of a callback passed to `OnAppendCookie` */
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(PropertyWrite pw, Assignment delegateAssign, Callable c |
|
||||
pw.getProperty().getName() = "OnAppendCookie" and
|
||||
@@ -146,6 +154,7 @@ private module OnAppendCookieTrackingConfig<propertyName/0 getPropertyName> impl
|
||||
)
|
||||
}
|
||||
|
||||
/** Sink is a property write that sets the given property to `true`. */
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(PropertyWrite pw, Assignment a |
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
@@ -178,7 +187,7 @@ private module OnAppendCookieSecureTrackingConfig =
|
||||
OnAppendCookieTrackingConfig<getPropertyNameSecure/0>;
|
||||
|
||||
/**
|
||||
* Tracks if a callback used in `OnAppendCookie` sets `Secure` to `true`.
|
||||
* Tracks if a callback used in `OnAppendCookie` sets `Secure` to `true`, and thus cookies appended to responses are secure by default.
|
||||
*/
|
||||
module OnAppendCookieSecureTracking = DataFlow::Global<OnAppendCookieSecureTrackingConfig>;
|
||||
|
||||
@@ -191,6 +200,6 @@ private module OnAppendCookieHttpOnlyTrackingConfig =
|
||||
OnAppendCookieTrackingConfig<getPropertyNameHttpOnly/0>;
|
||||
|
||||
/**
|
||||
* Tracks if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`.
|
||||
* Tracks if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`, and thus cookies appended to responses are httponly by default.
|
||||
*/
|
||||
module OnAppendCookieHttpOnlyTracking = DataFlow::Global<OnAppendCookieHttpOnlyTrackingConfig>;
|
||||
@@ -72,17 +72,10 @@ class ReverseDnsSource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate conditionControlsCall0(
|
||||
SensitiveExecutionMethodCall call, Expr e, ControlFlow::BooleanSuccessor s
|
||||
) {
|
||||
forex(BasicBlock bb | bb = call.getAControlFlowNode().getBasicBlock() | e.controlsBlock(bb, s, _))
|
||||
}
|
||||
|
||||
private predicate conditionControlsCall(
|
||||
SensitiveExecutionMethodCall call, SensitiveExecutionMethod def, Expr e, boolean cond
|
||||
) {
|
||||
exists(ControlFlow::BooleanSuccessor s | cond = s.getValue() | conditionControlsCall0(call, e, s)) and
|
||||
e.(Guard).directlyControls(call.getBasicBlock(), cond) and
|
||||
def = call.getTarget().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Cookies without the <code>HttpOnly</code> flag set are accessible to client-side scripts such as JavaScript running in the same origin.
|
||||
In case of a Cross-Site Scripting (XSS) vulnerability, the cookie can be stolen by a malicious script.
|
||||
If a sensitive cookie does not need to be accessed directly by client-side JS, the <code>HttpOnly</code> flag should be set.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Set the <code>HttpOnly</code> flag to <code>true</code> for authentication cookies to ensure they are not accessible to client-side scripts.
|
||||
</p>
|
||||
<p>
|
||||
When using ASP.NET Core, <code>CookiePolicyOptions</code> can be used to set a default policy for cookies.
|
||||
|
||||
When using ASP.NET Web Forms, a default may also be configured in the <code>Web.config</code> file, using the <code>httpOnlyCookies</code> attribute of the
|
||||
the <code><httpCookies></code> element.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the example below, <code>Microsoft.AspNetCore.Http.CookieOptions.HttpOnly</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="httponlyflagcore.cs" />
|
||||
|
||||
<p>
|
||||
In the following example, <code>CookiePolicyOptions</code> are set programmatically to configure defaults.
|
||||
</p>
|
||||
|
||||
<sample src="cookiepolicyoptions.cs" />
|
||||
|
||||
<p>
|
||||
In the example below, <code>System.Web.HttpCookie.HttpOnly</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="httponlyflag.cs" />
|
||||
|
||||
<p>
|
||||
In the example below, the <code>httpOnlyCookies</code> attribute is set to <code>true</code> in the <code>Web.config</code> file.
|
||||
</p>
|
||||
<sample src="Web.config"/>
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>ASP.Net Core docs: <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookieoptions.httponly">CookieOptions.HttpOnly Property</a>.</li>
|
||||
<li>MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header.</li>
|
||||
<li>Web Forms docs: <a href="https://msdn.microsoft.com/en-us/library/system.web.httpcookie.httponly(v=vs.110).aspx">HttpCookie.HttpOnly Property</a>.</li>
|
||||
<li>Web Forms docs: <a href="https://msdn.microsoft.com/library/ms228262%28v=vs.100%29.aspx">httpCookies Element</a>.</li>
|
||||
<li>PortSwigger: <a href="https://portswigger.net/kb/issues/00500600_cookie-without-httponly-flag-set">Cookie without HttpOnly flag set</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @name Cookie 'HttpOnly' attribute is not set to true
|
||||
* @description Sensitive cookies without the `HttpOnly` property set are accessible by client-side scripts such as JavaScript.
|
||||
* This makes them more vulnerable to being stolen by an XSS attack.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 5.0
|
||||
* @precision high
|
||||
* @id cs/web/cookie-httponly-not-set
|
||||
* @tags security
|
||||
* external/cwe/cwe-1004
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.asp.WebConfig
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
import semmle.code.csharp.security.auth.SecureCookies
|
||||
|
||||
predicate cookieAppendHttpOnlyByDefault() {
|
||||
// default is set to `Always`
|
||||
getAValueForCookiePolicyProp("HttpOnly").getValue() = "1"
|
||||
or
|
||||
// there is an `OnAppendCookie` callback that sets `HttpOnly` to true
|
||||
OnAppendCookieHttpOnlyTracking::flowTo(_)
|
||||
}
|
||||
|
||||
predicate httpOnlyFalse(ObjectCreation oc) {
|
||||
exists(Assignment a |
|
||||
getAValueForProp(oc, a, "HttpOnly") = a.getRValue() and
|
||||
a.getRValue().getValue() = "false"
|
||||
)
|
||||
}
|
||||
|
||||
predicate httpOnlyFalseOrNotSet(ObjectCreation oc) {
|
||||
httpOnlyFalse(oc)
|
||||
or
|
||||
not isPropertySet(oc, "HttpOnly")
|
||||
}
|
||||
|
||||
predicate nonHttpOnlyCookieOptionsCreation(ObjectCreation oc, MethodCall append) {
|
||||
// `HttpOnly` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
httpOnlyFalseOrNotSet(oc) and
|
||||
exists(DataFlow::Node creation, DataFlow::Node sink |
|
||||
CookieOptionsTracking::flow(creation, sink) and
|
||||
creation.asExpr() = oc and
|
||||
sink.asExpr() = append.getArgument(2)
|
||||
)
|
||||
}
|
||||
|
||||
predicate nonHttpOnlySystemWebSensitiveCookieCreation(ObjectCreation oc) {
|
||||
oc.getType() instanceof SystemWebHttpCookie and
|
||||
isCookieWithSensitiveName(oc.getArgument(0)) and
|
||||
(
|
||||
httpOnlyFalse(oc)
|
||||
or
|
||||
// the property wasn't explicitly set, so a default value from config is used
|
||||
not isPropertySet(oc, "HttpOnly") and
|
||||
// the default in config is not set to `true`
|
||||
not exists(XmlElement element |
|
||||
element instanceof HttpCookiesElement and
|
||||
element.(HttpCookiesElement).isHttpOnlyCookies()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate sensitiveCookieAppend(MethodCall mc) {
|
||||
exists(MicrosoftAspNetCoreHttpResponseCookies iResponse |
|
||||
iResponse.getAppendMethod() = mc.getTarget() and
|
||||
isCookieWithSensitiveName(mc.getArgument(0))
|
||||
)
|
||||
}
|
||||
|
||||
predicate nonHttpOnlyCookieCall(Call c) {
|
||||
(
|
||||
not cookieAppendHttpOnlyByDefault() and
|
||||
exists(MethodCall mc |
|
||||
sensitiveCookieAppend(mc) and
|
||||
(
|
||||
nonHttpOnlyCookieOptionsCreation(c, mc)
|
||||
or
|
||||
// IResponseCookies.Append(String, String) was called, `HttpOnly` is set to `false` by default
|
||||
mc = c and
|
||||
mc.getNumberOfArguments() < 3 and
|
||||
mc.getTarget().getParameter(0).getType() instanceof StringType
|
||||
)
|
||||
)
|
||||
or
|
||||
nonHttpOnlySystemWebSensitiveCookieCreation(c)
|
||||
)
|
||||
}
|
||||
|
||||
predicate nonHttpOnlyCookieBuilderAssignment(Assignment a, Expr val) {
|
||||
val.getValue() = "false" and
|
||||
exists(PropertyWrite pw |
|
||||
(
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
|
||||
pw.getProperty().getDeclaringType() instanceof
|
||||
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
|
||||
) and
|
||||
pw.getProperty().getName() = "HttpOnly" and
|
||||
a.getLValue() = pw and
|
||||
DataFlow::localExprFlow(val, a.getRValue())
|
||||
)
|
||||
}
|
||||
|
||||
from Expr httpOnlySink
|
||||
where
|
||||
(
|
||||
nonHttpOnlyCookieCall(httpOnlySink)
|
||||
or
|
||||
exists(Assignment a |
|
||||
httpOnlySink = a.getRValue() and
|
||||
nonHttpOnlyCookieBuilderAssignment(a, _)
|
||||
)
|
||||
)
|
||||
select httpOnlySink, "Cookie attribute 'HttpOnly' is not set to true."
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpCookies requireSSL="false" />
|
||||
<httpCookies httpOnlyCookies="true"/>
|
||||
</system.web>
|
||||
</configuration>
|
||||
</configuration>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Cookies without the <code>Secure</code> flag set may be transmitted using HTTP instead of HTTPS.
|
||||
This leaves them vulnerable to being read by a third party attacker. If a sensitive cookie such as a session
|
||||
key is intercepted this way, it would allow the attacker to perform actions on a user's behalf.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
When using ASP.NET Core, ensure cookies have the secure flag set by setting <code>Microsoft.AspNetCore.Http.CookieOptions.Secure</code> to <code>true</code>, or
|
||||
using <code>CookiePolicyOptions</code> to set a default security policy.
|
||||
</p>
|
||||
<p>
|
||||
When using ASP.NET Web Forms, cookies can be configured as secure by default in the <code>Web.config</code> file, setting the <code>requireSSL</code> attribute to <code>true</code> in the <code>forms</code> or <code>httpCookies</code> element.
|
||||
Cookies may also be set to be secure programmatically by setting the <code>System.Web.HttpCookie.Secure</code> attribute to <code>true</code>.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the example below, <code>Microsoft.AspNetCore.Http.CookieOptions.Secure</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="secureflagcore.cs" />
|
||||
|
||||
<p>
|
||||
In the following example, <code>CookiePolicyOptions</code> are set programmatically to configure defaults.
|
||||
</p>
|
||||
|
||||
<sample src="cookiepolicyoptions.cs" />
|
||||
|
||||
<p>
|
||||
In the example below <code>System.Web.HttpCookie.Secure</code> is set to <code>true</code> programmatically.
|
||||
</p>
|
||||
|
||||
<sample src="secureflag.cs" />
|
||||
|
||||
<p>
|
||||
In the example below, the <code>requireSSL</code> attribute is set to <code>true</code> in the <code>forms</code> element of the <code>Web.config</code> file.
|
||||
</p>
|
||||
<sample src="Web.config" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>ASP.NET Core docs: <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookieoptions.secure">CookieOptions.Secure Property</a>.</li>
|
||||
<li>MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header.</li>
|
||||
<li>Web Forms docs: <a href="https://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.requiressl(v=vs.110).aspx">FormsAuthentication.RequireSSL Property</a>.</li>
|
||||
<li>Web Forms docs: <a href="https://msdn.microsoft.com/en-us/library/1d3t3c61(v=vs.100).aspx">forms Element for authentication</a>.</li>
|
||||
<li>Web Forms docs: <a href="https://msdn.microsoft.com/library/ms228262%28v=vs.100%29.aspx">httpCookies Element</a>.</li>
|
||||
<li>Detectify: <a href="https://support.detectify.com/support/solutions/articles/48001048982-cookie-lack-secure-flag">Cookie lack Secure flag</a>.</li>
|
||||
<li>PortSwigger: <a href="https://portswigger.net/kb/issues/00500200_tls-cookie-without-secure-flag-set">TLS cookie without secure flag set</a>.</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
116
csharp/ql/src/Security Features/CWE-614/CookieWithoutSecure.ql
Normal file
116
csharp/ql/src/Security Features/CWE-614/CookieWithoutSecure.ql
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @name Cookie 'Secure' attribute is not set to true
|
||||
* @description Cookies without the `Secure` flag may be sent in cleartext.
|
||||
* This makes them vulnerable to be intercepted by an attacker.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @security-severity 5.0
|
||||
* @precision high
|
||||
* @id cs/web/cookie-secure-not-set
|
||||
* @tags security
|
||||
* external/cwe/cwe-319
|
||||
* external/cwe/cwe-614
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.asp.WebConfig
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
import semmle.code.csharp.security.auth.SecureCookies
|
||||
|
||||
predicate cookieAppendSecureByDefault() {
|
||||
// default is set to `Always` or `SameAsRequest`
|
||||
(
|
||||
getAValueForCookiePolicyProp("Secure").getValue() = "0" or
|
||||
getAValueForCookiePolicyProp("Secure").getValue() = "1"
|
||||
)
|
||||
or
|
||||
//callback `OnAppendCookie` that sets `Secure` to true
|
||||
OnAppendCookieSecureTracking::flowTo(_)
|
||||
}
|
||||
|
||||
predicate secureFalse(ObjectCreation oc) {
|
||||
exists(Assignment a |
|
||||
getAValueForProp(oc, a, "Secure") = a.getRValue() and
|
||||
a.getRValue().getValue() = "false"
|
||||
)
|
||||
}
|
||||
|
||||
predicate secureFalseOrNotSet(ObjectCreation oc) {
|
||||
secureFalse(oc)
|
||||
or
|
||||
not isPropertySet(oc, "Secure")
|
||||
}
|
||||
|
||||
predicate insecureCookieOptionsCreation(ObjectCreation oc) {
|
||||
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
secureFalseOrNotSet(oc) and
|
||||
exists(DataFlow::Node creation |
|
||||
CookieOptionsTracking::flow(creation, _) and
|
||||
creation.asExpr() = oc
|
||||
)
|
||||
}
|
||||
|
||||
predicate insecureCookieAppend(Expr sink) {
|
||||
// IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
|
||||
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
|
||||
mc = sink and
|
||||
iResponse.getAppendMethod() = mc.getTarget() and
|
||||
mc.getNumberOfArguments() < 3 and
|
||||
mc.getTarget().getParameter(0).getType() instanceof StringType
|
||||
)
|
||||
}
|
||||
|
||||
predicate insecureSystemWebCookieCreation(ObjectCreation oc) {
|
||||
oc.getType() instanceof SystemWebHttpCookie and
|
||||
(
|
||||
secureFalse(oc)
|
||||
or
|
||||
// `Secure` property in `System.Web.HttpCookie` wasn't set, so a default value from config is used
|
||||
not isPropertySet(oc, "Secure") and
|
||||
// the default in config is not set to `true`
|
||||
not exists(XmlElement element |
|
||||
element instanceof FormsElement and
|
||||
element.(FormsElement).isRequireSsl()
|
||||
or
|
||||
element instanceof HttpCookiesElement and
|
||||
element.(HttpCookiesElement).isRequireSsl()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate insecureCookieCall(Call c) {
|
||||
not cookieAppendSecureByDefault() and
|
||||
(
|
||||
insecureCookieOptionsCreation(c)
|
||||
or
|
||||
insecureCookieAppend(c)
|
||||
)
|
||||
or
|
||||
insecureSystemWebCookieCreation(c)
|
||||
}
|
||||
|
||||
predicate insecureSecurePolicyAssignment(Assignment a, Expr val) {
|
||||
exists(PropertyWrite pw |
|
||||
(
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
|
||||
pw.getProperty().getDeclaringType() instanceof
|
||||
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
|
||||
) and
|
||||
pw.getProperty().getName() = "SecurePolicy" and
|
||||
a.getLValue() = pw and
|
||||
DataFlow::localExprFlow(val, a.getRValue()) and
|
||||
val.getValue() = "2" // None
|
||||
)
|
||||
}
|
||||
|
||||
from Expr secureSink
|
||||
where
|
||||
insecureCookieCall(secureSink)
|
||||
or
|
||||
exists(Assignment a |
|
||||
secureSink = a.getRValue() and
|
||||
insecureSecurePolicyAssignment(a, _)
|
||||
)
|
||||
select secureSink, "Cookie attribute 'Secure' is not set to true."
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
The `cs/web/cookie-secure-not-set` and `cs/web/cookie-httponly-not-set` queries have been promoted from experimental to the main query pack.
|
||||
@@ -1,51 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Cookies without <code>HttpOnly</code> flag are accessible to JavaScript running in the same origin. In case of
|
||||
Cross-Site Scripting (XSS) vulnerability the cookie can be stolen by malicious script.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Protect sensitive cookies, such as related to authentication, by setting <code>HttpOnly</code> to <code>true</code> to make
|
||||
them not accessible to JavaScript. In ASP.NET case it is also possible to set the attribute via <code><httpCookies></code> element
|
||||
of <code>web.config</code> with the attribute <code>httpOnlyCookies="true"</code>.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the example below <code>Microsoft.AspNetCore.Http.CookieOptions.HttpOnly</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="httponlyflagcore.cs" />
|
||||
|
||||
<p>
|
||||
In the following example <code>CookiePolicyOptions</code> are set programmatically to configure defaults.
|
||||
</p>
|
||||
|
||||
<sample src="cookiepolicyoptions.cs" />
|
||||
|
||||
<p>
|
||||
In the example below <code>System.Web.HttpCookie.HttpOnly</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="httponlyflag.cs" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li><a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookieoptions.httponly">CookieOptions.HttpOnly Property,</a></li>
|
||||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header,</li>
|
||||
<li><a href="https://msdn.microsoft.com/en-us/library/system.web.httpcookie.httponly(v=vs.110).aspx">HttpCookie.HttpOnly Property,</a></li>
|
||||
<li><a href="https://msdn.microsoft.com/library/ms228262%28v=vs.100%29.aspx">httpCookies Element,</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,107 +0,0 @@
|
||||
/**
|
||||
* @name 'HttpOnly' attribute is not set to true
|
||||
* @description Omitting the 'HttpOnly' attribute for security sensitive data allows
|
||||
* malicious JavaScript to steal it in case of XSS vulnerability. Always set
|
||||
* 'HttpOnly' to 'true' to authentication related cookie to make it
|
||||
* not accessible by JavaScript.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id cs/web/cookie-httponly-not-set
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-1004
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.asp.WebConfig
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
deprecated import experimental.dataflow.flowsources.AuthCookie
|
||||
|
||||
deprecated query predicate problems(Expr httpOnlySink, string message) {
|
||||
(
|
||||
exists(Assignment a, Expr val |
|
||||
httpOnlySink = a.getRValue() and
|
||||
val.getValue() = "false" and
|
||||
(
|
||||
exists(ObjectCreation oc |
|
||||
getAValueForProp(oc, a, "HttpOnly") = val and
|
||||
(
|
||||
oc.getType() instanceof SystemWebHttpCookie and
|
||||
isCookieWithSensitiveName(oc.getArgument(0))
|
||||
or
|
||||
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
iResponse.getAppendMethod() = mc.getTarget() and
|
||||
isCookieWithSensitiveName(mc.getArgument(0)) and
|
||||
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
|
||||
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
|
||||
// Passed as third argument to `IResponseCookies.Append`
|
||||
exists(DataFlow::Node creation, DataFlow::Node append |
|
||||
CookieOptionsTracking::flow(creation, append) and
|
||||
creation.asExpr() = oc and
|
||||
append.asExpr() = mc.getArgument(2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(PropertyWrite pw |
|
||||
(
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
|
||||
pw.getProperty().getDeclaringType() instanceof
|
||||
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
|
||||
) and
|
||||
pw.getProperty().getName() = "HttpOnly" and
|
||||
a.getLValue() = pw and
|
||||
DataFlow::localExprFlow(val, a.getRValue())
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(Call c |
|
||||
httpOnlySink = c and
|
||||
(
|
||||
exists(MicrosoftAspNetCoreHttpResponseCookies iResponse, MethodCall mc |
|
||||
// default is not configured or is not set to `Always`
|
||||
not getAValueForCookiePolicyProp("HttpOnly").getValue() = "1" and
|
||||
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
|
||||
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
|
||||
iResponse.getAppendMethod() = mc.getTarget() and
|
||||
isCookieWithSensitiveName(mc.getArgument(0)) and
|
||||
(
|
||||
// `HttpOnly` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
|
||||
exists(ObjectCreation oc |
|
||||
oc = c and
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
not isPropertySet(oc, "HttpOnly") and
|
||||
exists(DataFlow::Node creation |
|
||||
CookieOptionsTracking::flow(creation, _) and
|
||||
creation.asExpr() = oc
|
||||
)
|
||||
)
|
||||
or
|
||||
// IResponseCookies.Append(String, String) was called, `HttpOnly` is set to `false` by default
|
||||
mc = c and
|
||||
mc.getNumberOfArguments() < 3
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(ObjectCreation oc |
|
||||
oc = c and
|
||||
oc.getType() instanceof SystemWebHttpCookie and
|
||||
isCookieWithSensitiveName(oc.getArgument(0)) and
|
||||
// the property wasn't explicitly set, so a default value from config is used
|
||||
not isPropertySet(oc, "HttpOnly") and
|
||||
// the default in config is not set to `true`
|
||||
not exists(XmlElement element |
|
||||
element instanceof HttpCookiesElement and
|
||||
element.(HttpCookiesElement).isHttpOnlyCookies()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) and
|
||||
message = "Cookie attribute 'HttpOnly' is not set to true."
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Sensitive data that is transmitted using HTTP is vulnerable to being read by a third party. By default,
|
||||
cookies are sent via HTTP, not HTTPS.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
In ASP.NET case when using cookies ensure that HTTPS is used by setting the property <code>Microsoft.AspNetCore.Http.CookieOptions.Secure</code> to <code>true</code>.
|
||||
</p>
|
||||
<p>
|
||||
In ASP.NET Core case when using cookies, ensure that HTTPS is used, either via the <code><forms></code> attribute above, or
|
||||
the <code><httpCookies></code> element, with the attribute <code>requireSSL="true"</code>. It is also possible to require cookies
|
||||
to use HTTPS programmatically, by setting the property <code>System.Web.HttpCookie.Secure</code> to <code>true</code>.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the example below <code>Microsoft.AspNetCore.Http.CookieOptions.Secure</code> is set to <code>true</code> programmatically.
|
||||
</p>
|
||||
|
||||
<sample src="secureflagcore.cs" />
|
||||
|
||||
<p>
|
||||
In the following example <code>CookiePolicyOptions</code> are set programmatically to configure defaults.
|
||||
</p>
|
||||
|
||||
<sample src="cookiepolicyoptions.cs" />
|
||||
|
||||
<p>
|
||||
In the example below <code>System.Web.HttpCookie.Secure</code> is set to <code>true</code> programmatically.
|
||||
</p>
|
||||
|
||||
<sample src="secureflag.cs" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li><a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookieoptions.secure">CookieOptions.Secure Property,</a></li>
|
||||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header,</li>
|
||||
<li><a href="https://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.requiressl(v=vs.110).aspx">FormsAuthentication.RequireSSL Property,</a></li>
|
||||
<li><a href="https://msdn.microsoft.com/en-us/library/1d3t3c61(v=vs.100).aspx">forms Element for authentication,</a></li>
|
||||
<li><a href="https://msdn.microsoft.com/library/ms228262%28v=vs.100%29.aspx">httpCookies Element,</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,107 +0,0 @@
|
||||
/**
|
||||
* @name 'Secure' attribute is not set to true
|
||||
* @description Omitting the 'Secure' attribute allows data to be transmitted insecurely
|
||||
* using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS
|
||||
* is used at all times.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id cs/web/cookie-secure-not-set
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-319
|
||||
* external/cwe/cwe-614
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.asp.WebConfig
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
deprecated import experimental.dataflow.flowsources.AuthCookie
|
||||
|
||||
deprecated query predicate problems(Expr secureSink, string message) {
|
||||
(
|
||||
exists(Call c |
|
||||
secureSink = c and
|
||||
(
|
||||
// default is not configured or is not set to `Always` or `SameAsRequest`
|
||||
not (
|
||||
getAValueForCookiePolicyProp("Secure").getValue() = "0" or
|
||||
getAValueForCookiePolicyProp("Secure").getValue() = "1"
|
||||
) and
|
||||
// there is no callback `OnAppendCookie` that sets `Secure` to true
|
||||
not OnAppendCookieSecureTracking::flowTo(_) and
|
||||
(
|
||||
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
|
||||
exists(ObjectCreation oc |
|
||||
oc = c and
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
not isPropertySet(oc, "Secure") and
|
||||
exists(DataFlow::Node creation |
|
||||
CookieOptionsTracking::flow(creation, _) and
|
||||
creation.asExpr() = oc
|
||||
)
|
||||
)
|
||||
or
|
||||
// IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
|
||||
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
|
||||
mc = c and
|
||||
iResponse.getAppendMethod() = mc.getTarget() and
|
||||
mc.getNumberOfArguments() < 3
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(ObjectCreation oc |
|
||||
oc = c and
|
||||
oc.getType() instanceof SystemWebHttpCookie and
|
||||
// the property wasn't explicitly set, so a default value from config is used
|
||||
not isPropertySet(oc, "Secure") and
|
||||
// the default in config is not set to `true`
|
||||
// the `exists` below covers the `cs/web/requiressl-not-set`
|
||||
not exists(XmlElement element |
|
||||
element instanceof FormsElement and
|
||||
element.(FormsElement).isRequireSsl()
|
||||
or
|
||||
element instanceof HttpCookiesElement and
|
||||
element.(HttpCookiesElement).isRequireSsl()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(Assignment a, Expr val |
|
||||
secureSink = a.getRValue() and
|
||||
(
|
||||
exists(ObjectCreation oc |
|
||||
getAValueForProp(oc, a, "Secure") = val and
|
||||
val.getValue() = "false" and
|
||||
(
|
||||
oc.getType() instanceof SystemWebHttpCookie
|
||||
or
|
||||
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
// there is no callback `OnAppendCookie` that sets `Secure` to true
|
||||
not OnAppendCookieSecureTracking::flowTo(_) and
|
||||
// the cookie option is passed to `Append`
|
||||
exists(DataFlow::Node creation |
|
||||
CookieOptionsTracking::flow(creation, _) and
|
||||
creation.asExpr() = oc
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(PropertyWrite pw |
|
||||
(
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
|
||||
pw.getProperty().getDeclaringType() instanceof
|
||||
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
|
||||
) and
|
||||
pw.getProperty().getName() = "SecurePolicy" and
|
||||
a.getLValue() = pw and
|
||||
DataFlow::localExprFlow(val, a.getRValue()) and
|
||||
val.getValue() = "2" // None
|
||||
)
|
||||
)
|
||||
)
|
||||
) and
|
||||
message = "Cookie attribute 'Secure' is not set to true."
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<authentication>
|
||||
<forms
|
||||
requireSSL="true"
|
||||
... />
|
||||
</authentication>
|
||||
<httpCookies
|
||||
requireSSL="true"
|
||||
... />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,4 +0,0 @@
|
||||
| Program.cs:25:34:25:38 | false | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:38:88:38:92 | false | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:61:34:61:34 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:68:88:68:88 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,37 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
public class MyController : Microsoft.AspNetCore.Mvc.Controller
|
||||
{
|
||||
public void CookieDefault()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
cookieOptions.HttpOnly = false;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly is set in callback
|
||||
}
|
||||
}
|
||||
|
||||
public class Startup
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
app.UseCookiePolicy();
|
||||
}
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions);
|
||||
});
|
||||
}
|
||||
|
||||
private void SetCookies(CookieOptions options)
|
||||
{
|
||||
options.Secure = true;
|
||||
options.HttpOnly = true;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
|
||||
@@ -1,4 +0,0 @@
|
||||
| Program.cs:23:27:23:31 | false | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:28:74:28:78 | false | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:48:27:48:27 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:54:74:54:74 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs
|
||||
@@ -1,2 +0,0 @@
|
||||
| Program.cs:5:9:5:49 | call to method Append | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| Program.cs:15:29:15:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,52 +0,0 @@
|
||||
public class MyController : Microsoft.AspNetCore.Mvc.Controller
|
||||
{
|
||||
public void CookieDefault()
|
||||
{
|
||||
Response.Cookies.Append("auth", "secret"); // BAD: HttpOnly is set to false by default
|
||||
}
|
||||
|
||||
public void CookieDefaultForgery()
|
||||
{
|
||||
Response.Cookies.Append("antiforgerytoken", "secret"); // GOOD: not an auth cookie
|
||||
}
|
||||
|
||||
public void CookieDefault2()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD: HttpOnly is set to false by default
|
||||
}
|
||||
|
||||
public void CookieDelete()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
Response.Cookies.Delete("auth", cookieOptions); // GOOD: Delete call
|
||||
}
|
||||
|
||||
void CookieDirectTrue()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
cookieOptions.HttpOnly = true;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
|
||||
}
|
||||
|
||||
void CookieDirectTrueInitializer()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true };
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
|
||||
}
|
||||
|
||||
void CookieIntermediateTrue()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
bool v = true;
|
||||
cookieOptions.HttpOnly = v;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
|
||||
}
|
||||
|
||||
void CookieIntermediateTrueInitializer()
|
||||
{
|
||||
bool v = true;
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v };
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
|
||||
@@ -1 +0,0 @@
|
||||
| Program.cs:5:22:5:59 | object creation of type HttpCookie | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,36 +0,0 @@
|
||||
class Program
|
||||
{
|
||||
void CookieDefault()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID"); // BAD: httpOnlyCookies is set to false by default
|
||||
}
|
||||
|
||||
void CookieDefaultForgery()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie
|
||||
}
|
||||
|
||||
void CookieDirectTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
cookie.HttpOnly = true; // GOOD
|
||||
}
|
||||
|
||||
void CookieDirectTrueInitializer()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD
|
||||
}
|
||||
|
||||
void CookieIntermediateTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
bool v = true;
|
||||
cookie.HttpOnly = v; // GOOD: should track local data flow
|
||||
}
|
||||
|
||||
void CookieIntermediateTrueInitializer()
|
||||
{
|
||||
bool v = true;
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs
|
||||
@@ -1 +0,0 @@
|
||||
| Program.cs:5:22:5:59 | object creation of type HttpCookie | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,36 +0,0 @@
|
||||
class Program
|
||||
{
|
||||
void CookieDefault()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID"); // BAD: httpOnlyCookies is set to false in config
|
||||
}
|
||||
|
||||
void CookieDefaultForgery()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie
|
||||
}
|
||||
|
||||
void CookieDirectTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
cookie.HttpOnly = true; // GOOD
|
||||
}
|
||||
|
||||
void CookieDirectTrueInitializer()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD
|
||||
}
|
||||
|
||||
void CookieIntermediateTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
bool v = true;
|
||||
cookie.HttpOnly = v; // GOOD: should track local data flow
|
||||
}
|
||||
|
||||
void CookieIntermediateTrueInitializer()
|
||||
{
|
||||
bool v = true;
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpCookies httpOnlyCookies="false" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,36 +0,0 @@
|
||||
class Program
|
||||
{
|
||||
void CookieDefault()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID"); // GOOD: httpOnlyCookies is set to true in config
|
||||
}
|
||||
|
||||
void CookieDefaultForgery()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie
|
||||
}
|
||||
|
||||
void CookieDirectTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
cookie.HttpOnly = true; // GOOD
|
||||
}
|
||||
|
||||
void CookieDirectTrueInitializer()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD
|
||||
}
|
||||
|
||||
void CookieIntermediateTrue()
|
||||
{
|
||||
var cookie = new System.Web.HttpCookie("sessionID");
|
||||
bool v = true;
|
||||
cookie.HttpOnly = v; // GOOD: should track local data flow
|
||||
}
|
||||
|
||||
void CookieIntermediateTrueInitializer()
|
||||
{
|
||||
bool v = true;
|
||||
var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpCookies httpOnlyCookies="true" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs
|
||||
@@ -1,47 +0,0 @@
|
||||
public class MyController : Microsoft.AspNetCore.Mvc.Controller
|
||||
{
|
||||
public void CookieDefault()
|
||||
{
|
||||
Response.Cookies.Append("name", "value"); // BAD: requireSSL is set to false by default
|
||||
}
|
||||
|
||||
public void CookieDefault2()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
Response.Cookies.Append("name", "value", cookieOptions); // BAD: requireSSL is set to false by default
|
||||
}
|
||||
|
||||
public void CookieDelete()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
Response.Cookies.Delete("name", cookieOptions); // GOOD: Delete call
|
||||
}
|
||||
|
||||
void CookieDirectTrue()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
cookieOptions.Secure = true;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
|
||||
}
|
||||
|
||||
void CookieDirectTrueInitializer()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = true };
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
|
||||
}
|
||||
|
||||
void CookieIntermediateTrue()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
bool v = true;
|
||||
cookieOptions.Secure = v;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
|
||||
}
|
||||
|
||||
void CookieIntermediateTrueInitializer()
|
||||
{
|
||||
bool v = true;
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v };
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
| Program.cs:5:9:5:48 | call to method Append | Cookie attribute 'Secure' is not set to true. |
|
||||
| Program.cs:10:29:10:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1,3 +0,0 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1,4 +0,0 @@
|
||||
| Program.cs:25:32:25:36 | false | Cookie attribute 'Secure' is not set to true. |
|
||||
| Program.cs:31:86:31:90 | false | Cookie attribute 'Secure' is not set to true. |
|
||||
| Program.cs:54:32:54:32 | access to local variable v | Cookie attribute 'Secure' is not set to true. |
|
||||
| Program.cs:61:86:61:86 | access to local variable v | Cookie attribute 'Secure' is not set to true. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
@@ -1,37 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
public class MyController : Microsoft.AspNetCore.Mvc.Controller
|
||||
{
|
||||
public void CookieDefault()
|
||||
{
|
||||
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
|
||||
cookieOptions.Secure = false;
|
||||
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in callback
|
||||
}
|
||||
}
|
||||
|
||||
public class Startup
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
app.UseCookiePolicy();
|
||||
}
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions);
|
||||
});
|
||||
}
|
||||
|
||||
private void SetCookies(CookieOptions options)
|
||||
{
|
||||
options.Secure = true;
|
||||
options.HttpOnly = true;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security Features/CWE-614/CookieWithoutSecure.ql
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user