mirror of
https://github.com/github/codeql.git
synced 2026-07-01 01:25:33 +02:00
Compare commits
7 Commits
copilot/up
...
unified/dc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58bb4c2f4d | ||
|
|
7ee7d670e2 | ||
|
|
0891d91df7 | ||
|
|
2b2613de4e | ||
|
|
cacdc467de | ||
|
|
d1d9df7729 | ||
|
|
9bffcf81b5 |
@@ -3,13 +3,13 @@ class C
|
||||
void Problems()
|
||||
{
|
||||
// correct expectation comment, but only for `problem-query`
|
||||
var x = "Alert"; // $ Alert[problem-query]
|
||||
var x = "Alert"; // $ Alert
|
||||
|
||||
// irrelevant expectation comment, will be ignored
|
||||
x = "Not an alert"; // $ IrrelevantTag
|
||||
|
||||
// incorrect expectation comment
|
||||
x = "Also not an alert"; // $ MISSING: Alert[problem-query]
|
||||
x = "Also not an alert"; // $ Alert
|
||||
|
||||
// missing expectation comment, but only for `problem-query`
|
||||
x = "Alert";
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
| InlineTests.cs:88:13:88:23 | "Alert:0:1" | InlineTests.cs:88:13:88:23 | "Alert:0:1" | InlineTests.cs:87:16:87:21 | "Sink" | This is a problem |
|
||||
edges
|
||||
testFailures
|
||||
| InlineTests.cs:6:26:6:35 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:37:28:37:38 | // ... | Missing result: Source |
|
||||
| InlineTests.cs:38:24:38:32 | // ... | Missing result: Sink |
|
||||
| InlineTests.cs:39:33:39:42 | // ... | Missing result: Alert |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
| InlineTests.cs:100:13:100:25 | "Alert:3:2:1" | InlineTests.cs:97:18:97:25 | "Source" | InlineTests.cs:98:16:98:21 | "Sink" | This is a problem with $@ | InlineTests.cs:99:19:99:27 | "Related" | a related location |
|
||||
edges
|
||||
testFailures
|
||||
| InlineTests.cs:6:26:6:35 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:32:32:32:42 | // ... | Missing result: Source |
|
||||
| InlineTests.cs:33:28:33:36 | // ... | Missing result: Sink |
|
||||
| InlineTests.cs:34:30:34:39 | // ... | Missing result: Alert |
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
| InlineTests.cs:15:13:15:19 | "Alert" | This is a problem |
|
||||
| InlineTests.cs:18:13:18:19 | "Alert" | This is a problem |
|
||||
testFailures
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:15:13:15:19 | This is a problem | Unexpected result: Alert |
|
||||
| InlineTests.cs:34:30:34:39 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:39:33:39:42 | // ... | Missing result: Alert |
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
| InlineTests.cs:22:13:22:21 | "Alert:1" | This is a problem with $@ | InlineTests.cs:21:23:21:31 | "Related" | a related location |
|
||||
| InlineTests.cs:26:13:26:21 | "Alert:1" | This is a problem with $@ | InlineTests.cs:25:19:25:27 | "Related" | a related location |
|
||||
testFailures
|
||||
| InlineTests.cs:6:26:6:35 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:25:19:25:27 | "Related" | Unexpected result: RelatedLocation |
|
||||
| InlineTests.cs:34:30:34:39 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:39:33:39:42 | // ... | Missing result: Alert |
|
||||
|
||||
@@ -30,5 +30,7 @@ nodes
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
|
||||
subpaths
|
||||
testFailures
|
||||
| BadMacUse.java:50:56:50:66 | // $ Source | Missing result: Source |
|
||||
| BadMacUse.java:63:118:63:128 | // $ Source | Missing result: Source |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |
|
||||
|
||||
@@ -31,7 +31,7 @@ nodes
|
||||
| BadMacUse.java:124:42:124:51 | ciphertext | semmle.label | ciphertext |
|
||||
subpaths
|
||||
testFailures
|
||||
| BadMacUse.java:50:28:50:53 | doFinal(...) : byte[] | Fixed missing result: Source |
|
||||
| BadMacUse.java:63:118:63:128 | // $ Source | Missing result: Source |
|
||||
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:124:42:124:51 | ciphertext | Unexpected result: Alert |
|
||||
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |
|
||||
|
||||
@@ -45,7 +45,7 @@ nodes
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
|
||||
subpaths
|
||||
testFailures
|
||||
| BadMacUse.java:63:82:63:97 | plaintext : byte[] | Fixed missing result: Source |
|
||||
| BadMacUse.java:50:56:50:66 | // $ Source | Missing result: Source |
|
||||
| BadMacUse.java:139:79:139:90 | input : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | Unexpected result: Alert |
|
||||
|
||||
@@ -47,7 +47,7 @@ class BadMacUse {
|
||||
SecretKey encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new SecureRandom());
|
||||
byte[] plaintext = cipher.doFinal(ciphertext); // $ MISSING: Source
|
||||
byte[] plaintext = cipher.doFinal(ciphertext); // $ Source
|
||||
|
||||
// Now verify MAC (too late)
|
||||
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
|
||||
@@ -60,7 +60,7 @@ class BadMacUse {
|
||||
}
|
||||
}
|
||||
|
||||
public void BadMacOnPlaintext(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] plaintext) throws Exception {// $ MISSING: Source
|
||||
public void BadMacOnPlaintext(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] plaintext) throws Exception {// $ Source
|
||||
// Create keys directly from provided byte arrays
|
||||
SecretKey encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
|
||||
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
|
||||
|
||||
@@ -126,3 +126,5 @@ nodes
|
||||
| InsecureIVorNonceSource.java:202:54:202:55 | iv : byte[] | semmle.label | iv : byte[] |
|
||||
| InsecureIVorNonceSource.java:206:51:206:56 | ivSpec | semmle.label | ivSpec |
|
||||
subpaths
|
||||
testFailures
|
||||
| InsecureIVorNonceSource.java:42:21:42:21 | 1 : Number | Unexpected result: Source |
|
||||
|
||||
@@ -39,7 +39,7 @@ public class InsecureIVorNonceSource {
|
||||
public byte[] encryptWithStaticIvByteArray(byte[] key, byte[] plaintext) throws Exception {
|
||||
byte[] iv = new byte[16];
|
||||
for (byte i = 0; i < iv.length; i++) {
|
||||
iv[i] = 1; // $ Source
|
||||
iv[i] = 1;
|
||||
}
|
||||
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
|
||||
@@ -40,11 +40,11 @@ public class Test {
|
||||
* SAST/CBOM: - Parent: PBKDF2. - Iteration count is only 10, which is far
|
||||
* below acceptable security standards. - Flagged as insecure.
|
||||
*/
|
||||
public void pbkdf2LowIteration(String password, int iterationCount) throws Exception { // $ MISSING: Source
|
||||
public void pbkdf2LowIteration(String password, int iterationCount) throws Exception { // $ Source
|
||||
byte[] salt = generateSalt(16);
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256);
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256); // $ Alert[java/quantum/examples/unknown-kdf-iteration-count]
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
byte[] key = factory.generateSecret(spec).getEncoded(); // $ Alert[java/quantum/examples/unknown-kdf-iteration-count]
|
||||
byte[] key = factory.generateSecret(spec).getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
#select
|
||||
| Test.java:47:22:47:49 | KeyDerivation | Key derivation operation with unknown iteration: $@ | Test.java:43:53:43:70 | iterationCount | iterationCount |
|
||||
testFailures
|
||||
| Test.java:45:94:45:154 | // $ Alert[java/quantum/examples/unknown-kdf-iteration-count] | Missing result: Alert[java/quantum/examples/unknown-kdf-iteration-count] |
|
||||
| Test.java:47:22:47:49 | Key derivation operation with unknown iteration: $@ | Unexpected result: Alert |
|
||||
|
||||
@@ -12,3 +12,5 @@ nodes
|
||||
| Test.java:58:30:58:38 | 1_000_000 : Number | semmle.label | 1_000_000 : Number |
|
||||
| Test.java:59:72:59:85 | iterationCount | semmle.label | iterationCount |
|
||||
subpaths
|
||||
testFailures
|
||||
| Test.java:43:92:43:102 | // $ Source | Missing result: Source |
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for Angular's `@HostListener('window:message', ...)` and `@HostListener('document:message', ...)` decorators as `postMessage` event handlers. The decorated method's event parameter is now recognized as a client-side remote flow source, and is considered by the `js/missing-origin-check` query.
|
||||
@@ -195,6 +195,18 @@ class PostMessageEventHandler extends Function {
|
||||
rhs = DataFlow::globalObjectRef().getAPropertyWrite("onmessage").getRhs() and
|
||||
rhs.getABoundFunctionValue(paramIndex).getFunction() = this
|
||||
)
|
||||
or
|
||||
// Angular's `@HostListener('window:message', ['$event'])` decorator registers
|
||||
// a method as a `message` event handler on the global `window` or `document`
|
||||
// target. The decorated method receives the `MessageEvent` as its first
|
||||
// parameter, so it is equivalent to `window.addEventListener('message', ...)`.
|
||||
exists(MethodDefinition method, DataFlow::CallNode decorator |
|
||||
decorator = DataFlow::moduleMember("@angular/core", "HostListener").getACall() and
|
||||
decorator = method.getADecorator().getExpression().flow() and
|
||||
decorator.getArgument(0).mayHaveStringValue(["window:message", "document:message"]) and
|
||||
method.getBody() = this and
|
||||
paramIndex = 0
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Component, HostListener } from '@angular/core';
|
||||
|
||||
@Component({ selector: 'app-root' })
|
||||
class AngularComponent {
|
||||
// Angular registers this as a `window` message handler via the decorator,
|
||||
// equivalent to `window.addEventListener('message', ...)`.
|
||||
@HostListener('window:message', ['$event'])
|
||||
onWindowMessage(event: MessageEvent): void { // $ Alert - no origin check
|
||||
eval(event.data);
|
||||
}
|
||||
|
||||
@HostListener('document:message', ['$event'])
|
||||
onDocumentMessage(event: MessageEvent): void { // $ Alert - no origin check
|
||||
eval(event.data);
|
||||
}
|
||||
|
||||
@HostListener('window:message', ['$event'])
|
||||
onCheckedMessage(event: MessageEvent): void { // OK - has an origin check
|
||||
if (event.origin === 'https://www.example.com') {
|
||||
eval(event.data);
|
||||
}
|
||||
}
|
||||
|
||||
// Not a message event, so it is not a postMessage handler.
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: MessageEvent): void { // OK - not a message handler
|
||||
eval(event.data);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
| Angular.ts:8:19:8:23 | event | Postmessage handler has no origin check. |
|
||||
| Angular.ts:13:21:13:25 | event | Postmessage handler has no origin check. |
|
||||
| tst.js:11:20:11:24 | event | Postmessage handler has no origin check. |
|
||||
| tst.js:24:27:24:27 | e | Postmessage handler has no origin check. |
|
||||
| tst.js:40:27:40:27 | e | Postmessage handler has no origin check. |
|
||||
|
||||
@@ -3,5 +3,5 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious
|
||||
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
|
||||
| taint_test.py:32:9:32:25 | taint_test.py:32 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
|
||||
| taint_test.py:37:24:37:40 | taint_test.py:37 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
|
||||
| taint_test.py:41:24:41:40 | taint_test.py:41 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
|
||||
testFailures
|
||||
| taint_test.py:41:20:41:21 | ts | Fixed missing result: tainted |
|
||||
|
||||
@@ -38,7 +38,7 @@ def bad_usage():
|
||||
|
||||
# if you try to get around it by adding BOTH annotations, that results in a problem
|
||||
# from the default set of inline-test-expectation rules
|
||||
ensure_tainted(ts, should_be_tainted) # $ tainted
|
||||
ensure_tainted(ts, should_be_tainted) # $ tainted MISSING: tainted
|
||||
|
||||
# simulating handling something we _want_ to treat at untainted, but we currently treat as tainted
|
||||
should_not_be_tainted = "pretend this is now safe" + ts
|
||||
|
||||
@@ -28,6 +28,7 @@ nodes
|
||||
| string_flow.rb:227:10:227:10 | a | semmle.label | a |
|
||||
subpaths
|
||||
testFailures
|
||||
| string_flow.rb:85:10:85:10 | a | Unexpected result: hasValueFlow=a |
|
||||
| string_flow.rb:227:10:227:10 | a | Unexpected result: hasValueFlow=a |
|
||||
#select
|
||||
| string_flow.rb:3:10:3:22 | call to new | string_flow.rb:2:9:2:18 | call to source | string_flow.rb:3:10:3:22 | call to new | $@ | string_flow.rb:2:9:2:18 | call to source | call to source |
|
||||
|
||||
@@ -82,7 +82,7 @@ end
|
||||
def m_clear
|
||||
a = source "a"
|
||||
a.clear
|
||||
sink a # $ hasValueFlow=a
|
||||
sink a
|
||||
end
|
||||
|
||||
# concat and prepend omitted because they clash with the summaries for
|
||||
|
||||
@@ -18,7 +18,7 @@ class OneController < ActionController::Base
|
||||
end
|
||||
|
||||
def c
|
||||
sink @foo # $ hasTaintFlow
|
||||
sink @foo
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -270,6 +270,7 @@ nodes
|
||||
| params_flow.rb:205:10:205:10 | a | semmle.label | a |
|
||||
subpaths
|
||||
testFailures
|
||||
| filter_flow.rb:21:10:21:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:38:10:38:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:55:10:55:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:71:10:71:17 | call to bar | Unexpected result: hasTaintFlow |
|
||||
|
||||
@@ -497,6 +497,7 @@ nodes
|
||||
| hash_extensions.rb:126:10:126:19 | call to sole | semmle.label | call to sole |
|
||||
subpaths
|
||||
testFailures
|
||||
| hash_extensions.rb:126:10:126:19 | call to sole | Unexpected result: hasValueFlow=b |
|
||||
#select
|
||||
| active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source | call to source |
|
||||
| active_support.rb:188:10:188:13 | ...[...] | active_support.rb:186:10:186:18 | call to source | active_support.rb:188:10:188:13 | ...[...] | $@ | active_support.rb:186:10:186:18 | call to source | call to source |
|
||||
|
||||
@@ -123,7 +123,7 @@ def m_sole
|
||||
multi = [source("b"), source("c")]
|
||||
sink(empty.sole)
|
||||
sink(single.sole) # $ hasValueFlow=a
|
||||
sink(multi.sole) # $ hasValueFlow=b # TODO: model that 'sole' does not return if the receiver has multiple elements
|
||||
sink(multi.sole) # TODO: model that 'sole' does not return if the receiver has multiple elements
|
||||
end
|
||||
|
||||
m_sole()
|
||||
|
||||
@@ -23,6 +23,7 @@ nodes
|
||||
| views/index.erb:2:10:2:12 | call to foo | semmle.label | call to foo |
|
||||
subpaths
|
||||
testFailures
|
||||
| views/index.erb:2:10:2:12 | call to foo | Unexpected result: hasTaintFlow |
|
||||
#select
|
||||
| app.rb:95:10:95:14 | @user | app.rb:103:13:103:22 | call to source | app.rb:95:10:95:14 | @user | $@ | app.rb:103:13:103:22 | call to source | call to source |
|
||||
| views/index.erb:2:10:2:12 | call to foo | app.rb:75:12:75:17 | call to params | views/index.erb:2:10:2:12 | call to foo | $@ | app.rb:75:12:75:17 | call to params | call to params |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
<%= @foo %>
|
||||
<%= sink foo # $ hasTaintFlow %>
|
||||
<%= sink foo %>
|
||||
@@ -1,4 +1,5 @@
|
||||
testFailures
|
||||
| improper_memoization.rb:100:1:104:3 | m14 | Unexpected result: result=BAD |
|
||||
#select
|
||||
| improper_memoization.rb:50:1:55:3 | m7 | improper_memoization.rb:50:8:50:10 | arg | improper_memoization.rb:51:3:53:5 | ... \|\|= ... |
|
||||
| improper_memoization.rb:58:1:63:3 | m8 | improper_memoization.rb:58:8:58:10 | arg | improper_memoization.rb:59:3:61:5 | ... \|\|= ... |
|
||||
|
||||
@@ -101,4 +101,4 @@ def m14(arg)
|
||||
@m14 ||= {}
|
||||
key = "foo/#{arg}"
|
||||
@m14[key] ||= long_running_method(arg)
|
||||
end # $ SPURIOUS: result=BAD
|
||||
end
|
||||
|
||||
@@ -5,6 +5,8 @@ column_kind: "utf8"
|
||||
legacy_qltest_extraction: true
|
||||
build_modes:
|
||||
- none
|
||||
default_queries:
|
||||
- codeql/unified-queries
|
||||
github_api_languages:
|
||||
- Swift
|
||||
scc_languages:
|
||||
|
||||
@@ -7,6 +7,7 @@ codeql_rust_binary(
|
||||
name = "extractor",
|
||||
srcs = glob(["src/**/*.rs"]),
|
||||
aliases = aliases(),
|
||||
compile_data = ["ast_types.yml"],
|
||||
proc_macro_deps = all_crate_deps(
|
||||
proc_macro = True,
|
||||
),
|
||||
|
||||
@@ -16,7 +16,9 @@ fn main() {
|
||||
Some(&grammar_js),
|
||||
tree_sitter_generate::ABI_VERSION_MAX,
|
||||
None,
|
||||
None,
|
||||
// Evaluate grammar.js with the embedded QuickJS runtime instead of
|
||||
// spawning `node`, which isn't available inside Bazel's sandbox.
|
||||
Some("native"),
|
||||
true,
|
||||
tree_sitter_generate::OptLevel::default(),
|
||||
)
|
||||
|
||||
14
unified/ql/src/DummyQuery.ql
Normal file
14
unified/ql/src/DummyQuery.ql
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @name Dummy query
|
||||
* @description Dummy query that flags any name longer than 20 characters
|
||||
* @kind problem
|
||||
* @id unified/dummy
|
||||
* @problem.severity info
|
||||
* @precision low
|
||||
*/
|
||||
|
||||
import unified
|
||||
|
||||
from Identifier id
|
||||
where id.getValue().length() > 20
|
||||
select id, "Name is too long: " + id.getValue()
|
||||
@@ -0,0 +1,3 @@
|
||||
- queries: .
|
||||
- apply: code-quality-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
3
unified/ql/src/codeql-suites/unified-code-quality.qls
Normal file
3
unified/ql/src/codeql-suites/unified-code-quality.qls
Normal file
@@ -0,0 +1,3 @@
|
||||
- queries: .
|
||||
- apply: code-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
4
unified/ql/src/codeql-suites/unified-code-scanning.qls
Normal file
4
unified/ql/src/codeql-suites/unified-code-scanning.qls
Normal file
@@ -0,0 +1,4 @@
|
||||
- description: Standard Code Scanning queries
|
||||
- queries: .
|
||||
- apply: code-scanning-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
@@ -0,0 +1,3 @@
|
||||
- queries: .
|
||||
- apply: security-and-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
@@ -0,0 +1,4 @@
|
||||
- description: Extended and experimental security queries
|
||||
- queries: .
|
||||
- apply: security-experimental-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
@@ -0,0 +1,4 @@
|
||||
- description: Security-extended queries
|
||||
- queries: .
|
||||
- apply: security-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
Reference in New Issue
Block a user