diff --git a/javascript/lib/ghsl.qll b/javascript/lib/ghsl.qll new file mode 100644 index 00000000..0eca22f0 --- /dev/null +++ b/javascript/lib/ghsl.qll @@ -0,0 +1 @@ +import ghsl.Utils \ No newline at end of file diff --git a/javascript/lib/ghsl/Utils.qll b/javascript/lib/ghsl/Utils.qll new file mode 100644 index 00000000..45d4df85 --- /dev/null +++ b/javascript/lib/ghsl/Utils.qll @@ -0,0 +1,92 @@ +/** + * A collection of utility predicates and classes for JavaScript + */ +private import javascript +private import semmle.javascript.security.dataflow.CommandInjectionCustomizations +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations +private import semmle.javascript.security.dataflow.LogInjectionQuery as LogInjection +private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations +private import semmle.javascript.security.dataflow.Xss as Xss +private import semmle.javascript.security.dataflow.XxeCustomizations + + +/** + * Filter results to a specific file and line number + * + * **Examples:** + * + * ``` + * filterByLocation(sources, "db.js", 1) + * // or we don't care about the line numbers + * filterByLocation(sources, "db.js", _) + * ``` + */ +predicate filterByLocation(DataFlow::Node node, string relative_path, int linenumber) { + node.getLocation().getFile().getRelativePath() = relative_path and + node.getLocation().getStartLine() = linenumber +} + + +/** + * All Sources (Remote and Local) + */ +class AllSources extends DataFlow::Node { + private string threadmodel; + + AllSources() { + this instanceof RemoteSources and + threadmodel = "remote" or + this instanceof LocalSources and + threadmodel = "local" + } + + /** + * Gets the source threat model. + */ + string getThreatModel() { + result = threadmodel + } +} + +/** + * Remote Sources (HTTP frameworks, etc) + */ +class RemoteSources extends ThreatModelSource { + RemoteSources() { this.getThreatModel() = "remote" } +} + +/** + * Local Sources (CLI arguments, Filesystem, etc) + */ +class LocalSources extends ThreatModelSource { + LocalSources() { this.getThreatModel() = "local" } +} + +/** + * List of all sinks + */ +class AllSinks extends DataFlow::Node { + private string sink; + + AllSinks() { + this instanceof CodeInjection::Sink and + sink = "code-injection" or + this instanceof CommandInjection::Sink and + sink = "command-injection" or + this instanceof LogInjection::Sink and + sink = "log-injection" or + this instanceof NosqlInjection::Sink and + sink = "nosql-injection" or + this instanceof Xss::Shared::Sink and + sink = "xss" or + this instanceof Xxe::Sink and + sink = "xxe" + } + + /** + * Gets the sink threat model. + */ + string sinkType() { + result = sink + } +} \ No newline at end of file diff --git a/javascript/lib/qlpack.yml b/javascript/lib/qlpack.yml index 6059e0f6..5f87b667 100644 --- a/javascript/lib/qlpack.yml +++ b/javascript/lib/qlpack.yml @@ -1,4 +1,4 @@ -library: true +library: true name: githubsecuritylab/codeql-javascript-libs version: 0.2.1 dependencies: diff --git a/javascript/src/debugging/Sinks.ql b/javascript/src/debugging/Sinks.ql new file mode 100644 index 00000000..ac62231c --- /dev/null +++ b/javascript/src/debugging/Sinks.ql @@ -0,0 +1,19 @@ +/** + * @name List of all known sinks + * @kind problem + * @problem.severity warning + * @security-severity 1.0 + * @sub-severity low + * @precision high + * @id js/debugging/sinks + * @tags debugging + */ + +import javascript +import ghsl + +from AllSinks sinks +// where +/// Filter by file and line number +// filterByLocation(sinks, "app.js", _) +select sinks, "sink[" + sinks.sinkType() + "]" diff --git a/javascript/src/debugging/Sources.ql b/javascript/src/debugging/Sources.ql new file mode 100644 index 00000000..451f18b0 --- /dev/null +++ b/javascript/src/debugging/Sources.ql @@ -0,0 +1,18 @@ +/** + * @name List of all known sources (remote, local, etc.) + * @kind problem + * @problem.severity warning + * @security-severity 1.0 + * @sub-severity low + * @precision high + * @id js/debugging/sources + * @tags debugging + */ + +import javascript +import ghsl + +from AllSources sources, string threatModel +where + sources.getThreatModel() = threatModel +select sources, "source[" + threatModel + "]" diff --git a/javascript/src/suites/javascript-debugging.qls b/javascript/src/suites/javascript-debugging.qls new file mode 100644 index 00000000..c4bfaf22 --- /dev/null +++ b/javascript/src/suites/javascript-debugging.qls @@ -0,0 +1,19 @@ +- description: "GitHub's Community Packs JavaScript/TypeScript Debugging Suite" + +- queries: '.' + from: githubsecuritylab/codeql-javascript-queries + +- include: + kind: + - problem + - path-problem + precision: + - very-high + - high + tags contain: + - debugging + +# Remove local testing folders +- exclude: + query path: + - /testing\/.*/ \ No newline at end of file