From 210d8529b6f022f2452c34f6768e80e28154a8d5 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 29 Nov 2022 19:09:29 -0500 Subject: [PATCH 1/8] add query for SupportedExternalApis --- .../ql/src/Telemetry/SupportedExternalApis.ql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 java/ql/src/Telemetry/SupportedExternalApis.ql diff --git a/java/ql/src/Telemetry/SupportedExternalApis.ql b/java/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..2e1baebd60f --- /dev/null +++ b/java/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,24 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes test and generated code. + * @kind metric + * @tags summary telemetry + * @id java/telemetry/supported-external-api + */ + +import java +import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +import semmle.code.java.dataflow.internal.NegativeSummary +import ExternalApi + +private predicate relevant(ExternalApi api) { + not api.isUninteresting() and + ( + api.isSupported() or + api = any(FlowSummaryImpl::Public::NegativeSummarizedCallable nsc).asCallable() + ) +} + +from string apiName, int usages +where Results::restrict(apiName, usages) +select apiName, usages order by usages desc From 7f45e320d88eb8f92307490dccd9310937881496 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 29 Nov 2022 20:16:29 -0500 Subject: [PATCH 2/8] add tests --- .../SupportedExternalApis.expected | 3 +++ .../SupportedExternalApis.java | 16 ++++++++++++++++ .../SupportedExternalApis.qlref | 1 + 3 files changed, 20 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..ce4b3dbe87a --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,3 @@ +| java.lang.StringBuilder#append(String) | 1 | +| java.lang.StringBuilder#toString() | 1 | +| java.util.Map#put(Object,Object) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java new file mode 100644 index 00000000000..34b56d5412e --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -0,0 +1,16 @@ +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +class SupportedExternalApis { + public static void main(String[] args) throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append("foo"); // supported + builder.toString(); // supported + + Map map = new HashMap<>(); + map.put("foo", new Object()); // supported + + Duration d = java.time.Duration.ofMillis(1000); // not supported + } +} diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql From 22c4d975adc7e9da87fc1b762095a8fe6bcc7e43 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 30 Nov 2022 18:03:57 -0500 Subject: [PATCH 3/8] remove old import --- java/ql/src/Telemetry/SupportedExternalApis.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/src/Telemetry/SupportedExternalApis.ql b/java/ql/src/Telemetry/SupportedExternalApis.ql index 2e1baebd60f..13c6473b580 100644 --- a/java/ql/src/Telemetry/SupportedExternalApis.ql +++ b/java/ql/src/Telemetry/SupportedExternalApis.ql @@ -8,7 +8,6 @@ import java import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -import semmle.code.java.dataflow.internal.NegativeSummary import ExternalApi private predicate relevant(ExternalApi api) { From 94c5d53192139ba36c907519c6f6aed0c8511f53 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 30 Nov 2022 18:51:05 -0500 Subject: [PATCH 4/8] add a couple more tests --- .../SupportedExternalApis.expected | 6 ++++++ .../SupportedExternalApis.java | 20 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index ce4b3dbe87a..6abe5a43232 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -1,3 +1,9 @@ +| java.net.URL#URL(String) | 2 | +| java.io.File#File(String) | 1 | +| java.io.FileWriter#FileWriter(File) | 1 | | java.lang.StringBuilder#append(String) | 1 | | java.lang.StringBuilder#toString() | 1 | +| java.net.URL#openConnection() | 1 | +| java.net.URL#openStream() | 1 | +| java.net.URLConnection#getInputStream() | 1 | | java.util.Map#put(Object,Object) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index 34b56d5412e..ec05018fd21 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -1,16 +1,26 @@ import java.time.Duration; import java.util.HashMap; import java.util.Map; +import java.io.InputStream; +import java.net.URL; +import java.io.File; +import java.io.FileWriter; class SupportedExternalApis { public static void main(String[] args) throws Exception { - StringBuilder builder = new StringBuilder(); - builder.append("foo"); // supported - builder.toString(); // supported + StringBuilder builder = new StringBuilder(); // uninteresting (parameterless constructor) + builder.append("foo"); // supported summary + builder.toString(); // supported summary - Map map = new HashMap<>(); - map.put("foo", new Object()); // supported + Map map = new HashMap<>(); // uninteresting (parameterless constructor) + map.put("foo", new Object()); // supported summary Duration d = java.time.Duration.ofMillis(1000); // not supported + + URL github = new URL("https://www.github.com/"); // supported summary + InputStream stream = github.openConnection().getInputStream(); // supported source (getInputStream), supported sink (openConnection) + + new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File) + new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL) } } From f1ebaf1ae10ba13b66491424085fca60063a7a4d Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 13:56:13 -0500 Subject: [PATCH 5/8] add csharp query --- .../ql/src/Telemetry/SupportedExternalApis.ql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 csharp/ql/src/Telemetry/SupportedExternalApis.ql diff --git a/csharp/ql/src/Telemetry/SupportedExternalApis.ql b/csharp/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..039f2a24677 --- /dev/null +++ b/csharp/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,24 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes APIs exposed by test libraries. + * @kind metric + * @tags summary telemetry + * @id csharp/telemetry/supported-external-api + */ + +private import csharp +private import semmle.code.csharp.dispatch.Dispatch +private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +private import ExternalApi + +private predicate relevant(ExternalApi api) { + not api.isUninteresting() and + ( + api.isSupported() or + api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable + ) +} + +from string info, int usages +where Results::restrict(info, usages) +select info, usages order by usages desc From b789534b6c0b6c34c201128cb09fc451870ab945 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:11:16 -0500 Subject: [PATCH 6/8] add csharp tests --- .../SupportedExternalApis.cs | 48 +++++++++++++++++++ .../SupportedExternalApis.expected | 11 +++++ .../SupportedExternalApis.qlref | 1 + .../Telemetry/SupportedExternalApis/options | 2 + 4 files changed, 62 insertions(+) create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs new file mode 100644 index 00000000000..6231ff6f61c --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Web; + +public class SupportedExternalApis +{ + public void M1() + { + var l = new List(); // Uninteresting parameterless constructor + var o = new object(); // Uninteresting parameterless constructor + l.Add(o); // Has flow summary + l.Add(o); // Has flow summary + } + + public void M2() + { + var d0 = new DateTime(); // Uninteresting parameterless constructor + var next0 = d0.AddYears(30); // Has no flow summary, supported as negative summary + + var d1 = new DateTime(2000, 1, 1); // Interesting constructor, supported as negative summary + var next1 = next0.AddDays(3); // Has no flow summary, supported as negative summary + var next2 = next1.AddYears(5); // Has no flow summary, supported as negative summary + } + + public void M3() + { + var guid1 = Guid.Parse("{12345678-1234-1234-1234-123456789012}"); // Has no flow summary, supported as negative summary + } + + public void M4() + { + var o = new object(); // Uninteresting parameterless constructor + var response = new HttpResponse(); // Uninteresting parameterless constructor + response.AddHeader("header", "value"); // Unsupported + response.AppendHeader("header", "value"); // Unsupported + response.Write(o); // Known sink + response.WriteFile("filename"); // Known sink + response.Write(o); // Known sink + } + + public void M5() + { + var l1 = Console.ReadLine(); // Known source + var l2 = Console.ReadLine(); // Known source + Console.SetError(Console.Out); // Has no flow summary, supported as negative summary + var x = Console.Read(); // Known source + } +} diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..f8b6feafb92 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,11 @@ +| System#Console.ReadLine() | 2 | +| System#DateTime.AddYears(System.Int32) | 2 | +| System.Collections.Generic#List<>.Add(T) | 2 | +| System.Web#HttpResponse.Write(System.Object) | 2 | +| System#Console.Read() | 1 | +| System#Console.SetError(System.IO.TextWriter) | 1 | +| System#Console.get_Out() | 1 | +| System#DateTime.AddDays(System.Double) | 1 | +| System#DateTime.DateTime(System.Int32,System.Int32,System.Int32) | 1 | +| System#Guid.Parse(System.String) | 1 | +| System.Web#HttpResponse.WriteFile(System.String) | 1 | diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options new file mode 100644 index 00000000000..9bbedebd7a2 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /r:System.Collections.Specialized.dll +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From aa633412f45fb0a6de162338f2e624ee145c64cd Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:25:45 -0500 Subject: [PATCH 7/8] add change notes --- .../change-notes/2022-12-01-supported-external-apis-query.md | 4 ++++ .../change-notes/2022-12-01-supported-external-apis-query.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md create mode 100644 java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md diff --git a/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..34bf2ef8409 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `csharp/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. diff --git a/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..83bfcf96e20 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. From 0e3e849ead716ae734ed9defdce7b00cb73cfea8 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:49:12 -0500 Subject: [PATCH 8/8] add negative summary test for java --- .../SupportedExternalApis/SupportedExternalApis.expected | 3 ++- .../Telemetry/SupportedExternalApis/SupportedExternalApis.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index 6abe5a43232..8a20a6c6c7b 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -1,5 +1,5 @@ +| java.io.File#File(String) | 2 | | java.net.URL#URL(String) | 2 | -| java.io.File#File(String) | 1 | | java.io.FileWriter#FileWriter(File) | 1 | | java.lang.StringBuilder#append(String) | 1 | | java.lang.StringBuilder#toString() | 1 | @@ -7,3 +7,4 @@ | java.net.URL#openStream() | 1 | | java.net.URLConnection#getInputStream() | 1 | | java.util.Map#put(Object,Object) | 1 | +| org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index ec05018fd21..7dd289acbaa 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.net.URL; import java.io.File; import java.io.FileWriter; +import org.apache.commons.io.FileUtils; class SupportedExternalApis { public static void main(String[] args) throws Exception { @@ -22,5 +23,7 @@ class SupportedExternalApis { new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File) new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL) + + FileUtils.deleteDirectory(new File("foo")); // supported negative summary (deleteDirectory), supported summary (File) } }