Skip to content

Commit cd46f31

Browse files
authored
Merge branch 'main' into py/CsvInjection
2 parents a726340 + 7a6646d commit cd46f31

File tree

351 files changed

+10812
-5328
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

351 files changed

+10812
-5328
lines changed

.github/workflows/js-ml-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ on:
1212
paths:
1313
- "javascript/ql/experimental/adaptivethreatmodeling/**"
1414
- .github/workflows/js-ml-tests.yml
15+
workflow_dispatch:
1516

1617
defaults:
1718
run:

config/identical-files.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,8 @@
525525
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll",
526526
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
527527
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
528-
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll"
528+
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
529+
"python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll"
529530
],
530531
"IncompleteUrlSubstringSanitization": [
531532
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
@@ -543,7 +544,8 @@
543544
],
544545
"ApiGraphModels": [
545546
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
546-
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll"
547+
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
548+
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll"
547549
],
548550
"TaintedFormatStringQuery Ruby/JS": [
549551
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",

cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@
1717
import cpp
1818
import semmle.code.cpp.dataflow.DataFlow
1919

20+
/**
21+
* A Linux system call.
22+
*/
23+
class SystemCallFunction extends Function {
24+
SystemCallFunction() {
25+
exists(MacroInvocation m |
26+
m.getMacro().getName().matches("SYSCALL\\_DEFINE%") and
27+
this = m.getEnclosingFunction()
28+
)
29+
}
30+
}
31+
32+
/**
33+
* A value that comes from a Linux system call (sources).
34+
*/
35+
class SystemCallSource extends DataFlow::Node {
36+
SystemCallSource() {
37+
exists(FunctionCall fc |
38+
fc.getTarget() instanceof SystemCallFunction and
39+
(
40+
this.asDefiningArgument() = fc.getAnArgument().getAChild*() or
41+
this.asExpr() = fc
42+
)
43+
)
44+
}
45+
}
46+
47+
/**
48+
* Macros used to check the value (barriers).
49+
*/
2050
class WriteAccessCheckMacro extends Macro {
2151
VariableAccess va;
2252

@@ -28,6 +58,9 @@ class WriteAccessCheckMacro extends Macro {
2858
VariableAccess getArgument() { result = va }
2959
}
3060

61+
/**
62+
* The `unsafe_put_user` macro and its uses (sinks).
63+
*/
3164
class UnSafePutUserMacro extends Macro {
3265
PointerDereferenceExpr writeUserPtr;
3366

@@ -42,15 +75,13 @@ class UnSafePutUserMacro extends Macro {
4275
}
4376
}
4477

45-
class ExploitableUserModePtrParam extends Parameter {
78+
class ExploitableUserModePtrParam extends SystemCallSource {
4679
ExploitableUserModePtrParam() {
47-
not exists(WriteAccessCheckMacro writeAccessCheck |
48-
DataFlow::localFlow(DataFlow::parameterNode(this),
49-
DataFlow::exprNode(writeAccessCheck.getArgument()))
50-
) and
5180
exists(UnSafePutUserMacro unsafePutUser |
52-
DataFlow::localFlow(DataFlow::parameterNode(this),
53-
DataFlow::exprNode(unsafePutUser.getUserModePtr()))
81+
DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr()))
82+
) and
83+
not exists(WriteAccessCheckMacro writeAccessCheck |
84+
DataFlow::localFlow(this, DataFlow::exprNode(writeAccessCheck.getArgument()))
5485
)
5586
}
5687
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
| test.cpp:14:16:14:16 | p | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:14:16:14:16 | p | p |
1+
| test.cpp:20:21:20:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:20:21:20:22 | ref arg & ... | ref arg & ... |
2+
| test.cpp:41:21:41:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:41:21:41:22 | ref arg & ... | ref arg & ... |
3+
| test.cpp:69:21:69:27 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:69:21:69:27 | ref arg & ... | ref arg & ... |

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11

22
typedef unsigned long size_t;
33

4-
void SYSC_SOMESYSTEMCALL(void *param);
4+
#define SYSCALL_DEFINE(name, ...) \
5+
void do_sys_##name(); \
6+
void sys_##name(...) { do_sys_##name(); } \
7+
void do_sys_##name()
8+
SYSCALL_DEFINE(somesystemcall, void *param) {};
59

610
bool user_access_begin_impl(const void *where, size_t sz);
711
void user_access_end_impl();
@@ -13,14 +17,14 @@ void unsafe_put_user_impl(int what, const void *where, size_t sz);
1317

1418
void test1(int p)
1519
{
16-
SYSC_SOMESYSTEMCALL(&p);
20+
sys_somesystemcall(&p);
1721

1822
unsafe_put_user(123, &p); // BAD
1923
}
2024

2125
void test2(int p)
2226
{
23-
SYSC_SOMESYSTEMCALL(&p);
27+
sys_somesystemcall(&p);
2428

2529
if (user_access_begin(&p, sizeof(p)))
2630
{
@@ -34,16 +38,16 @@ void test3()
3438
{
3539
int v;
3640

37-
SYSC_SOMESYSTEMCALL(&v);
41+
sys_somesystemcall(&v);
3842

39-
unsafe_put_user(123, &v); // BAD [NOT DETECTED]
43+
unsafe_put_user(123, &v); // BAD
4044
}
4145

4246
void test4()
4347
{
4448
int v;
4549

46-
SYSC_SOMESYSTEMCALL(&v);
50+
sys_somesystemcall(&v);
4751

4852
if (user_access_begin(&v, sizeof(v)))
4953
{
@@ -62,16 +66,16 @@ void test5()
6266
{
6367
data myData;
6468

65-
SYSC_SOMESYSTEMCALL(&myData);
69+
sys_somesystemcall(&myData);
6670

67-
unsafe_put_user(123, &(myData.x)); // BAD [NOT DETECTED]
71+
unsafe_put_user(123, &(myData.x)); // BAD
6872
}
6973

7074
void test6()
7175
{
7276
data myData;
7377

74-
SYSC_SOMESYSTEMCALL(&myData);
78+
sys_somesystemcall(&myData);
7579

7680
if (user_access_begin(&myData, sizeof(myData)))
7781
{
Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint,summary:value
22
Dapper,55,,,,,,55,,,,
3+
JsonToItemsTaskFactory,,,7,,,,,,,7,
34
Microsoft.ApplicationBlocks.Data,28,,,,,,28,,,,
5+
Microsoft.CSharp,,,24,,,,,,,24,
46
Microsoft.EntityFrameworkCore,6,,,,,,6,,,,
5-
Microsoft.Extensions.Primitives,,,54,,,,,,,54,
6-
Microsoft.VisualBasic,,,4,,,,,,,,4
7+
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,15,
8+
Microsoft.Extensions.Caching.Memory,,,46,,,,,,,45,1
9+
Microsoft.Extensions.Configuration,,,83,,,,,,,80,3
10+
Microsoft.Extensions.DependencyInjection,,,62,,,,,,,62,
11+
Microsoft.Extensions.DependencyModel,,,12,,,,,,,12,
12+
Microsoft.Extensions.FileProviders,,,15,,,,,,,15,
13+
Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,13,2
14+
Microsoft.Extensions.Hosting,,,17,,,,,,,16,1
15+
Microsoft.Extensions.Http,,,10,,,,,,,10,
16+
Microsoft.Extensions.Logging,,,37,,,,,,,37,
17+
Microsoft.Extensions.Options,,,8,,,,,,,8,
18+
Microsoft.Extensions.Primitives,,,63,,,,,,,63,
19+
Microsoft.Interop,,,27,,,,,,,27,
20+
Microsoft.NET.Build.Tasks,,,1,,,,,,,1,
21+
Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,4,
22+
Microsoft.VisualBasic,,,9,,,,,,,5,4
23+
Microsoft.Win32,,,8,,,,,,,8,
724
MySql.Data.MySqlClient,48,,,,,,48,,,,
825
Newtonsoft.Json,,,91,,,,,,,73,18
926
ServiceStack,194,,7,27,,75,92,,,7,
10-
System,28,3,2336,,4,,23,1,3,611,1725
27+
System,28,3,12038,,4,,23,1,3,10096,1942

csharp/documentation/library-coverage/coverage.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ C# framework & library support
88

99
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
1010
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
11-
System,"``System.*``, ``System``",3,2336,28,5
12-
Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Primitives``, ``Microsoft.VisualBasic``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``",,149,137,
13-
Totals,,3,2492,359,5
11+
System,"``System.*``, ``System``",3,12038,28,5
12+
Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``",,554,137,
13+
Totals,,3,12599,359,5
1414

docs/codeql/codeql-cli/creating-codeql-databases.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ commands that you can specify for compiled languages.
226226

227227
- Java project built using Gradle::
228228

229-
codeql database create java-database --language=java --command='gradle clean test'
229+
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL:
230+
codeql database create java-database --language=java --command='gradle --no-daemon clean test'
230231

231232
- Java project built using Maven::
232233

docs/codeql/support/reusables/versions-compilers.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
Java,"Java 7 to 18 [4]_","javac (OpenJDK and Oracle JDK),
2121

2222
Eclipse compiler for Java (ECJ) [5]_",``.java``
23-
JavaScript,ECMAScript 2021 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [6]_"
23+
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [6]_"
2424
Python,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10",Not applicable,``.py``
2525
Ruby [7]_,"up to 3.0.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
26-
TypeScript [8]_,"2.6-4.6",Standard TypeScript compiler,"``.ts``, ``.tsx``"
26+
TypeScript [8]_,"2.6-4.7",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
2727

2828
.. container:: footnote-group
2929

java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
import java.io.File;
55
import java.io.IOException;
66
import java.util.Arrays;
7+
import java.util.Enumeration;
8+
import java.util.HashMap;
79
import java.util.LinkedHashMap;
810
import java.util.Map;
911
import java.util.Objects;
1012
import java.util.regex.Pattern;
13+
import java.util.zip.ZipEntry;
14+
import java.util.zip.ZipFile;
1115

1216
import com.github.codeql.Logger;
1317
import static com.github.codeql.ClassNamesKt.getIrDeclBinaryName;
@@ -547,6 +551,51 @@ else if (majorVersion==0)
547551
(tcv.majorVersion == majorVersion && tcv.minorVersion == minorVersion &&
548552
tcv.lastModified < lastModified);
549553
}
554+
555+
private static Map<String, Map<String, Long>> jarFileEntryTimeStamps = new HashMap<>();
556+
557+
private static Map<String, Long> getZipFileEntryTimeStamps(String path, Logger log) {
558+
try {
559+
Map<String, Long> result = new HashMap<>();
560+
ZipFile zf = new ZipFile(path);
561+
Enumeration<? extends ZipEntry> entries = zf.entries();
562+
while (entries.hasMoreElements()) {
563+
ZipEntry ze = entries.nextElement();
564+
result.put(ze.getName(), ze.getLastModifiedTime().toMillis());
565+
}
566+
return result;
567+
} catch(IOException e) {
568+
log.warn("Failed to get entry timestamps from " + path, e);
569+
return null;
570+
}
571+
}
572+
573+
private static long getVirtualFileTimeStamp(VirtualFile vf, Logger log) {
574+
if (vf.getFileSystem().getProtocol().equals("jar")) {
575+
String[] parts = vf.getPath().split("!/");
576+
if (parts.length == 2) {
577+
String jarFilePath = parts[0];
578+
String entryPath = parts[1];
579+
if (!jarFileEntryTimeStamps.containsKey(jarFilePath)) {
580+
jarFileEntryTimeStamps.put(jarFilePath, getZipFileEntryTimeStamps(jarFilePath, log));
581+
}
582+
Map<String, Long> entryTimeStamps = jarFileEntryTimeStamps.get(jarFilePath);
583+
if (entryTimeStamps != null) {
584+
Long entryTimeStamp = entryTimeStamps.get(entryPath);
585+
if (entryTimeStamp != null)
586+
return entryTimeStamp;
587+
else
588+
log.warn("Couldn't find timestamp for jar file " + jarFilePath + " entry " + entryPath);
589+
}
590+
} else {
591+
log.warn("Expected JAR-file path " + vf.getPath() + " to have exactly one '!/' separator");
592+
}
593+
}
594+
595+
// For all files except for jar files, and a fallback in case of I/O problems reading a jar file:
596+
return vf.getTimeStamp();
597+
}
598+
550599
private static TrapClassVersion fromSymbol(IrDeclaration sym, Logger log) {
551600
VirtualFile vf = sym instanceof IrClass ? getIrClassVirtualFile((IrClass)sym) :
552601
sym.getParent() instanceof IrClass ? getIrClassVirtualFile((IrClass)sym.getParent()) :
@@ -583,7 +632,7 @@ public void visit(int version, int access, java.lang.String name, java.lang.Stri
583632
};
584633
(new ClassReader(vf.contentsToByteArray())).accept(versionGetter, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
585634

586-
return new TrapClassVersion(versionStore[0] & 0xffff, versionStore[0] >> 16, vf.getTimeStamp(), "kotlin");
635+
return new TrapClassVersion(versionStore[0] & 0xffff, versionStore[0] >> 16, getVirtualFileTimeStamp(vf, log), "kotlin");
587636
}
588637
catch(IllegalAccessException e) {
589638
log.warn("Failed to read class file version information", e);

0 commit comments

Comments
 (0)