Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions java/lib/ghsl.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ghsl.LocalSources
// Export utils
import ghsl.Utils
118 changes: 118 additions & 0 deletions java/lib/ghsl/Utils.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* A collection of utility predicates and classes for the Java library.
*/

private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
// Sinks
private import semmle.code.java.security.QueryInjection
private import semmle.code.java.security.CommandLineQuery
private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.LogInjection
private import semmle.code.java.security.OgnlInjection
private import semmle.code.java.security.RequestForgery
private import semmle.code.java.security.TemplateInjection

/**
* Filter nodes by its location (relative path or base name).
*/
bindingset[relative_path]
predicate findByLocation(DataFlow::Node node, string relative_path, int linenumber) {
node.getLocation().getFile().getRelativePath().matches(relative_path) and
node.getLocation().getStartLine() = linenumber
}

/**
* This will only show sinks that are callable (method calls)
*/
predicate isCallable(DataFlow::Node sink) { sink.asExpr() instanceof MethodCall }

/**
* Check if the source node is a method parameter.
*/
predicate checkSource(DataFlow::Node source) {
exists(source.asParameter())
or
source.asExpr() instanceof MethodCall
}

/**
* Local sources
*/
class LocalSources = LocalUserInput;

/**
* List of all the souces
*/
class AllSources extends DataFlow::Node {
private string threadmodel;

AllSources() {
this instanceof LocalUserInput and
threadmodel = "local"
or
this instanceof RemoteFlowSource and
threadmodel = "remote"
or
this instanceof ActiveThreatModelSource
and
threadmodel = this.(SourceNode).getThreatModel()
}

/**
* Gets the source threat model.
*/
string getThreatModel() {
result = threadmodel
}
}

/**
* List of all the sinks that we want to check.
*/
class AllSinks extends DataFlow::Node {
private string sink;

AllSinks() {
this instanceof QueryInjectionSink
and
sink = "QueryInjectionSink"
or
this instanceof CommandInjectionSink
and
sink = "CommandInjectionSink"
or
this instanceof LdapInjectionSink
and
sink = "LdapInjectionSink"
or
this instanceof LogInjectionSink
and
sink = "LogInjectionSink"
or
this instanceof OgnlInjectionSink
and
sink = "OgnlInjectionSink"
or
this instanceof RequestForgerySink
and
sink = "RequestForgerySink"
or
this instanceof TemplateInjectionSink
and
sink = "TemplateInjectionSink"
or
// All MaD sinks
sinkNode(this, _)
and
sink = "MaD"
}

/**
* Gets the sink sink type.
*/
string sinkType() {
result = sink
}
}
1 change: 1 addition & 0 deletions java/lib/qlpack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ name: githubsecuritylab/codeql-java-libs
version: 0.2.1
dependencies:
codeql/java-all: '*'
githubsecuritylab/codeql-java-extensions: '0.2.1'
41 changes: 41 additions & 0 deletions java/src/debugging/PartialPathsFromSink.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @name Partial Path Query from Sink
* @kind path-problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision low
* @id java/debugging/partial-path-from-sink
* @tags debugging
*/

import java
import ghsl
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking

// Partial Graph
private module RemoteFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { any() }

predicate isSink(DataFlow::Node sink) { sink instanceof AllSinks }
}

int explorationLimit() { result = 10 }

private module RemoteFlows = DataFlow::Global<RemoteFlowsConfig>;

private module RemoteFlowsPartial = RemoteFlows::FlowExplorationRev<explorationLimit/0>;

private import RemoteFlowsPartial::PartialPathGraph

from RemoteFlowsPartial::PartialPathNode source, RemoteFlowsPartial::PartialPathNode sink
where
/// Only show sinks from a certain file
// findByLocation(sink.getNode(), "File.java", _) and
/// Only show sources that match our criteria
// checkSource(source.getNode()) and
/// Partical Path
RemoteFlowsPartial::partialFlow(source, sink, _)
select sink.getNode(), source, sink, "Partial Graph $@.", source.getNode(), "user-provided value"
41 changes: 41 additions & 0 deletions java/src/debugging/PartialPathsFromSource.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @name Partial Path Query from Source
* @kind path-problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision low
* @id java/debugging/partial-path-from-source
* @tags debugging
*/

import java
import ghsl
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking

// Partial Graph
private module RemoteFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof AllSources }

predicate isSink(DataFlow::Node sink) { none() }
}

int explorationLimit() { result = 10 }

private module RemoteFlows = DataFlow::Global<RemoteFlowsConfig>;

private module RemoteFlowsPartial = RemoteFlows::FlowExplorationFwd<explorationLimit/0>;

private import RemoteFlowsPartial::PartialPathGraph

from RemoteFlowsPartial::PartialPathNode source, RemoteFlowsPartial::PartialPathNode sink
where
/// Filter by file (line number)
// findByLocation(source.getNode(), "File.java", _) and
/// Filter by if the sink is callable
// isCallable(sink.getNode()) and
/// Perform Partial Flow query
RemoteFlowsPartial::partialFlow(source, sink, _)
select sink.getNode(), source, sink, "Partial Graph $@.", source.getNode(), "user-provided value"
16 changes: 16 additions & 0 deletions java/src/debugging/Sinks.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @name List of all known sinks
* @kind problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision high
* @id java/debugging/sinks
* @tags debugging
*/

import java
import ghsl

from AllSinks sinks
select sinks, "sink[" + sinks.sinkType() + "]"
19 changes: 19 additions & 0 deletions java/src/debugging/Sources.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @name List of all known sources (remote, local, etc.)
* @kind problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision high
* @id java/debugging/sources
* @tags debugging
*/

import java
import ghsl

from AllSources sources, string threatModel
where threatModel = sources.getThreatModel()
// Local sources
// sources.getThreatModel() = "local"
select sources, "source[" + threatModel + "]"
19 changes: 19 additions & 0 deletions java/src/suites/java-debugging.qls
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- description: "GitHub's Community Packs Java/Kotlin Extended Suite"

- queries: '.'
from: githubsecuritylab/codeql-java-queries

- include:
kind:
- problem
- path-problem
precision:
- very-high
- high
tags contain:
- debugging

# Remove local testing folders
- exclude:
query path:
- /testing\/.*/