Skip to content

Go: Local Sources #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 5, 2024
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
4 changes: 4 additions & 0 deletions go/ext/codeql-pack.lock.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
lockVersion: 1.0.0
dependencies: {}
compiled: false
Empty file added go/ext/generated/.gitkeep
Empty file.
Empty file added go/ext/manual/.gitkeep
Empty file.
19 changes: 19 additions & 0 deletions go/ext/manual/flag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
extensions:
# Make sure that the extensible model predicates are at least defined as empty.
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["flag", "", True, "String", "", "", "ReturnValue[0]", "remote", "manual"]
- ["flag", "", True, "StringVar", "", "", "ReturnValue[0]", "remote", "manual"]
# local variants
- ["flag", "", True, "String", "", "", "ReturnValue[0]", "local", "manual"]
- ["flag", "", True, "StringVar", "", "", "ReturnValue[0]", "local", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data: []
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data: []
27 changes: 27 additions & 0 deletions go/ext/manual/os.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
extensions:
# Make sure that the extensible model predicates are at least defined as empty.
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["os", "Args", True, "", "", "", "ReturnValue[0]", "remote", "manual"]
- ["os", "", True, "Getenv", "", "", "ReturnValue[0]", "remote", "manual"]
- ["os", "", True, "LookupEnv", "", "", "ReturnValue[0]", "remote", "manual"]
- ["os", "", True, "ReadFile", "", "", "ReturnValue[0]", "remote", "manual"]
- ["os", "", True, "Readlink", "", "", "ReturnValue[0]", "remote", "manual"]
- ["os", "", True, "Environ", "", "", "ReturnValue[0]", "remote", "manual"]
# local variants
- ["os", "Args", True, "", "", "", "ReturnValue[0]", "local", "manual"]
- ["os", "", True, "Getenv", "", "", "ReturnValue[0]", "local", "manual"]
- ["os", "", True, "LookupEnv", "", "", "ReturnValue[0]", "local", "manual"]
- ["os", "", True, "ReadFile", "", "", "ReturnValue[0]", "local", "manual"]
- ["os", "", True, "Readlink", "", "", "ReturnValue[0]", "local", "manual"]
- ["os", "", True, "Environ", "", "", "ReturnValue[0]", "local", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data: []
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data: []
10 changes: 10 additions & 0 deletions go/ext/qlpack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
library: true
name: githubsecuritylab/codeql-go-extensions
version: 0.0.1
extensionTargets:
codeql/go-all: '*'
dataExtensions:
- 'manual/*.yml'
- 'manual/**/*.yml'
- 'generated/*.yml'
- 'generated/**/*.yml'
92 changes: 23 additions & 69 deletions go/lib/ghsl/LocalSources.qll
Original file line number Diff line number Diff line change
Expand Up @@ -3,82 +3,36 @@ private import go
module LocalSources {
private import semmle.go.dataflow.DataFlow
private import semmle.go.dataflow.TaintTracking
private import semmle.go.dataflow.ExternalFlow as ExternalFlow
private import semmle.go.Scopes

abstract class Range extends DataFlow::Node { }

// ========== Sources ==========

abstract class Sources extends DataFlow::Node { }

// ----------------------------------------------------
// Used for finding Selections or Calls for Go imports
// ----------------------------------------------------

//class UseOfGoImports extends Sources {
//UseOfGoImports () {
//exists ( ValueEntity read,
//DataFlow::Package pkg |
//read.getScope().getEntity(_) = pkg.getScope().getEntity(_)
//and ( this.toString().regexpMatch("selection of.*")
//or this.toString().regexpMatch("call to .*") )
//)
//}
//}

// ----------------------------------------------------

class OsCmd extends LocalSources::Range {
OsCmd() {
exists ( ValueEntity read,
DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_)
and this.toString() = "selection of Run"
)
}
}
/**
* A source of data that is controlled by the local user.
*/
abstract class Range extends DataFlow::Node { }

class OsExec extends LocalSources::Range {
OsExec() {
exists ( ValueEntity read,
DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_)
and this.toString() = "selection of Command"
)
/**
* Support for Local Sources
*/
class MaDLocalSource extends Range {
MaDLocalSource() { ExternalFlow::sourceNode(this, "local") }
}
}

class OsArgs extends LocalSources::Range {
OsArgs() {
exists ( ValueEntity read,
DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_)
and this.toString() = "selection of Args"
)
class OsCmd extends LocalSources::Range {
OsCmd() {
exists(ValueEntity read, DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_) and
this.toString() = "selection of Run"
)
}
}
}

// Not currently working (need a test case)
//class OsGetenv extends Sources, DataFlow::CallNode {
//OsGetenv() {
//// https://pkg.go.dev/os#Getenv
//this.getTarget().hasQualifiedName(package("os", ""), "Getenv")
//or
//// https://pkg.go.dev/os#Environ
//this.getTarget().hasQualifiedName(package("os", ""), "Environ")
//}
//}

// https://pkg.go.dev/flag
class Flag extends LocalSources::Range {
Flag() {
exists ( ValueEntity read,
DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_)
and
( this.toString() = "selection of String"
or this.toString() = "selection of Parse" )
class OsExec extends LocalSources::Range {
OsExec() {
exists(ValueEntity read, DataFlow::Package pkg |
read.getScope().getEntity(_) = pkg.getScope().getEntity(_) and
this.toString() = "selection of Command"
)
}
}
}
}
25 changes: 25 additions & 0 deletions go/test/lib/localsources/cmd/flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"flag"
"fmt"
)

func main() {

wordPtr := flag.String("word", "foo", "a string")

numbPtr := flag.Int("numb", 42, "an int")
forkPtr := flag.Bool("fork", false, "a bool")

var svar string
flag.StringVar(&svar, "svar", "bar", "a string var")

flag.Parse()

fmt.Println("word:", *wordPtr)
fmt.Println("numb:", *numbPtr)
fmt.Println("fork:", *forkPtr)
fmt.Println("svar:", svar)
fmt.Println("tail:", flag.Args())
}
20 changes: 20 additions & 0 deletions go/test/lib/localsources/cmd/go_os.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"fmt"
"os"
)

func main() {
args := os.Args
fmt.Println(args[0], args[1])

// Environ
env := os.Environ()
fmt.Println(env[0], env[1])

// getenv
myenv := os.Getenv("HOME")
fmt.Println(myenv)

}
3 changes: 3 additions & 0 deletions go/test/lib/localsources/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/GitHubSecurityLab/CodeQLCommunityPacks

go 1.10
8 changes: 8 additions & 0 deletions go/test/lib/localsources/local.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
remoteSources
| cmd/flag.go:10:13:10:50 | call to String |
| cmd/go_os.go:13:9:13:20 | call to Environ |
| cmd/go_os.go:17:11:17:27 | call to Getenv |
localSources
| cmd/flag.go:10:13:10:50 | call to String |
| cmd/go_os.go:13:9:13:20 | call to Environ |
| cmd/go_os.go:17:11:17:27 | call to Getenv |
7 changes: 7 additions & 0 deletions go/test/lib/localsources/local.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import go
import ghsl.Utils
import ghsl.LocalSources

query predicate remoteSources(DataFlow::ExprNode node) { node instanceof RemoteFlowSource::Range }

query predicate localSources(DataFlow::ExprNode node) { node instanceof LocalSources::Range }
1 change: 1 addition & 0 deletions go/test/qlpack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ dependencies:
# codeql/go-queries: '*'
githubsecuritylab/codeql-go-queries: '*'
githubsecuritylab/codeql-go-libs: '*'
githubsecuritylab/codeql-go-extensions: '*'
extractor: go
tests: .
Loading