Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
119 changes: 119 additions & 0 deletions java/lib/ghsl/Utils.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* 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) {
// TODO: fix this
source.asParameter() instanceof Parameter
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"
48 changes: 48 additions & 0 deletions java/src/debugging/PartialPathsFromSource.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @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

class Sources extends AllSources {
Sources() {
findByLocation(this, "App.java", _)
}

}

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

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\/.*/
Loading