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
4 changes: 4 additions & 0 deletions detect/detect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ func TestPythonProject(t *testing.T) {
assertToolDetected(t, r, "lint", "Ruff")
assertToolDetected(t, r, "typecheck", "mypy")

// Detection-only library defs via dependencies primitive
assertToolDetected(t, r, "build", "requests")
assertToolDetected(t, r, "build", "Jinja2")

// Layout
if r.Layout == nil {
t.Fatal("expected layout info")
Expand Down
34 changes: 34 additions & 0 deletions detect/threat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,40 @@ func TestThreatModelGoProjectEmpty(t *testing.T) {
}
}

func TestThreatModelPythonLibs(t *testing.T) {
// Python fixture has requests (function:http-client) and jinja2
// (function:templating) which fire SSRF and XSS/SSTI mappings.
engine := New(loadKB(t), "../testdata/python-project")
r, err := engine.Run()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

tr := engine.ThreatModel(r)
threatIDs := make(map[string][]string)
for _, th := range tr.Threats {
threatIDs[th.ID] = th.IntroducedBy
}

if intro, ok := threatIDs["ssrf"]; !ok {
t.Error("expected ssrf threat from requests")
} else if !slices.Contains(intro, "requests") {
t.Errorf("ssrf introduced_by = %v, want to include requests", intro)
}

if intro, ok := threatIDs["ssti"]; !ok {
t.Error("expected ssti threat from jinja2")
} else if !slices.Contains(intro, "Jinja2") {
t.Errorf("ssti introduced_by = %v, want to include Jinja2", intro)
}

if intro, ok := threatIDs["xss"]; !ok {
t.Error("expected xss threat from jinja2 templating")
} else if !slices.Contains(intro, "Jinja2") {
t.Errorf("xss introduced_by = %v, want to include Jinja2", intro)
}
}

func TestSinksRubyProject(t *testing.T) {
engine := New(loadKB(t), "../testdata/ruby-project")
r, err := engine.Run()
Expand Down
28 changes: 28 additions & 0 deletions knowledge/csharp/newtonsoft-json.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[tool]
name = "Newtonsoft.Json"
category = "build"
homepage = "https://www.newtonsoft.com/json"
docs = "https://www.newtonsoft.com/json"
repo = "https://github.com/JamesNK/Newtonsoft.Json"
description = "JSON framework for .NET"

[detect]
dependencies = ["Newtonsoft.Json"]
ecosystems = ["csharp"]

[taxonomy]
role = ["library"]
function = ["serialization", "parsing"]
layer = ["backend"]

[[security.sinks]]
symbol = "TypeNameHandling"
threat = "deserialization"
cwe = "CWE-502"
note = "TypeNameHandling.All or .Auto enables polymorphic gadgets"

[[security.sinks]]
symbol = "JsonConvert.DeserializeObject"
threat = "deserialization"
cwe = "CWE-502"
note = "When TypeNameHandling is enabled"
27 changes: 27 additions & 0 deletions knowledge/go/golang-jwt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[tool]
name = "golang-jwt"
category = "build"
homepage = "https://golang-jwt.github.io/jwt"
docs = "https://golang-jwt.github.io/jwt"
repo = "https://github.com/golang-jwt/jwt"
description = "JWT implementation for Go"

[detect]
dependencies = ["github.com/golang-jwt/jwt/v5", "github.com/golang-jwt/jwt/v4", "github.com/golang-jwt/jwt"]
ecosystems = ["go"]

[taxonomy]
role = ["library"]
function = ["authentication"]
layer = ["backend"]

[[security.sinks]]
symbol = "jwt.Parse"
threat = "auth_bypass"
cwe = "CWE-347"
note = "Keyfunc must verify token.Method against expected"

[[security.sinks]]
symbol = "jwt.ParseWithClaims"
threat = "auth_bypass"
cwe = "CWE-347"
32 changes: 32 additions & 0 deletions knowledge/go/resty.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[tool]
name = "Resty"
category = "build"
homepage = "https://resty.dev"
docs = "https://resty.dev"
repo = "https://github.com/go-resty/resty"
description = "HTTP and REST client for Go"

[detect]
dependencies = ["github.com/go-resty/resty/v2", "github.com/go-resty/resty"]
ecosystems = ["go"]

[taxonomy]
role = ["library"]
function = ["http-client"]
layer = ["backend"]

[[security.sinks]]
symbol = "client.R().Get"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "client.R().Post"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "SetHostURL"
threat = "ssrf"
cwe = "CWE-918"
note = "When base URL is caller-controlled"
28 changes: 28 additions & 0 deletions knowledge/java/freemarker.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[tool]
name = "FreeMarker"
category = "build"
homepage = "https://freemarker.apache.org"
docs = "https://freemarker.apache.org"
repo = "https://github.com/apache/freemarker"
description = "Template engine for Java"

[detect]
dependencies = ["org.freemarker:freemarker"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["templating"]
layer = ["backend"]

[[security.sinks]]
symbol = "?no_esc"
threat = "xss"
cwe = "CWE-79"
note = "Built-in that bypasses autoescaping"

[[security.sinks]]
symbol = "Template.process"
threat = "ssti"
cwe = "CWE-1336"
note = "When template source is caller-controlled; new() built-in"
22 changes: 22 additions & 0 deletions knowledge/java/gson.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[tool]
name = "Gson"
category = "build"
homepage = "https://github.com/google/gson"
docs = "https://github.com/google/gson"
repo = "https://github.com/google/gson"
description = "JSON serialization for Java"

[detect]
dependencies = ["com.google.code.gson:gson"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["serialization", "parsing"]
layer = ["backend"]

[[security.sinks]]
symbol = "fromJson"
threat = "deserialization"
cwe = "CWE-502"
note = "Less gadget surface than Jackson but still risk with custom adapters"
34 changes: 34 additions & 0 deletions knowledge/java/jackson.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool]
name = "Jackson"
category = "build"
homepage = "https://github.com/FasterXML/jackson"
docs = "https://github.com/FasterXML/jackson"
repo = "https://github.com/FasterXML/jackson-databind"
description = "JSON processor for Java"

[detect]
dependencies = ["com.fasterxml.jackson.core:jackson-databind"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["serialization", "parsing"]
layer = ["backend"]

[[security.sinks]]
symbol = "enableDefaultTyping"
threat = "deserialization"
cwe = "CWE-502"
note = "Polymorphic deserialization with gadget chains; dozens of CVEs"

[[security.sinks]]
symbol = "@JsonTypeInfo"
threat = "deserialization"
cwe = "CWE-502"
note = "With use=Id.CLASS or Id.MINIMAL_CLASS"

[[security.sinks]]
symbol = "readValue"
threat = "deserialization"
cwe = "CWE-502"
note = "When target type uses polymorphic typing"
26 changes: 26 additions & 0 deletions knowledge/java/okhttp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[tool]
name = "OkHttp"
category = "build"
homepage = "https://square.github.io/okhttp"
docs = "https://square.github.io/okhttp"
repo = "https://github.com/square/okhttp"
description = "HTTP client for JVM and Android"

[detect]
dependencies = ["com.squareup.okhttp3:okhttp"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["http-client"]
layer = ["backend"]

[[security.sinks]]
symbol = "OkHttpClient.newCall"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "Request.Builder.url"
threat = "ssrf"
cwe = "CWE-918"
27 changes: 27 additions & 0 deletions knowledge/java/snakeyaml.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[tool]
name = "SnakeYAML"
category = "build"
homepage = "https://bitbucket.org/snakeyaml/snakeyaml"
docs = "https://bitbucket.org/snakeyaml/snakeyaml"
repo = "https://bitbucket.org/snakeyaml/snakeyaml"
description = "YAML parser for Java"

[detect]
dependencies = ["org.yaml:snakeyaml"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["serialization", "parsing"]
layer = ["backend"]

[[security.sinks]]
symbol = "Yaml.load"
threat = "deserialization"
cwe = "CWE-502"
note = "Default Constructor allows arbitrary types; use SafeConstructor; CVE-2022-1471"

[[security.sinks]]
symbol = "Yaml(new Constructor())"
threat = "deserialization"
cwe = "CWE-502"
34 changes: 34 additions & 0 deletions knowledge/java/thymeleaf.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool]
name = "Thymeleaf"
category = "build"
homepage = "https://www.thymeleaf.org"
docs = "https://www.thymeleaf.org"
repo = "https://github.com/thymeleaf/thymeleaf"
description = "Server-side Java template engine"

[detect]
dependencies = ["org.thymeleaf:thymeleaf", "org.springframework.boot:spring-boot-starter-thymeleaf"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["templating"]
layer = ["backend"]

[[security.sinks]]
symbol = "th:utext"
threat = "xss"
cwe = "CWE-79"
note = "Unescaped text; th:text is escaped"

[[security.sinks]]
symbol = "[("
threat = "xss"
cwe = "CWE-79"
note = "Inline unescaped expression"

[[security.sinks]]
symbol = "SpringTemplateEngine.process"
threat = "ssti"
cwe = "CWE-1336"
note = "When template name is caller-controlled; SpEL evaluation"
22 changes: 22 additions & 0 deletions knowledge/java/xstream.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[tool]
name = "XStream"
category = "build"
homepage = "https://x-stream.github.io"
docs = "https://x-stream.github.io"
repo = "https://github.com/x-stream/xstream"
description = "XML serialization for Java"

[detect]
dependencies = ["com.thoughtworks.xstream:xstream"]
ecosystems = ["java"]

[taxonomy]
role = ["library"]
function = ["serialization", "parsing"]
layer = ["backend"]

[[security.sinks]]
symbol = "XStream.fromXML"
threat = "deserialization"
cwe = "CWE-502"
note = "Without security framework configured; many CVEs"
37 changes: 37 additions & 0 deletions knowledge/node/axios.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[tool]
name = "axios"
category = "build"
homepage = "https://axios-http.com"
docs = "https://axios-http.com"
repo = "https://github.com/axios/axios"
description = "Promise-based HTTP client"

[detect]
dependencies = ["axios"]
ecosystems = ["node"]

[taxonomy]
role = ["library"]
function = ["http-client"]
layer = ["backend", "frontend"]

[[security.sinks]]
symbol = "axios.get"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "axios.post"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "axios.request"
threat = "ssrf"
cwe = "CWE-918"

[[security.sinks]]
symbol = "axios.create"
threat = "ssrf"
cwe = "CWE-918"
note = "When baseURL is caller-controlled"
Loading