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
16 changes: 8 additions & 8 deletions go/lib/codeql-pack.lock.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
lockVersion: 1.0.0
dependencies:
codeql/dataflow:
version: 1.1.8
version: 2.0.4
codeql/go-all:
version: 3.0.1
version: 4.2.2
codeql/mad:
version: 1.0.14
version: 1.0.20
codeql/ssa:
version: 1.0.14
version: 1.0.20
codeql/threat-models:
version: 1.0.14
version: 1.0.20
codeql/tutorial:
version: 1.0.14
version: 1.0.20
codeql/typetracking:
version: 1.0.14
version: 2.0.4
codeql/util:
version: 2.0.1
version: 2.0.7
compiled: false
4 changes: 4 additions & 0 deletions go/lib/ghsl.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import go
import ghsl.Utils
import ghsl.LocalSources
import ghsl.Sinks
48 changes: 48 additions & 0 deletions go/lib/ghsl/Sinks.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
private import go
private import semmle.go.dataflow.DataFlow
private import semmle.go.security.CommandInjectionCustomizations
private import semmle.go.security.OpenUrlRedirectCustomizations
private import semmle.go.security.ReflectedXssCustomizations
private import semmle.go.security.RequestForgeryCustomizations
private import semmle.go.security.SqlInjectionCustomizations
private import semmle.go.security.UnsafeUnzipSymlinkCustomizations
private import semmle.go.security.XPathInjectionCustomizations
private import semmle.go.security.ZipSlipCustomizations

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

AllSinks() {
this instanceof CommandInjection::Sink and
sink = "command-injection"
or
this instanceof OpenUrlRedirect::Sink and
sink = "open-url-redirect"
or
this instanceof ReflectedXss::Sink and
sink = "reflected-xss"
or
this instanceof RequestForgery::Sink and
sink = "request-forgery"
or
this instanceof SqlInjection::Sink and
sink = "sql-injection"
or
this instanceof UnsafeUnzipSymlink::EvalSymlinksSink and
sink = "unsafe-unzip"
or
this instanceof XPathInjection::Sink and
sink = "xpath-injection"
or
this instanceof ZipSlip::Sink and
sink = "zip-slip"
}

/**
* Gets the sink sink type.
*/
string sinkType() { result = sink }
}
43 changes: 41 additions & 2 deletions go/lib/ghsl/Utils.qll
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
import go
import semmle.go.frameworks.stdlib.Fmt
private import go
private import semmle.go.dataflow.DataFlow
private import semmle.go.dataflow.TaintTracking
private import semmle.go.frameworks.stdlib.Fmt

/**
* Find Node at Location
*/
predicate filterByLocation(DataFlow::Node node, string relative_path, int linenumber) {
node.getLocation().getFile().getRelativePath() = relative_path and
node.getLocation().getStartLine() = linenumber
}

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

AllSources() {
this instanceof RemoteFlowSource::Range and
threatmodel = "remote"
or
this instanceof LocalSources and
threatmodel = "local"
}

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

/**
* Local sources
*/
class LocalSources extends DataFlow::Node {
LocalSources() {
this.(SourceNode).getThreatModel() = "local"
}
}

class DynamicStrings extends DataFlow::Node {
DynamicStrings() {
Expand Down
40 changes: 40 additions & 0 deletions go/src/debugging/PartialPathsFromSink.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @name Partial Path Query from Sink
* @kind path-problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision low
* @id go/debugging/partial-path-from-sink
* @tags debugging
*/

import go
import ghsl
import semmle.go.dataflow.DataFlow
import semmle.go.dataflow.TaintTracking

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

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

int explorationLimit() { result = 10 }

private module PartialFlows = DataFlow::Global<PartialFlowConfig>;

private module PartialFlowsGraph = PartialFlows::FlowExplorationRev<explorationLimit/0>;

private import PartialFlowsGraph::PartialPathGraph

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

import go
import ghsl
import semmle.go.dataflow.DataFlow
import semmle.go.dataflow.TaintTracking

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

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

int explorationLimit() { result = 10 }

module PartialFlows = DataFlow::Global<PartialFlowConfig>;

module PartialFlowsGraph = PartialFlows::FlowExplorationFwd<explorationLimit/0>;

import PartialFlowsGraph::PartialPathGraph

from PartialFlowsGraph::PartialPathNode source, PartialFlowsGraph::PartialPathNode sink
where
/// Filter by location
// filterByLocation(source.getNode(), "main.go", _)
PartialFlowsGraph::partialFlow(source, sink, _)
select sink.getNode(), source, sink, "Partial Graph $@.", source.getNode(), "user-provided value"
15 changes: 15 additions & 0 deletions go/src/debugging/Sinks.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @name List of all known sinks
* @kind problem
* @problem.severity warning
* @security-severity 1.0
* @sub-severity low
* @precision high
* @id go/debugging/sinks
* @tags debugging
*/

import ghsl

from AllSinks sinks
select sinks, "sink[" + sinks.sinkType() + "]"
18 changes: 18 additions & 0 deletions go/src/debugging/Sources.ql
Original file line number Diff line number Diff line change
@@ -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 go/debugging/sources
* @tags debugging
*/

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 go/src/suites/go-debugging.qls
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- description: "GitHub's Community Packs Go Debugging Suite"

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

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

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