Skip to content

Commit b6d93ae

Browse files
committed
Merge remote-tracking branch 'upstream/rc/1.25' into merge-rc-1.25
2 parents c56d5eb + 83340e2 commit b6d93ae

File tree

22 files changed

+643
-301
lines changed

22 files changed

+643
-301
lines changed

Diff for: change-notes/1.25/analysis-java.md

+14-6
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@ The following changes in version 1.25 affect Java analysis in all applications.
44

55
## General improvements
66

7-
## New queries
8-
9-
| **Query** | **Tags** | **Purpose** |
10-
|-----------------------------|-----------|--------------------------------------------------------------------|
11-
7+
The Java autobuilder has been improved to detect more Gradle Java versions.
128

139
## Changes to existing queries
1410

1511
| **Query** | **Expected impact** | **Change** |
1612
|------------------------------|------------------------|-----------------------------------|
17-
13+
| Hard-coded credential in API call (`java/hardcoded-credential-api-call`) | More results | The query now recognizes the `BasicAWSCredentials` class of the Amazon client SDK library with hardcoded access key/secret key. |
14+
| Deserialization of user-controlled data (`java/unsafe-deserialization`) | Fewer false positive results | The query no longer reports results using `org.apache.commons.io.serialization.ValidatingObjectInputStream`. |
15+
| Use of a broken or risky cryptographic algorithm (`java/weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
16+
| Use of a potentially broken or risky cryptographic algorithm (`java/potentially-weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
17+
| Reading from a world writable file (`java/world-writable-file-read`) | More results | The query now recognizes more JDK file operations. |
1818

1919
## Changes to libraries
2020

21+
* The data-flow library has been improved with more taint flow modeling for the
22+
Collections framework and other classes of the JDK. This affects all security
23+
queries using data flow and can yield additional results.
24+
* The data-flow library has been improved with more taint flow modeling for the
25+
Spring framework. This affects all security queries using data flow and can
26+
yield additional results on project that rely on the Spring framework.
2127
* The data-flow library has been improved, which affects most security queries by potentially
2228
adding more results. Flow through methods now takes nested field reads/writes into account.
2329
For example, the library is able to track flow from `"taint"` to `sink()` via the method
@@ -39,3 +45,5 @@ The following changes in version 1.25 affect Java analysis in all applications.
3945
}
4046
}
4147
```
48+
* The library has been extended with more support for Java 14 features
49+
(`switch` expressions and pattern-matching for `instanceof`).

Diff for: change-notes/1.25/analysis-python.md

+6-19
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
# Improvements to Python analysis
22

3-
The following changes in version 1.25 affect Python analysis in all applications.
4-
5-
## General improvements
6-
7-
8-
## New queries
9-
10-
| **Query** | **Tags** | **Purpose** |
11-
|-----------------------------|-----------|--------------------------------------------------------------------|
12-
13-
14-
## Changes to existing queries
15-
16-
| **Query** | **Expected impact** | **Change** |
17-
|----------------------------|------------------------|------------------------------------------------------------------|
18-
19-
20-
## Changes to libraries
21-
223
* Importing `semmle.python.web.HttpRequest` will no longer import `UntrustedStringKind` transitively. `UntrustedStringKind` is the most commonly used non-abstract subclass of `ExternalStringKind`. If not imported (by one mean or another), taint-tracking queries that concern `ExternalStringKind` will not produce any results. Please ensure such queries contain an explicit import (`import semmle.python.security.strings.Untrusted`).
4+
* Added model of taint sources for HTTP servers using `http.server`.
5+
* Added taint modeling of routed parameters in Flask.
6+
* Improved modeling of built-in methods on strings for taint tracking.
7+
* Improved classification of test files.
8+
* New class `BoundMethodValue` represents a bound method during runtime.
9+
* The query `py/command-line-injection` now recognizes command execution with the `fabric` and `invoke` Python libraries.

Diff for: csharp/extractor/Semmle.Extraction.CIL/Context.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public Context(Extraction.Context cx, string assemblyPath, bool extractPdbs)
4343
namespaceFactory = new CachedFunction<StringHandle, Entities.Namespace>(n => CreateNamespace(mdReader.GetString(n)));
4444
namespaceDefinitionFactory = new CachedFunction<NamespaceDefinitionHandle, Entities.Namespace>(CreateNamespace);
4545
sourceFiles = new CachedFunction<PDB.ISourceFile, Entities.PdbSourceFile>(path => new Entities.PdbSourceFile(this, path));
46-
folders = new CachedFunction<string, Entities.Folder>(path => new Entities.Folder(this, path));
46+
folders = new CachedFunction<PathTransformer.ITransformedPath, Entities.Folder>(path => new Entities.Folder(this, path));
4747
sourceLocations = new CachedFunction<PDB.Location, Entities.PdbSourceLocation>(location => new Entities.PdbSourceLocation(this, location));
4848

4949
defaultGenericContext = new EmptyContext(this);

Diff for: csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using Semmle.Extraction.Entities;
77
using System.IO;
8+
using Semmle.Util;
89

910
namespace Semmle.Extraction.CIL.Entities
1011
{
@@ -134,9 +135,12 @@ public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger
134135
extracted = false;
135136
try
136137
{
137-
var extractor = new Extractor(false, assemblyPath, logger);
138-
var project = layout.LookupProjectOrDefault(assemblyPath);
139-
using (var trapWriter = project.CreateTrapWriter(logger, assemblyPath + ".cil", true, trapCompression))
138+
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
139+
var pathTransformer = new PathTransformer(canonicalPathCache);
140+
var extractor = new Extractor(false, assemblyPath, logger, pathTransformer);
141+
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
142+
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
143+
using (var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), true, trapCompression))
140144
{
141145
trapFile = trapWriter.TrapFile;
142146
if (nocache || !System.IO.File.Exists(trapFile))

Diff for: csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using System.IO;
33

44
namespace Semmle.Extraction.CIL.Entities
@@ -13,37 +13,38 @@ interface IFile : IFileOrFolder
1313

1414
public class File : LabelledEntity, IFile
1515
{
16-
protected readonly string path;
16+
protected readonly string OriginalPath;
17+
protected readonly PathTransformer.ITransformedPath TransformedPath;
1718

1819
public File(Context cx, string path) : base(cx)
1920
{
20-
this.path = Semmle.Extraction.Entities.File.PathAsDatabaseString(path);
21+
this.OriginalPath = path;
22+
TransformedPath = cx.cx.Extractor.PathTransformer.Transform(OriginalPath);
2123
}
2224

2325
public override void WriteId(TextWriter trapFile)
2426
{
25-
trapFile.Write(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));
27+
trapFile.Write(TransformedPath.DatabaseId);
2628
}
2729

2830
public override bool Equals(object? obj)
2931
{
30-
return GetType() == obj?.GetType() && path == ((File)obj).path;
32+
return GetType() == obj?.GetType() && OriginalPath == ((File)obj).OriginalPath;
3133
}
3234

33-
public override int GetHashCode() => 11 * path.GetHashCode();
35+
public override int GetHashCode() => 11 * OriginalPath.GetHashCode();
3436

3537
public override IEnumerable<IExtractionProduct> Contents
3638
{
3739
get
3840
{
39-
var directoryName = System.IO.Path.GetDirectoryName(path);
40-
if (directoryName is null)
41-
throw new InternalError($"Directory name for path '{path}' is null.");
42-
43-
var parent = cx.CreateFolder(directoryName);
44-
yield return parent;
45-
yield return Tuples.containerparent(parent, this);
46-
yield return Tuples.files(this, path, System.IO.Path.GetFileNameWithoutExtension(path), System.IO.Path.GetExtension(path).Substring(1));
41+
if (TransformedPath.ParentDirectory is PathTransformer.ITransformedPath dir)
42+
{
43+
var parent = cx.CreateFolder(dir);
44+
yield return parent;
45+
yield return Tuples.containerparent(parent, this);
46+
}
47+
yield return Tuples.files(this, TransformedPath.Value, TransformedPath.NameWithoutExtension, TransformedPath.Extension);
4748
}
4849
}
4950

@@ -69,9 +70,9 @@ public override IEnumerable<IExtractionProduct> Contents
6970
var text = file.Contents;
7071

7172
if (text == null)
72-
cx.cx.Extractor.Logger.Log(Util.Logging.Severity.Warning, string.Format("PDB source file {0} could not be found", path));
73+
cx.cx.Extractor.Logger.Log(Util.Logging.Severity.Warning, string.Format("PDB source file {0} could not be found", OriginalPath));
7374
else
74-
cx.cx.TrapWriter.Archive(path, text);
75+
cx.cx.TrapWriter.Archive(TransformedPath, text);
7576

7677
yield return Tuples.file_extraction_mode(this, 2);
7778
}

Diff for: csharp/extractor/Semmle.Extraction.CIL/Entities/Folder.cs

+8-12
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ interface IFolder : IFileOrFolder
99

1010
public sealed class Folder : LabelledEntity, IFolder
1111
{
12-
readonly string path;
12+
readonly PathTransformer.ITransformedPath TransformedPath;
1313

14-
public Folder(Context cx, string path) : base(cx)
14+
public Folder(Context cx, PathTransformer.ITransformedPath path) : base(cx)
1515
{
16-
this.path = path;
16+
this.TransformedPath = path;
1717
}
1818

1919
public override void WriteId(TextWriter trapFile)
2020
{
21-
trapFile.Write(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));
21+
trapFile.Write(TransformedPath.DatabaseId);
2222
}
2323

2424
public override string IdSuffix => ";folder";
@@ -27,25 +27,21 @@ public override IEnumerable<IExtractionProduct> Contents
2727
{
2828
get
2929
{
30-
// On Posix, we could get a Windows directory of the form "C:"
31-
bool windowsDriveLetter = path.Length == 2 && char.IsLetter(path[0]) && path[1] == ':';
32-
33-
var parent = Path.GetDirectoryName(path);
34-
if (parent != null && !windowsDriveLetter)
30+
if (TransformedPath.ParentDirectory is PathTransformer.ITransformedPath parent)
3531
{
3632
var parentFolder = cx.CreateFolder(parent);
3733
yield return parentFolder;
3834
yield return Tuples.containerparent(parentFolder, this);
3935
}
40-
yield return Tuples.folders(this, Semmle.Extraction.Entities.File.PathAsDatabaseString(path), Path.GetFileName(path));
36+
yield return Tuples.folders(this, TransformedPath.Value, TransformedPath.NameWithoutExtension);
4137
}
4238
}
4339

4440
public override bool Equals(object? obj)
4541
{
46-
return obj is Folder folder && path == folder.path;
42+
return obj is Folder folder && TransformedPath == folder.TransformedPath;
4743
}
4844

49-
public override int GetHashCode() => path.GetHashCode();
45+
public override int GetHashCode() => TransformedPath.GetHashCode();
5046
}
5147
}

Diff for: csharp/extractor/Semmle.Extraction.CIL/Factories.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ Namespace CreateNamespace(NamespaceDefinitionHandle handle)
201201

202202
#region Locations
203203
readonly CachedFunction<PDB.ISourceFile, PdbSourceFile> sourceFiles;
204-
readonly CachedFunction<string, Folder> folders;
204+
readonly CachedFunction<PathTransformer.ITransformedPath, Folder> folders;
205205
readonly CachedFunction<PDB.Location, PdbSourceLocation> sourceLocations;
206206

207207
/// <summary>
@@ -216,7 +216,7 @@ Namespace CreateNamespace(NamespaceDefinitionHandle handle)
216216
/// </summary>
217217
/// <param name="path">The path of the folder.</param>
218218
/// <returns>A folder entity.</returns>
219-
public Folder CreateFolder(string path) => folders[path];
219+
public Folder CreateFolder(PathTransformer.ITransformedPath path) => folders[path];
220220

221221
/// <summary>
222222
/// Creates a source location.

Diff for: csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs

+16-10
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ public class Analyser : IDisposable
2727

2828
public readonly bool AddAssemblyTrapPrefix;
2929

30-
public Analyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix)
30+
public readonly PathTransformer PathTransformer;
31+
32+
public Analyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix, PathTransformer pathTransformer)
3133
{
3234
Logger = logger;
3335
AddAssemblyTrapPrefix = addAssemblyTrapPrefix;
3436
Logger.Log(Severity.Info, "EXTRACTION STARTING at {0}", DateTime.Now);
3537
stopWatch.Start();
3638
progressMonitor = pm;
39+
PathTransformer = pathTransformer;
3740
}
3841

3942
CSharpCompilation compilation;
@@ -67,7 +70,7 @@ public void EndInitialize(
6770
layout = new Layout();
6871
this.options = options;
6972
this.compilation = compilation;
70-
extractor = new Extraction.Extractor(false, GetOutputName(compilation, commandLineArguments), Logger);
73+
extractor = new Extraction.Extractor(false, GetOutputName(compilation, commandLineArguments), Logger, PathTransformer);
7174
LogDiagnostics();
7275

7376
SetReferencePaths();
@@ -117,7 +120,7 @@ public void InitializeStandalone(CSharpCompilation compilationIn, CommonOptions
117120
{
118121
compilation = compilationIn;
119122
layout = new Layout();
120-
extractor = new Extraction.Extractor(true, null, Logger);
123+
extractor = new Extraction.Extractor(true, null, Logger, PathTransformer);
121124
this.options = options;
122125
LogExtractorInfo(Extraction.Extractor.Version);
123126
SetReferencePaths();
@@ -230,9 +233,10 @@ void DoAnalyseCompilation(string cwd, string[] args)
230233
try
231234
{
232235
var assemblyPath = extractor.OutputPath;
236+
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
233237
var assembly = compilation.Assembly;
234-
var projectLayout = layout.LookupProjectOrDefault(assemblyPath);
235-
var trapWriter = projectLayout.CreateTrapWriter(Logger, assemblyPath, true, options.TrapCompression);
238+
var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath);
239+
var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, true, options.TrapCompression);
236240
compilationTrapFile = trapWriter; // Dispose later
237241
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath, true), AddAssemblyTrapPrefix);
238242

@@ -260,8 +264,9 @@ void DoAnalyseAssembly(PortableExecutableReference r)
260264
stopwatch.Start();
261265

262266
var assemblyPath = r.FilePath;
263-
var projectLayout = layout.LookupProjectOrDefault(assemblyPath);
264-
using (var trapWriter = projectLayout.CreateTrapWriter(Logger, assemblyPath, true, options.TrapCompression))
267+
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
268+
var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath);
269+
using (var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, true, options.TrapCompression))
265270
{
266271
var skipExtraction = options.Cache && File.Exists(trapWriter.TrapFile);
267272

@@ -360,16 +365,17 @@ void DoExtractTree(SyntaxTree tree)
360365
var stopwatch = new Stopwatch();
361366
stopwatch.Start();
362367
var sourcePath = tree.FilePath;
368+
var transformedSourcePath = PathTransformer.Transform(sourcePath);
363369

364-
var projectLayout = layout.LookupProjectOrNull(sourcePath);
370+
var projectLayout = layout.LookupProjectOrNull(transformedSourcePath);
365371
bool excluded = projectLayout == null;
366-
string trapPath = excluded ? "" : projectLayout.GetTrapPath(Logger, sourcePath, options.TrapCompression);
372+
string trapPath = excluded ? "" : projectLayout.GetTrapPath(Logger, transformedSourcePath, options.TrapCompression);
367373
bool upToDate = false;
368374

369375
if (!excluded)
370376
{
371377
// compilation.Clone() is used to allow symbols to be garbage collected.
372-
using (var trapWriter = projectLayout.CreateTrapWriter(Logger, sourcePath, false, options.TrapCompression))
378+
using (var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedSourcePath, false, options.TrapCompression))
373379
{
374380
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
375381

Diff for: csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilation.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Linq;
6+
using Semmle.Util;
67

78
namespace Semmle.Extraction.CSharp.Entities
89
{
@@ -22,7 +23,7 @@ protected override void Populate(TextWriter trapFile)
2223
{
2324
Extraction.Entities.Assembly.CreateOutputAssembly(cx);
2425

25-
trapFile.compilations(this, Extraction.Entities.File.PathAsDatabaseString(cwd));
26+
trapFile.compilations(this, FileUtils.ConvertToUnix(cwd));
2627

2728
// Arguments
2829
int index = 0;

Diff for: csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs

+8-5
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ public static ExitCode Run(string[] args)
7676
return ExitCode.Ok;
7777
}
7878

79-
using (var analyser = new Analyser(new LogProgressMonitor(logger), logger, commandLineArguments.AssemblySensitiveTrap))
79+
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
80+
var pathTransformer = new PathTransformer(canonicalPathCache);
81+
82+
using (var analyser = new Analyser(new LogProgressMonitor(logger), logger, commandLineArguments.AssemblySensitiveTrap, pathTransformer))
8083
using (var references = new BlockingCollection<MetadataReference>())
8184
{
8285
try
8386
{
8487
var compilerVersion = new CompilerVersion(commandLineArguments);
8588

86-
bool preserveSymlinks = Environment.GetEnvironmentVariable("SEMMLE_PRESERVE_SYMLINKS") == "true";
87-
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000, preserveSymlinks ? CanonicalPathCache.Symlinks.Preserve : CanonicalPathCache.Symlinks.Follow);
88-
8989
if (compilerVersion.SkipExtraction)
9090
{
9191
logger.Log(Severity.Warning, " Unrecognized compiler '{0}' because {1}", compilerVersion.SpecifiedCompiler, compilerVersion.SkipReason);
@@ -318,7 +318,10 @@ public static void ExtractStandalone(
318318
ILogger logger,
319319
CommonOptions options)
320320
{
321-
using (var analyser = new Analyser(pm, logger, false))
321+
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
322+
var pathTransformer = new PathTransformer(canonicalPathCache);
323+
324+
using (var analyser = new Analyser(pm, logger, false, pathTransformer))
322325
using (var references = new BlockingCollection<MetadataReference>())
323326
{
324327
try

0 commit comments

Comments
 (0)