Merge branch 'main' into atorralba/promote-ognl-injection

This commit is contained in:
Tony Torralba
2021-07-20 17:17:17 +02:00
2457 changed files with 219307 additions and 31173 deletions

View File

@@ -0,0 +1,97 @@
name: Check framework coverage changes
on:
pull_request:
paths:
- '.github/workflows/csv-coverage-pr-comment.yml'
- '*/ql/src/**/*.ql'
- '*/ql/src/**/*.qll'
- 'misc/scripts/library-coverage/*.py'
# input data files
- '*/documentation/library-coverage/cwe-sink.csv'
- '*/documentation/library-coverage/frameworks.csv'
branches:
- main
- 'rc/*'
jobs:
generate:
name: Generate framework coverage artifacts
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v2
with:
path: merge
- name: Clone self (github/codeql) - BASE
uses: actions/checkout@v2
with:
fetch-depth: 2
path: base
- run: |
git checkout HEAD^1
git log -1 --format='%H'
working-directory: base
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Generate CSV files on merge commit of the PR
run: |
echo "Running generator on merge"
PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
mkdir out_merge
cp framework-coverage-*.csv out_merge/
cp framework-coverage-*.rst out_merge/
- name: Generate CSV files on base commit of the PR
run: |
echo "Running generator on base"
PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base
mkdir out_base
cp framework-coverage-*.csv out_base/
cp framework-coverage-*.rst out_base/
- name: Generate diff of coverage reports
run: |
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
- name: Upload CSV package list
uses: actions/upload-artifact@v2
with:
name: csv-framework-coverage-merge
path: |
out_merge/framework-coverage-*.csv
out_merge/framework-coverage-*.rst
- name: Upload CSV package list
uses: actions/upload-artifact@v2
with:
name: csv-framework-coverage-base
path: |
out_base/framework-coverage-*.csv
out_base/framework-coverage-*.rst
- name: Upload comparison results
uses: actions/upload-artifact@v2
with:
name: comparison
path: |
comparison.md
- name: Save PR number
run: |
mkdir -p pr
echo ${{ github.event.pull_request.number }} > pr/NR
- name: Upload PR number
uses: actions/upload-artifact@v2
with:
name: pr
path: pr/

View File

@@ -0,0 +1,34 @@
name: Comment on PR with framework coverage changes
on:
workflow_run:
workflows: ["Check framework coverage changes"]
types:
- completed
jobs:
check:
name: Check framework coverage differences and comment
runs-on: ubuntu-latest
if: >
${{ github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Check coverage difference file and comment
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_ID: ${{ github.event.workflow_run.id }}
run: |
python misc/scripts/library-coverage/comment-pr.py "$GITHUB_REPOSITORY" "$RUN_ID"

View File

@@ -0,0 +1,42 @@
name: Build framework coverage timeseries reports
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone self (github/codeql)
uses: actions/checkout@v2
with:
path: script
- name: Clone self (github/codeql) for analysis
uses: actions/checkout@v2
with:
path: codeqlModels
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Build modeled package list
run: |
CLI=$(realpath "codeql-cli/codeql")
echo $CLI
PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels
- name: Upload timeseries CSV
uses: actions/upload-artifact@v2
with:
name: framework-coverage-timeseries
path: framework-coverage-timeseries-*.csv

View File

@@ -0,0 +1,44 @@
name: Update framework coverage reports
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
jobs:
update:
name: Update framework coverage report
if: github.event.repository.fork == false
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v2
with:
path: ql
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Generate coverage files
run: |
PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
- name: Create pull request with changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY"

View File

@@ -1,4 +1,4 @@
name: Build/check CSV flow coverage report name: Build framework coverage reports
on: on:
workflow_dispatch: workflow_dispatch:
@@ -6,22 +6,6 @@ on:
qlModelShaOverride: qlModelShaOverride:
description: 'github/codeql repo SHA used for looking up the CSV models' description: 'github/codeql repo SHA used for looking up the CSV models'
required: false required: false
push:
branches:
- main
- 'rc/**'
pull_request:
paths:
- '.github/workflows/csv-coverage.yml'
- '*/ql/src/**/*.ql'
- '*/ql/src/**/*.qll'
- 'misc/scripts/library-coverage/*.py'
# input data files
- '*/documentation/library-coverage/cwe-sink.csv'
- '*/documentation/library-coverage/frameworks.csv'
# coverage report files
- '*/documentation/library-coverage/flow-model-coverage.csv'
- '*/documentation/library-coverage/flow-model-coverage.rst'
jobs: jobs:
build: build:
@@ -33,28 +17,20 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
path: script path: script
- name: Clone self (github/codeql) at a given SHA for analysis
if: github.event.inputs.qlModelShaOverride != ''
uses: actions/checkout@v2
with:
path: codeqlModels
ref: github.event.inputs.qlModelShaOverride
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
if: github.event.inputs.qlModelShaOverride == ''
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
path: codeqlModels path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v2 uses: actions/setup-python@v2
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
uses: dsaltares/fetch-gh-release-asset@aa37ae5c44d3c9820bc12fe675e8670ecd93bd1c env:
with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
repo: "github/codeql-cli-binaries" run: |
version: "latest" gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
file: "codeql-linux64.zip"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unzip CodeQL CLI - name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip run: unzip -d codeql-cli codeql-linux64.zip
- name: Build modeled package list - name: Build modeled package list
@@ -63,15 +39,11 @@ jobs:
- name: Upload CSV package list - name: Upload CSV package list
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: csv-flow-model-coverage name: framework-coverage-csv
path: flow-model-coverage-*.csv path: framework-coverage-*.csv
- name: Upload RST package list - name: Upload RST package list
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: rst-flow-model-coverage name: framework-coverage-rst
path: flow-model-coverage-*.rst path: framework-coverage-*.rst
# - name: Check coverage files
# if: github.event.pull_request
# run: |
# python script/misc/scripts/library-coverage/compare-files.py codeqlModels

View File

@@ -17,3 +17,9 @@
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go /java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go /java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go /java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
# CodeQL tools and associated docs
/docs/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers

View File

@@ -448,5 +448,17 @@
"SensitiveDataHeuristics Python/JS": [ "SensitiveDataHeuristics Python/JS": [
"javascript/ql/src/semmle/javascript/security/internal/SensitiveDataHeuristics.qll", "javascript/ql/src/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
"python/ql/src/semmle/python/security/internal/SensitiveDataHeuristics.qll" "python/ql/src/semmle/python/security/internal/SensitiveDataHeuristics.qll"
],
"ReDoS Util Python/JS": [
"javascript/ql/src/semmle/javascript/security/performance/ReDoSUtil.qll",
"python/ql/src/semmle/python/security/performance/ReDoSUtil.qll"
],
"ReDoS Exponential Python/JS": [
"javascript/ql/src/semmle/javascript/security/performance/ExponentialBackTracking.qll",
"python/ql/src/semmle/python/security/performance/ExponentialBackTracking.qll"
],
"ReDoS Polynomial Python/JS": [
"javascript/ql/src/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
"python/ql/src/semmle/python/security/performance/SuperlinearBackTracking.qll"
] ]
} }

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* The `StackVariableReachability` library now ignores some paths that contain an infeasible combination
of conditionals. These improvements primarily affect the queries `cpp/uninitialized-local` and
`cpp/use-after-free`.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The "Use of a broken or risky cryptographic algorithm" (`cpp/weak-cryptographic-algorithm`) query has been further improved to reduce false positives and its `@precision` increased to `high`.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The DataFlow libraries have been augmented with support for `Configuration`-specific in-place read steps at, for example, sinks and custom taint steps. This means that it is now possible to specify sinks that accept flow with non-empty access paths.

View File

@@ -0,0 +1,2 @@
lgtm
* The 'Uncontrolled data in arithmetic expression' (cpp/uncontrolled-arithmetic) query now recognizes more sources of randomness.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Wrong type of arguments to formatting function' (cpp/wrong-type-format-argument) query is now more accepting of the string and character formatting differences between Microsoft and non-Microsoft platforms. There are now fewer false positive results.

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/offset-use-before-range-check * @id cpp/offset-use-before-range-check
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.2
* @precision medium * @precision medium
* @tags reliability * @tags reliability
* security * security

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/descriptor-may-not-be-closed * @id cpp/descriptor-may-not-be-closed
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-775 * external/cwe/cwe-775

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/descriptor-never-closed * @id cpp/descriptor-never-closed
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-775 * external/cwe/cwe-775

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/file-may-not-be-closed * @id cpp/file-may-not-be-closed
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-775 * external/cwe/cwe-775

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/file-never-closed * @id cpp/file-never-closed
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-775 * external/cwe/cwe-775

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/global-use-before-init * @id cpp/global-use-before-init
* @problem.severity warning * @problem.severity warning
* @security-severity 6.9 * @security-severity 7.8
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-457 * external/cwe/cwe-457

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/inconsistent-nullness-testing * @id cpp/inconsistent-nullness-testing
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-476 * external/cwe/cwe-476

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/initialization-not-run * @id cpp/initialization-not-run
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 7.5
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-456 * external/cwe/cwe-456

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/late-negative-test * @id cpp/late-negative-test
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-823 * external/cwe/cwe-823

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/memory-may-not-be-freed * @id cpp/memory-may-not-be-freed
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-401 * external/cwe/cwe-401

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/memory-never-freed * @id cpp/memory-never-freed
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @tags efficiency * @tags efficiency
* security * security
* external/cwe/cwe-401 * external/cwe/cwe-401

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/missing-negativity-test * @id cpp/missing-negativity-test
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-823 * external/cwe/cwe-823

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/missing-null-test * @id cpp/missing-null-test
* @problem.severity recommendation * @problem.severity recommendation
* @security-severity 3.6 * @security-severity 7.5
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-476 * external/cwe/cwe-476

View File

@@ -3,7 +3,7 @@
* @description An object that was allocated with 'malloc' or 'new' is being freed using a mismatching 'free' or 'delete'. * @description An object that was allocated with 'malloc' or 'new' is being freed using a mismatching 'free' or 'delete'.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @precision high * @precision high
* @id cpp/new-free-mismatch * @id cpp/new-free-mismatch
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/overflow-calculated * @id cpp/overflow-calculated
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 9.8
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-131 * external/cwe/cwe-131

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/overflow-destination * @id cpp/overflow-destination
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @precision low * @precision low
* @tags reliability * @tags reliability
* security * security

View File

@@ -4,7 +4,7 @@
* may result in a buffer overflow. * may result in a buffer overflow.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/static-buffer-overflow * @id cpp/static-buffer-overflow
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/return-stack-allocated-object * @id cpp/return-stack-allocated-object
* @problem.severity warning * @problem.severity warning
* @security-severity 2.9 * @security-severity 2.1
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-562 * external/cwe/cwe-562

View File

@@ -4,7 +4,7 @@
* an instance of the type of the pointer may result in a buffer overflow * an instance of the type of the pointer may result in a buffer overflow
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 8.1
* @precision medium * @precision medium
* @id cpp/allocation-too-small * @id cpp/allocation-too-small
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* multiple instances of the type of the pointer may result in a buffer overflow * multiple instances of the type of the pointer may result in a buffer overflow
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 8.1
* @precision medium * @precision medium
* @id cpp/suspicious-allocation-size * @id cpp/suspicious-allocation-size
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/use-after-free * @id cpp/use-after-free
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 9.3
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-416 * external/cwe/cwe-416

View File

@@ -7,10 +7,6 @@
import cpp import cpp
class AnonymousCompilation extends Compilation {
override string toString() { result = "<compilation>" }
}
string describe(Compilation c) { string describe(Compilation c) {
if c.getArgument(1) = "--mimic" if c.getArgument(1) = "--mimic"
then result = "compiler invocation " + concat(int i | i > 1 | c.getArgument(i), " " order by i) then result = "compiler invocation " + concat(int i | i > 1 | c.getArgument(i), " " order by i)
@@ -19,4 +15,4 @@ string describe(Compilation c) {
from Compilation c from Compilation c
where not c.normalTermination() where not c.normalTermination()
select c, "Extraction aborted for " + describe(c), 2 select "Extraction aborted for " + describe(c)

View File

@@ -6,7 +6,7 @@
* to a larger type. * to a larger type.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 8.1
* @precision very-high * @precision very-high
* @id cpp/bad-addition-overflow-check * @id cpp/bad-addition-overflow-check
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* be a sign that the result can overflow the type converted from. * be a sign that the result can overflow the type converted from.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.1
* @precision high * @precision high
* @id cpp/integer-multiplication-cast-to-long * @id cpp/integer-multiplication-cast-to-long
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* unsigned integer values. * unsigned integer values.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.1
* @precision high * @precision high
* @id cpp/signed-overflow-check * @id cpp/signed-overflow-check
* @tags correctness * @tags correctness

View File

@@ -6,7 +6,7 @@
* use the width of the base type, leading to misaligned reads. * use the width of the base type, leading to misaligned reads.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @precision high * @precision high
* @id cpp/upcast-array-pointer-arithmetic * @id cpp/upcast-array-pointer-arithmetic
* @tags correctness * @tags correctness

View File

@@ -6,7 +6,7 @@
* from an untrusted source, this can be used for exploits. * from an untrusted source, this can be used for exploits.
* @kind problem * @kind problem
* @problem.severity recommendation * @problem.severity recommendation
* @security-severity 6.9 * @security-severity 9.3
* @precision high * @precision high
* @id cpp/non-constant-format * @id cpp/non-constant-format
* @tags maintainability * @tags maintainability

View File

@@ -3,7 +3,7 @@
* @description Using the return value from snprintf without proper checks can cause overflow. * @description Using the return value from snprintf without proper checks can cause overflow.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.1
* @precision high * @precision high
* @id cpp/overflowing-snprintf * @id cpp/overflowing-snprintf
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* a source of security issues. * a source of security issues.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 2.9 * @security-severity 5.0
* @precision high * @precision high
* @id cpp/wrong-number-format-arguments * @id cpp/wrong-number-format-arguments
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* behavior. * behavior.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 6.4 * @security-severity 7.5
* @precision high * @precision high
* @id cpp/wrong-type-format-argument * @id cpp/wrong-type-format-argument
* @tags reliability * @tags reliability
@@ -19,28 +19,32 @@ import cpp
* Holds if the argument corresponding to the `pos` conversion specifier * Holds if the argument corresponding to the `pos` conversion specifier
* of `ffc` is expected to have type `expected`. * of `ffc` is expected to have type `expected`.
*/ */
pragma[noopt]
private predicate formattingFunctionCallExpectedType( private predicate formattingFunctionCallExpectedType(
FormattingFunctionCall ffc, int pos, Type expected FormattingFunctionCall ffc, int pos, Type expected
) { ) {
exists(FormattingFunction f, int i, FormatLiteral fl | ffc.getFormat().(FormatLiteral).getConversionType(pos) = expected
ffc instanceof FormattingFunctionCall and
ffc.getTarget() = f and
f.getFormatParameterIndex() = i and
ffc.getArgument(i) = fl and
fl.getConversionType(pos) = expected
)
} }
/** /**
* Holds if the argument corresponding to the `pos` conversion specifier * Holds if the argument corresponding to the `pos` conversion specifier
* of `ffc` is expected to have type `expected` and the corresponding * of `ffc` could alternatively have type `expected`, for example on a different
* argument `arg` has type `actual`. * platform.
*/
private predicate formattingFunctionCallAlternateType(
FormattingFunctionCall ffc, int pos, Type expected
) {
ffc.getFormat().(FormatLiteral).getConversionTypeAlternate(pos) = expected
}
/**
* Holds if the argument corresponding to the `pos` conversion specifier
* of `ffc` is `arg` and has type `actual`.
*/ */
pragma[noopt] pragma[noopt]
predicate formatArgType(FormattingFunctionCall ffc, int pos, Type expected, Expr arg, Type actual) { predicate formattingFunctionCallActualType(
FormattingFunctionCall ffc, int pos, Expr arg, Type actual
) {
exists(Expr argConverted | exists(Expr argConverted |
formattingFunctionCallExpectedType(ffc, pos, expected) and
ffc.getConversionArgument(pos) = arg and ffc.getConversionArgument(pos) = arg and
argConverted = arg.getFullyConverted() and argConverted = arg.getFullyConverted() and
actual = argConverted.getType() actual = argConverted.getType()
@@ -72,7 +76,8 @@ class ExpectedType extends Type {
ExpectedType() { ExpectedType() {
exists(Type t | exists(Type t |
( (
formatArgType(_, _, t, _, _) or formattingFunctionCallExpectedType(_, _, t) or
formattingFunctionCallAlternateType(_, _, t) or
formatOtherArgType(_, _, t, _, _) formatOtherArgType(_, _, t, _, _)
) and ) and
this = t.getUnspecifiedType() this = t.getUnspecifiedType()
@@ -91,7 +96,11 @@ class ExpectedType extends Type {
*/ */
predicate trivialConversion(ExpectedType expected, Type actual) { predicate trivialConversion(ExpectedType expected, Type actual) {
exists(Type exp, Type act | exists(Type exp, Type act |
formatArgType(_, _, exp, _, act) and (
formattingFunctionCallExpectedType(_, _, exp) or
formattingFunctionCallAlternateType(_, _, exp)
) and
formattingFunctionCallActualType(_, _, _, act) and
expected = exp.getUnspecifiedType() and expected = exp.getUnspecifiedType() and
actual = act.getUnspecifiedType() actual = act.getUnspecifiedType()
) and ) and
@@ -146,9 +155,13 @@ int sizeof_IntType() { exists(IntType it | result = it.getSize()) }
from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual
where where
( (
formatArgType(ffc, n, expected, arg, actual) and formattingFunctionCallExpectedType(ffc, n, expected) and
formattingFunctionCallActualType(ffc, n, arg, actual) and
not exists(Type anyExpected | not exists(Type anyExpected |
formatArgType(ffc, n, anyExpected, arg, actual) and (
formattingFunctionCallExpectedType(ffc, n, anyExpected) or
formattingFunctionCallAlternateType(ffc, n, anyExpected)
) and
trivialConversion(anyExpected.getUnspecifiedType(), actual.getUnspecifiedType()) trivialConversion(anyExpected.getUnspecifiedType(), actual.getUnspecifiedType())
) )
or or

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/incorrect-not-operator-usage * @id cpp/incorrect-not-operator-usage
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @precision medium * @precision medium
* @tags security * @tags security
* external/cwe/cwe-480 * external/cwe/cwe-480

View File

@@ -3,7 +3,7 @@
* @description Using alloca in a loop can lead to a stack overflow * @description Using alloca in a loop can lead to a stack overflow
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 7.5
* @precision high * @precision high
* @id cpp/alloca-in-loop * @id cpp/alloca-in-loop
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/improper-null-termination * @id cpp/improper-null-termination
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @tags security * @tags security
* external/cwe/cwe-170 * external/cwe/cwe-170
* external/cwe/cwe-665 * external/cwe/cwe-665

View File

@@ -4,7 +4,7 @@
* on undefined behavior and may lead to memory corruption. * on undefined behavior and may lead to memory corruption.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 2.9 * @security-severity 2.1
* @precision high * @precision high
* @id cpp/pointer-overflow-check * @id cpp/pointer-overflow-check
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* as the third argument may result in a buffer overflow. * as the third argument may result in a buffer overflow.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/bad-strncpy-size * @id cpp/bad-strncpy-size
* @tags reliability * @tags reliability

View File

@@ -3,7 +3,7 @@
* @description Calling 'strncat' with an incorrect size argument may result in a buffer overflow. * @description Calling 'strncat' with an incorrect size argument may result in a buffer overflow.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 10.0 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/unsafe-strncat * @id cpp/unsafe-strncat
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* the machine pointer size. * the machine pointer size.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision medium * @precision medium
* @id cpp/suspicious-sizeof * @id cpp/suspicious-sizeof
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/uninitialized-local * @id cpp/uninitialized-local
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @precision medium * @precision medium
* @tags security * @tags security
* external/cwe/cwe-665 * external/cwe/cwe-665

View File

@@ -4,7 +4,7 @@
* may result in a buffer overflow * may result in a buffer overflow
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 9.8
* @precision medium * @precision medium
* @id cpp/unsafe-strcat * @id cpp/unsafe-strcat
* @tags reliability * @tags reliability

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/self-assignment-check * @id cpp/self-assignment-check
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.0
* @tags reliability * @tags reliability
* security * security
* external/cwe/cwe-826 * external/cwe/cwe-826

View File

@@ -6,7 +6,7 @@
* @kind path-problem * @kind path-problem
* @id cpp/unsafe-use-of-this * @id cpp/unsafe-use-of-this
* @problem.severity error * @problem.severity error
* @security-severity 3.6 * @security-severity 7.5
* @precision very-high * @precision very-high
* @tags correctness * @tags correctness
* language-features * language-features

View File

@@ -7,7 +7,7 @@
* undefined data. * undefined data.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 2.9 * @security-severity 5.0
* @precision very-high * @precision very-high
* @id cpp/too-few-arguments * @id cpp/too-few-arguments
* @tags correctness * @tags correctness

View File

@@ -9,7 +9,6 @@
* @tags reliability * @tags reliability
* external/cwe/cwe-573 * external/cwe/cwe-573
* external/cwe/cwe-252 * external/cwe/cwe-252
* @opaque-id SM02344
* @microsoft.severity Important * @microsoft.severity Important
*/ */

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/memset-may-be-deleted * @id cpp/memset-may-be-deleted
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 7.8
* @precision high * @precision high
* @tags security * @tags security
* external/cwe/cwe-14 * external/cwe/cwe-14

View File

@@ -5,7 +5,7 @@
* @kind path-problem * @kind path-problem
* @precision low * @precision low
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 7.8
* @tags security external/cwe/cwe-20 * @tags security external/cwe/cwe-20
*/ */

View File

@@ -5,7 +5,7 @@
* @kind path-problem * @kind path-problem
* @precision low * @precision low
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 7.8
* @tags security external/cwe/cwe-20 * @tags security external/cwe/cwe-20
*/ */

View File

@@ -4,7 +4,7 @@
* attacker to access unexpected resources. * attacker to access unexpected resources.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 7.5
* @precision medium * @precision medium
* @id cpp/path-injection * @id cpp/path-injection
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* to command injection. * to command injection.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.8
* @precision low * @precision low
* @id cpp/command-line-injection * @id cpp/command-line-injection
* @tags security * @tags security

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability. * allows for a cross-site scripting vulnerability.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @security-severity 2.9 * @security-severity 6.1
* @precision high * @precision high
* @id cpp/cgi-xss * @id cpp/cgi-xss
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* to SQL Injection. * to SQL Injection.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @security-severity 6.4 * @security-severity 8.8
* @precision high * @precision high
* @id cpp/sql-injection * @id cpp/sql-injection
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* commands. * commands.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.0 * @security-severity 8.2
* @precision medium * @precision medium
* @id cpp/uncontrolled-process-operation * @id cpp/uncontrolled-process-operation
* @tags security * @tags security

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/overflow-buffer * @id cpp/overflow-buffer
* @problem.severity recommendation * @problem.severity recommendation
* @security-severity 10.0 * @security-severity 9.3
* @tags security * @tags security
* external/cwe/cwe-119 * external/cwe/cwe-119
* external/cwe/cwe-121 * external/cwe/cwe-121

View File

@@ -5,7 +5,7 @@
* overflow. * overflow.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.3
* @precision high * @precision high
* @id cpp/badly-bounded-write * @id cpp/badly-bounded-write
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* of data written may overflow. * of data written may overflow.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/overrunning-write * @id cpp/overrunning-write
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* take extreme values. * take extreme values.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/overrunning-write-with-float * @id cpp/overrunning-write-with-float
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* of data written may overflow. * of data written may overflow.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.3
* @precision medium * @precision medium
* @id cpp/unbounded-write * @id cpp/unbounded-write
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* a specific value to terminate the argument list. * a specific value to terminate the argument list.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision medium * @precision medium
* @id cpp/unterminated-variadic-call * @id cpp/unterminated-variadic-call
* @tags reliability * @tags reliability

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/unclear-array-index-validation * @id cpp/unclear-array-index-validation
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @tags security * @tags security
* external/cwe/cwe-129 * external/cwe/cwe-129
*/ */

View File

@@ -5,7 +5,7 @@
* terminator can cause a buffer overrun. * terminator can cause a buffer overrun.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 9.8
* @precision high * @precision high
* @id cpp/no-space-for-terminator * @id cpp/no-space-for-terminator
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* or data representation problems. * or data representation problems.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.9 * @security-severity 9.3
* @precision high * @precision high
* @id cpp/tainted-format-string * @id cpp/tainted-format-string
* @tags reliability * @tags reliability

View File

@@ -5,7 +5,7 @@
* or data representation problems. * or data representation problems.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.9 * @security-severity 9.3
* @precision high * @precision high
* @id cpp/tainted-format-string-through-global * @id cpp/tainted-format-string-through-global
* @tags reliability * @tags reliability

View File

@@ -2,9 +2,9 @@
* @name User-controlled data in arithmetic expression * @name User-controlled data in arithmetic expression
* @description Arithmetic operations on user-controlled data that is * @description Arithmetic operations on user-controlled data that is
* not validated can cause overflows. * not validated can cause overflows.
* @kind problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.6
* @precision low * @precision low
* @id cpp/tainted-arithmetic * @id cpp/tainted-arithmetic
* @tags security * @tags security
@@ -16,22 +16,39 @@ import cpp
import semmle.code.cpp.security.Overflow import semmle.code.cpp.security.Overflow
import semmle.code.cpp.security.Security import semmle.code.cpp.security.Security
import semmle.code.cpp.security.TaintTracking import semmle.code.cpp.security.TaintTracking
import TaintedWithPath
import Bounded
from Expr origin, Operation op, Expr e, string effect bindingset[op]
where predicate missingGuard(Operation op, Expr e, string effect) {
isUserInput(origin, _) and
tainted(origin, e) and
op.getAnOperand() = e and
(
missingGuardAgainstUnderflow(op, e) and effect = "underflow" missingGuardAgainstUnderflow(op, e) and effect = "underflow"
or or
missingGuardAgainstOverflow(op, e) and effect = "overflow" missingGuardAgainstOverflow(op, e) and effect = "overflow"
or or
not e instanceof VariableAccess and effect = "overflow" not e instanceof VariableAccess and effect = "overflow"
) and }
(
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element e) {
exists(Operation op |
missingGuard(op, e, _) and
op.getAnOperand() = e
|
op instanceof UnaryArithmeticOperation or op instanceof UnaryArithmeticOperation or
op instanceof BinaryArithmeticOperation op instanceof BinaryArithmeticOperation
) )
select e, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", }
origin, "User-provided value"
override predicate isBarrier(Expr e) {
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
}
}
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
where
taintedWithPath(origin, e, sourceNode, sinkNode) and
op.getAnOperand() = e and
missingGuard(op, e, effect)
select e, sourceNode, sinkNode,
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", origin,
"User-provided value"

View File

@@ -4,7 +4,7 @@
* validated can cause overflows. * validated can cause overflows.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.6
* @precision medium * @precision medium
* @id cpp/uncontrolled-arithmetic * @id cpp/uncontrolled-arithmetic
* @tags security * @tags security
@@ -15,106 +15,61 @@
import cpp import cpp
import semmle.code.cpp.security.Overflow import semmle.code.cpp.security.Overflow
import semmle.code.cpp.security.Security import semmle.code.cpp.security.Security
import semmle.code.cpp.security.TaintTracking import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis import semmle.code.cpp.ir.dataflow.TaintTracking
import TaintedWithPath import DataFlow::PathGraph
import Bounded
predicate isUnboundedRandCall(FunctionCall fc) { /**
exists(Function func | func = fc.getTarget() | * A function that outputs random data such as `std::rand`.
func.hasGlobalOrStdOrBslName("rand") and */
not bounded(fc) and abstract class RandomFunction extends Function {
func.getNumberOfParameters() = 0 /**
) * Gets the `FunctionOutput` that describes how this function returns the random data.
*/
FunctionOutput getFunctionOutput() { result.isReturnValue() }
} }
/** /**
* An operand `e` of a division expression (i.e., `e` is an operand of either a `DivExpr` or * The standard function `std::rand`.
* a `AssignDivExpr`) is bounded when `e` is the left-hand side of the division.
*/ */
pragma[inline] private class StdRand extends RandomFunction {
predicate boundedDiv(Expr e, Expr left) { e = left } StdRand() {
this.hasGlobalOrStdOrBslName("rand") and
/** this.getNumberOfParameters() = 0
* An operand `e` of a remainder expression `rem` (i.e., `rem` is either a `RemExpr` or }
* an `AssignRemExpr`) with left-hand side `left` and right-ahnd side `right` is bounded
* when `e` is `left` and `right` is upper bounded by some number that is less than the maximum integer
* allowed by the result type of `rem`.
*/
pragma[inline]
predicate boundedRem(Expr e, Expr rem, Expr left, Expr right) {
e = left and
upperBound(right.getFullyConverted()) < exprMaxVal(rem.getFullyConverted())
} }
/** /**
* An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr` * The Unix function `rand_r`.
* or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper
* bounded by some number that is less than the maximum integer allowed by the result type of `andExpr`.
*/ */
pragma[inline] private class RandR extends RandomFunction {
predicate boundedBitwiseAnd(Expr e, Expr andExpr, Expr operand1, Expr operand2) { RandR() {
operand1 != operand2 and this.hasGlobalName("rand_r") and
e = operand1 and this.getNumberOfParameters() = 1
upperBound(operand2.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted()) }
} }
/** /**
* Holds if `fc` is a part of the left operand of a binary operation that greatly reduces the range * The Unix function `random`.
* of possible values.
*/ */
predicate bounded(Expr e) { private class Random extends RandomFunction {
// For `%` and `&` we require that `e` is bounded by a value that is strictly smaller than the Random() {
// maximum possible value of the result type of the operation. this.hasGlobalName("random") and
// For example, the function call `rand()` is considered bounded in the following program: this.getNumberOfParameters() = 1
// ``` }
// int i = rand() % (UINT8_MAX + 1);
// ```
// but not in:
// ```
// unsigned char uc = rand() % (UINT8_MAX + 1);
// ```
exists(RemExpr rem | boundedRem(e, rem, rem.getLeftOperand(), rem.getRightOperand()))
or
exists(AssignRemExpr rem | boundedRem(e, rem, rem.getLValue(), rem.getRValue()))
or
exists(BitwiseAndExpr andExpr |
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
)
or
exists(AssignAndExpr andExpr |
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
)
or
// Optimitically assume that a division always yields a much smaller value.
boundedDiv(e, any(DivExpr div).getLeftOperand())
or
boundedDiv(e, any(AssignDivExpr div).getLValue())
or
boundedDiv(e, any(RShiftExpr shift).getLeftOperand())
or
boundedDiv(e, any(AssignRShiftExpr div).getLValue())
} }
predicate isUnboundedRandCallOrParent(Expr e) { /**
isUnboundedRandCall(e) * The Windows `rand_s` function.
or */
isUnboundedRandCallOrParent(e.getAChild()) private class RandS extends RandomFunction {
RandS() {
this.hasGlobalName("rand_s") and
this.getNumberOfParameters() = 1
} }
predicate isUnboundedRandValue(Expr e) { override FunctionOutput getFunctionOutput() { result.isParameterDeref(0) }
isUnboundedRandCall(e)
or
exists(MacroInvocation mi |
e = mi.getExpr() and
isUnboundedRandCallOrParent(e)
)
}
class SecurityOptionsArith extends SecurityOptions {
override predicate isUserInput(Expr expr, string cause) {
isUnboundedRandValue(expr) and
cause = "rand"
}
} }
predicate missingGuard(VariableAccess va, string effect) { predicate missingGuard(VariableAccess va, string effect) {
@@ -125,16 +80,47 @@ predicate missingGuard(VariableAccess va, string effect) {
) )
} }
class Configuration extends TaintTrackingConfiguration { class UncontrolledArithConfiguration extends TaintTracking::Configuration {
override predicate isSink(Element e) { missingGuard(e, _) } UncontrolledArithConfiguration() { this = "UncontrolledArithConfiguration" }
override predicate isBarrier(Expr e) { super.isBarrier(e) or bounded(e) } override predicate isSource(DataFlow::Node source) {
exists(RandomFunction rand, Call call | call.getTarget() = rand |
rand.getFunctionOutput().isReturnValue() and
source.asExpr() = call
or
exists(int n |
source.asDefiningArgument() = call.getArgument(n) and
rand.getFunctionOutput().isParameterDeref(n)
)
)
} }
from Expr origin, VariableAccess va, string effect, PathNode sourceNode, PathNode sinkNode override predicate isSink(DataFlow::Node sink) { missingGuard(sink.asExpr(), _) }
override predicate isSanitizer(DataFlow::Node node) {
bounded(node.asExpr())
or
// If this expression is part of bitwise 'and' or 'or' operation it's likely that the value is
// only used as a bit pattern.
node.asExpr() =
any(Operation op |
op instanceof BitwiseOrExpr or
op instanceof BitwiseAndExpr or
op instanceof ComplementExpr
).getAnOperand*()
}
}
/** Gets the expression that corresponds to `node`, if any. */
Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] }
from
UncontrolledArithConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink,
VariableAccess va, string effect
where where
taintedWithPath(origin, va, sourceNode, sinkNode) and config.hasFlowPath(source, sink) and
sink.getNode().asExpr() = va and
missingGuard(va, effect) missingGuard(va, effect)
select va, sourceNode, sinkNode, select sink.getNode(), source, sink,
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", origin, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
"Uncontrolled value" getExpr(source.getNode()), "Uncontrolled value"

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/arithmetic-with-extreme-values * @id cpp/arithmetic-with-extreme-values
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.6
* @precision low * @precision low
* @tags security * @tags security
* reliability * reliability

View File

@@ -0,0 +1,55 @@
/**
* This file provides the `bounded` predicate that is used in both `cpp/uncontrolled-arithmetic`
* and `cpp/tainted-arithmetic`.
*/
private import cpp
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
/**
* An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr`
* or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper
* bounded by some number that is less than the maximum integer allowed by the result type of `andExpr`.
*/
pragma[inline]
private predicate boundedBitwiseAnd(Expr e, Expr andExpr, Expr operand1, Expr operand2) {
operand1 != operand2 and
e = operand1 and
upperBound(operand2.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
}
/**
* Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operand of an
* operation that may greatly reduce the range of possible values.
*/
predicate bounded(Expr e) {
(
e instanceof UnaryArithmeticOperation or
e instanceof BinaryArithmeticOperation or
e instanceof AssignArithmeticOperation
) and
not convertedExprMightOverflow(e)
or
// Optimitically assume that a remainder expression always yields a much smaller value.
e = any(RemExpr rem).getLeftOperand()
or
e = any(AssignRemExpr rem).getLValue()
or
exists(BitwiseAndExpr andExpr |
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
)
or
exists(AssignAndExpr andExpr |
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
)
or
// Optimitically assume that a division always yields a much smaller value.
e = any(DivExpr div).getLeftOperand()
or
e = any(AssignDivExpr div).getLValue()
or
e = any(RShiftExpr shift).getLeftOperand()
or
e = any(AssignRShiftExpr div).getLValue()
}

View File

@@ -5,7 +5,7 @@
* @id cpp/comparison-with-wider-type * @id cpp/comparison-with-wider-type
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @precision high * @precision high
* @tags reliability * @tags reliability
* security * security

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/integer-overflow-tainted * @id cpp/integer-overflow-tainted
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.1
* @precision low * @precision low
* @tags security * @tags security
* external/cwe/cwe-190 * external/cwe/cwe-190

View File

@@ -4,7 +4,7 @@
* user can result in integer overflow. * user can result in integer overflow.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 8.1
* @precision medium * @precision medium
* @id cpp/uncontrolled-allocation-size * @id cpp/uncontrolled-allocation-size
* @tags reliability * @tags reliability

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/unsigned-difference-expression-compared-zero * @id cpp/unsigned-difference-expression-compared-zero
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 9.8
* @precision medium * @precision medium
* @tags security * @tags security
* correctness * correctness

View File

@@ -4,7 +4,7 @@
* @kind problem * @kind problem
* @id cpp/hresult-boolean-conversion * @id cpp/hresult-boolean-conversion
* @problem.severity error * @problem.severity error
* @security-severity 4.2 * @security-severity 7.5
* @precision high * @precision high
* @tags security * @tags security
* external/cwe/cwe-253 * external/cwe/cwe-253

View File

@@ -5,7 +5,7 @@
* vulnerable to spoofing attacks. * vulnerable to spoofing attacks.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.8 * @security-severity 8.1
* @precision medium * @precision medium
* @id cpp/user-controlled-bypass * @id cpp/user-controlled-bypass
* @tags security * @tags security

View File

@@ -4,7 +4,7 @@
* to an attacker. * to an attacker.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.5
* @precision medium * @precision medium
* @id cpp/cleartext-storage-buffer * @id cpp/cleartext-storage-buffer
* @tags security * @tags security

View File

@@ -4,7 +4,7 @@
* to an attacker. * to an attacker.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 7.5
* @precision medium * @precision medium
* @id cpp/cleartext-storage-file * @id cpp/cleartext-storage-file
* @tags security * @tags security

View File

@@ -4,7 +4,7 @@
* database can expose it to an attacker. * database can expose it to an attacker.
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.4 * @security-severity 7.5
* @precision medium * @precision medium
* @id cpp/cleartext-storage-database * @id cpp/cleartext-storage-database
* @tags security * @tags security

View File

@@ -4,8 +4,8 @@
* an attacker to compromise security. * an attacker to compromise security.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.2 * @security-severity 7.5
* @precision medium * @precision high
* @id cpp/weak-cryptographic-algorithm * @id cpp/weak-cryptographic-algorithm
* @tags security * @tags security
* external/cwe/cwe-327 * external/cwe/cwe-327
@@ -70,9 +70,12 @@ EnumConstant getAdditionalEvidenceEnumConst() { isEncryptionAdditionalEvidence(r
predicate getInsecureEncryptionEvidence(FunctionCall fc, Element blame, string description) { predicate getInsecureEncryptionEvidence(FunctionCall fc, Element blame, string description) {
// find use of an insecure algorithm name // find use of an insecure algorithm name
( (
fc.getTarget() = getAnInsecureEncryptionFunction() and exists(FunctionCall fc2 |
blame = fc and fc.getAChild*() = fc2 and
fc2.getTarget() = getAnInsecureEncryptionFunction() and
blame = fc2 and
description = "call to " + fc.getTarget().getName() description = "call to " + fc.getTarget().getName()
)
or or
exists(MacroInvocation mi | exists(MacroInvocation mi |
( (
@@ -93,7 +96,10 @@ predicate getInsecureEncryptionEvidence(FunctionCall fc, Element blame, string d
) and ) and
// find additional evidence that this function is related to encryption. // find additional evidence that this function is related to encryption.
( (
fc.getTarget() = getAnAdditionalEvidenceFunction() exists(FunctionCall fc2 |
fc.getAChild*() = fc2 and
fc2.getTarget() = getAnAdditionalEvidenceFunction()
)
or or
exists(MacroInvocation mi | exists(MacroInvocation mi |
( (
@@ -107,6 +113,27 @@ predicate getInsecureEncryptionEvidence(FunctionCall fc, Element blame, string d
ec = fc.getAnArgument() and ec = fc.getAnArgument() and
ec.getTarget() = getAdditionalEvidenceEnumConst() ec.getTarget() = getAdditionalEvidenceEnumConst()
) )
) and
// exclude calls from templates as this is rarely the right place to flag an
// issue
not fc.isFromTemplateInstantiation(_) and
(
// the function should have an input that looks like a non-constant buffer
exists(Expr e |
fc.getAnArgument() = e and
(
e.getUnspecifiedType() instanceof PointerType or
e.getUnspecifiedType() instanceof ReferenceType or
e.getUnspecifiedType() instanceof ArrayType
) and
not e.getType().isDeeplyConstBelow() and
not e.isConstant()
)
or
// or be a non-const member function of an object
fc.getTarget() instanceof MemberFunction and
not fc.getTarget() instanceof ConstMemberFunction and
not fc.getTarget().isStatic()
) )
} }

View File

@@ -4,7 +4,7 @@
* attackers to retrieve portions of memory. * attackers to retrieve portions of memory.
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.2 * @security-severity 7.5
* @precision very-high * @precision very-high
* @id cpp/openssl-heartbleed * @id cpp/openssl-heartbleed
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* the two operations. * the two operations.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.7
* @precision medium * @precision medium
* @id cpp/toctou-race-condition * @id cpp/toctou-race-condition
* @tags security * @tags security
@@ -16,10 +16,13 @@ import cpp
import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.controlflow.Guards
/** /**
* An operation on a filename. * An operation on a filename that is likely to modify the corresponding file
* and may return an indication of success.
* *
* Note: we're not interested in operations on file descriptors, as they * Note: we're not interested in operations where the file is specified by a
* are better behaved. * descriptor, rather than a filename, as they are better behaved. We are
* interested in functions that take a filename and return a file descriptor,
* however.
*/ */
FunctionCall filenameOperation(Expr path) { FunctionCall filenameOperation(Expr path) {
exists(string name | name = result.getTarget().getName() | exists(string name | name = result.getTarget().getName() |
@@ -48,7 +51,8 @@ FunctionCall filenameOperation(Expr path) {
} }
/** /**
* A use of `access` (or similar) on a filename. * An operation on a filename that returns information in the return value but
* does not modify the corresponding file. For example, `access`.
*/ */
FunctionCall accessCheck(Expr path) { FunctionCall accessCheck(Expr path) {
exists(string name | name = result.getTarget().getName() | exists(string name | name = result.getTarget().getName() |
@@ -62,7 +66,9 @@ FunctionCall accessCheck(Expr path) {
} }
/** /**
* A use of `stat` (or similar) on a filename. * An operation on a filename that returns information via a pointer argument
* and any return value, but does not modify the corresponding file. For
* example, `stat`.
*/ */
FunctionCall stat(Expr path, Expr buf) { FunctionCall stat(Expr path, Expr buf) {
exists(string name | name = result.getTarget().getName() | exists(string name | name = result.getTarget().getName() |
@@ -77,7 +83,7 @@ FunctionCall stat(Expr path, Expr buf) {
} }
/** /**
* Holds if `use` points to `source`, either by being the same or by * Holds if `use` refers to `source`, either by being the same or by
* one step of variable indirection. * one step of variable indirection.
*/ */
predicate referenceTo(Expr source, Expr use) { predicate referenceTo(Expr source, Expr use) {
@@ -88,36 +94,38 @@ predicate referenceTo(Expr source, Expr use) {
) )
} }
from FunctionCall fc, Expr check, Expr checkUse, Expr opUse from Expr check, Expr checkPath, FunctionCall use, Expr usePath
where where
// checkUse looks like a check on a filename // `check` looks like a check on a filename
( (
// either: // either:
// an access check // an access check
check = accessCheck(checkUse) check = accessCheck(checkPath)
or or
// a stat // a stat
check = stat(checkUse, _) check = stat(checkPath, _)
or or
// another filename operation (null pointers can indicate errors) // another filename operation (null pointers can indicate errors)
check = filenameOperation(checkUse) check = filenameOperation(checkPath)
or or
// access to a member variable on the stat buf // access to a member variable on the stat buf
// (morally, this should be a use-use pair, but it seems unlikely // (morally, this should be a use-use pair, but it seems unlikely
// that this variable will get reused in practice) // that this variable will get reused in practice)
exists(Variable buf | exists(stat(checkUse, buf.getAnAccess())) | exists(Variable buf | exists(stat(checkPath, buf.getAnAccess())) |
check.(VariableAccess).getQualifier() = buf.getAnAccess() check.(VariableAccess).getQualifier() = buf.getAnAccess()
) )
) and ) and
// checkUse and opUse refer to the same SSA variable // `checkPath` and `usePath` refer to the same SSA variable
exists(SsaDefinition def, StackVariable v | def.getAUse(v) = checkUse and def.getAUse(v) = opUse) and exists(SsaDefinition def, StackVariable v |
// opUse looks like an operation on a filename def.getAUse(v) = checkPath and def.getAUse(v) = usePath
fc = filenameOperation(opUse) and ) and
// the return value of check is used (possibly with one step of // `op` looks like an operation on a filename
// variable indirection) in a guard which controls fc use = filenameOperation(usePath) and
// the return value of `check` is used (possibly with one step of
// variable indirection) in a guard which controls `use`
exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) | exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) |
guard.controls(fc.(ControlFlowNode).getBasicBlock(), _) guard.controls(use.(ControlFlowNode).getBasicBlock(), _)
) )
select fc, select use,
"The $@ being operated upon was previously $@, but the underlying file may have been changed since then.", "The $@ being operated upon was previously $@, but the underlying file may have been changed since then.",
opUse, "filename", check, "checked" usePath, "filename", check, "checked"

View File

@@ -4,7 +4,7 @@
* @id cpp/unsafe-create-process-call * @id cpp/unsafe-create-process-call
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 7.8
* @precision medium * @precision medium
* @msrc.severity important * @msrc.severity important
* @tags security * @tags security

View File

@@ -5,8 +5,7 @@
* state, and reading the variable may result in undefined behavior. * state, and reading the variable may result in undefined behavior.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 6.9 * @security-severity 7.8
* @opaque-id SM02313
* @id cpp/conditionally-uninitialized-variable * @id cpp/conditionally-uninitialized-variable
* @tags security * @tags security
* external/cwe/cwe-457 * external/cwe/cwe-457

View File

@@ -4,7 +4,7 @@
* can cause buffer overflow conditions. * can cause buffer overflow conditions.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision medium * @precision medium
* @id cpp/suspicious-pointer-scaling * @id cpp/suspicious-pointer-scaling
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/incorrect-pointer-scaling-char * @id cpp/incorrect-pointer-scaling-char
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision low * @precision low
* @tags security * @tags security
* external/cwe/cwe-468 * external/cwe/cwe-468

View File

@@ -4,7 +4,7 @@
* can cause buffer overflow conditions. * can cause buffer overflow conditions.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision medium * @precision medium
* @id cpp/suspicious-pointer-scaling-void * @id cpp/suspicious-pointer-scaling-void
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* implicitly scaled. * implicitly scaled.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 8.8
* @precision high * @precision high
* @id cpp/suspicious-add-sizeof * @id cpp/suspicious-add-sizeof
* @tags security * @tags security

View File

@@ -5,7 +5,7 @@
* attack plan. * attack plan.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 3.6 * @security-severity 6.5
* @precision medium * @precision medium
* @id cpp/system-data-exposure * @id cpp/system-data-exposure
* @tags security * @tags security

View File

@@ -6,7 +6,7 @@
* @kind problem * @kind problem
* @id cpp/incorrect-string-type-conversion * @id cpp/incorrect-string-type-conversion
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 8.8
* @precision high * @precision high
* @tags security * @tags security
* external/cwe/cwe-704 * external/cwe/cwe-704

View File

@@ -3,7 +3,7 @@
* @description Creating a file that is world-writable can allow an attacker to write to the file. * @description Creating a file that is world-writable can allow an attacker to write to the file.
* @kind problem * @kind problem
* @problem.severity warning * @problem.severity warning
* @security-severity 5.9 * @security-severity 7.8
* @precision medium * @precision medium
* @id cpp/world-writable-file-creation * @id cpp/world-writable-file-creation
* @tags security * @tags security

View File

@@ -7,7 +7,7 @@
* @id cpp/unsafe-dacl-security-descriptor * @id cpp/unsafe-dacl-security-descriptor
* @kind problem * @kind problem
* @problem.severity error * @problem.severity error
* @security-severity 5.9 * @security-severity 7.8
* @precision high * @precision high
* @tags security * @tags security
* external/cwe/cwe-732 * external/cwe/cwe-732

View File

@@ -5,7 +5,7 @@
* @kind problem * @kind problem
* @id cpp/lock-order-cycle * @id cpp/lock-order-cycle
* @problem.severity error * @problem.severity error
* @security-severity 6.9 * @security-severity 5.0
* @tags security * @tags security
* external/cwe/cwe-764 * external/cwe/cwe-764
* external/cwe/cwe-833 * external/cwe/cwe-833

Some files were not shown because too many files have changed in this diff Show More