Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
d518890
test-cases: add CWE-77 (JS shelljs), CWE-912 (Java backdoor), CWE-23 …
CSTRSK Aug 8, 2026
b411304
test-cases: add CWE-307, CWE-285, CWE-200, CWE-400
CSTRSK Aug 8, 2026
02a54c3
test-cases: add CWE-287 (go)
CSTRSK Aug 8, 2026
dfc798d
test-cases: add CWE-306 (ruby)
CSTRSK Aug 8, 2026
c28655e
test-cases: add CWE-326 (python)
CSTRSK Aug 8, 2026
b34c34f
test-cases: add CWE-311 (java)
CSTRSK Aug 8, 2026
0e1258e
test-cases: add CWE-345 (go)
CSTRSK Aug 8, 2026
7357b9e
test-cases: add CWE-426 (ruby)
CSTRSK Aug 8, 2026
43a3c34
test-cases: add CWE-434 (javascript)
CSTRSK Aug 8, 2026
9023701
test-cases: add CWE-444 (python)
CSTRSK Aug 8, 2026
6c0b09d
test-cases: add CWE-470 (java)
CSTRSK Aug 8, 2026
a6d378b
test-cases: add CWE-476 (go)
CSTRSK Aug 8, 2026
cec8a33
test-cases: add CWE-494 (ruby)
CSTRSK Aug 8, 2026
21d130f
test-cases: add CWE-617 (javascript)
CSTRSK Aug 8, 2026
ab2afc0
test-cases: add CWE-626 (python)
CSTRSK Aug 8, 2026
5e0cb1f
test-cases: add CWE-693 (java)
CSTRSK Aug 8, 2026
00f2f8e
test-cases: add CWE-754 (go)
CSTRSK Aug 8, 2026
0303d5f
test-cases: add CWE-770 (ruby)
CSTRSK Aug 8, 2026
901b8c2
test-cases: add CWE-787 (javascript)
CSTRSK Aug 8, 2026
6388c44
test-cases: add CWE-835 (python)
CSTRSK Aug 8, 2026
2df3067
test-cases: add CWE-319 (java)
CSTRSK Aug 8, 2026
79e5f40
test-cases: add CWE-312 (go)
CSTRSK Aug 8, 2026
b8c0b53
test-cases: add CWE-284 (ruby)
CSTRSK Aug 8, 2026
5af847a
test-cases: add CWE-281 (javascript)
CSTRSK Aug 8, 2026
dd64787
test-cases: add CWE-113 (python)
CSTRSK Aug 8, 2026
c87f7ac
test-cases: add CWE-117 (java)
CSTRSK Aug 8, 2026
4da16d4
test-cases: add CWE-1236 (go)
CSTRSK Aug 8, 2026
8c23dd3
test-cases: add CWE-1321 (ruby)
CSTRSK Aug 8, 2026
e8a38ce
test-cases: add CWE-1333 (javascript)
CSTRSK Aug 9, 2026
d7715d3
test-cases: add CWE-1336 (python)
CSTRSK Aug 9, 2026
1dae686
test-cases: add CWE-1357 (java)
CSTRSK Aug 9, 2026
4371aa0
test-cases: add CWE-190 (go)
CSTRSK Aug 9, 2026
606a567
test-cases: add CWE-20 (ruby)
CSTRSK Aug 9, 2026
c77725b
test-cases: add CWE-201 (javascript)
CSTRSK Aug 9, 2026
83b9f86
test-cases: add CWE-209 (python)
CSTRSK Aug 9, 2026
1658d2c
test-cases: add CWE-256 (java)
CSTRSK Aug 9, 2026
f601b3a
test-cases: add CWE-295 (go)
CSTRSK Aug 9, 2026
1d627db
test-cases: add CWE-321 (ruby)
CSTRSK Aug 9, 2026
44bb174
test-cases: add CWE-327 (javascript)
CSTRSK Aug 9, 2026
edd7cd5
test-cases: add CWE-330 (python)
CSTRSK Aug 9, 2026
ffa08ba
test-cases: add CWE-338 (java)
CSTRSK Aug 9, 2026
de11541
test-cases: add CWE-346 (go)
CSTRSK Aug 9, 2026
7227489
test-cases: add CWE-347 (ruby)
CSTRSK Aug 9, 2026
981938c
test-cases: add CWE-352 (javascript)
CSTRSK Aug 9, 2026
bc39e54
test-cases: add CWE-362 (python)
CSTRSK Aug 9, 2026
c7cc096
test-cases: add CWE-377 (java)
CSTRSK Aug 9, 2026
ed4c8bf
test-cases: add CWE-384 (go)
CSTRSK Aug 9, 2026
d9db35b
test-cases: add CWE-489 (ruby)
CSTRSK Aug 9, 2026
aed554c
test-cases: add CWE-502 (javascript)
CSTRSK Aug 9, 2026
e3187f8
test-cases: add CWE-506 (python)
CSTRSK Aug 9, 2026
1dfb936
test-cases: add CWE-532 (java)
CSTRSK Aug 9, 2026
46c98cb
test-cases: add CWE-601 (go)
CSTRSK Aug 9, 2026
570c724
test-cases: add CWE-611 (ruby)
CSTRSK Aug 9, 2026
085117d
test-cases: add CWE-614 (javascript)
CSTRSK Aug 9, 2026
1934535
test-cases: add CWE-639 (python)
CSTRSK Aug 9, 2026
1e49764
test-cases: add CWE-643 (java)
CSTRSK Aug 9, 2026
702a611
test-cases: add CWE-681 (go)
CSTRSK Aug 9, 2026
b80638f
test-cases: add CWE-759 (ruby)
CSTRSK Aug 9, 2026
af73c6b
test-cases: add CWE-78 (javascript)
CSTRSK Aug 9, 2026
b0ace51
test-cases: add CWE-79 (python)
CSTRSK Aug 9, 2026
5a9e68e
test-cases: add CWE-798 (java)
CSTRSK Aug 9, 2026
fae6dec
test-cases: add CWE-862 (go)
CSTRSK Aug 9, 2026
21fdeab
test-cases: add CWE-89 (ruby)
CSTRSK Aug 9, 2026
02520c8
test-cases: add CWE-90 (javascript)
CSTRSK Aug 9, 2026
c7dd49f
test-cases: add CWE-915 (python)
CSTRSK Aug 9, 2026
c306d60
test-cases: add CWE-918 (java)
CSTRSK Aug 9, 2026
3314613
test-cases: add CWE-942 (go)
CSTRSK Aug 9, 2026
1f18d47
test-cases: add CWE-943 (ruby)
CSTRSK Aug 9, 2026
33d4e1a
test-cases: add CWE-95 (javascript)
CSTRSK Aug 9, 2026
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
84 changes: 79 additions & 5 deletions docs/VULNERABILITY_CATALOG.md

Large diffs are not rendered by default.

3,038 changes: 2,373 additions & 665 deletions vulns/VULNERABILITY_CATALOG.json

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions vulns/go/cwe-1236-go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// @id go-cwe-1236-csv-injection
// @test-case CSV injection via user-controlled input written to a CSV file
// @cwe CWE-1236
// @severity high
// @language go
// @expected-detection true
// @description User input is written directly into a CSV file without sanitization.
// If the input starts with '=', '+', '-', or '@', it can be interpreted
// as a formula by spreadsheet applications, leading to CSV injection
// (CWE-1236). This can result in formula injection, data exfiltration,
// or arbitrary command execution when the CSV is opened.
// @safe-guard Guarded by the always-false `neverRun` constant plus an `ignore`
// build tag; no file is ever written.
// @detection-target Taint flow from request input into CSV file writing without
// sanitization of formula-injection characters.
//
// NEVER RUN IN PRODUCTION — intentional test case for scanner validation.

//go:build ignore

package vulns

import (
"encoding/csv"
"net/http"
"os"
"strings"
)

func exportVulnerable(r *http.Request) error {
if neverRun {
userInput := r.URL.Query().Get("data") // SOURCE: attacker-controlled
file, err := os.Create("/tmp/export.csv")
if err != nil {
return err
}
defer file.Close()

writer := csv.NewWriter(file)
defer writer.Flush()

// VULNERABLE: CWE-1236 - user input written directly without sanitization
writer.Write([]string{userInput})
return nil
}
return nil
}

// exportSafe is the safe counterpart — the scanner should NOT flag this.
// @expected-detection false
func exportSafe(r *http.Request) error {
if neverRun {
userInput := r.URL.Query().Get("data") // SOURCE
file, err := os.Create("/tmp/export_safe.csv")
if err != nil {
return err
}
defer file.Close()

writer := csv.NewWriter(file)
defer writer.Flush()

// SAFE: input is sanitized to prevent formula injection
sanitized := userInput
if strings.HasPrefix(sanitized, "=") || strings.HasPrefix(sanitized, "+") ||
strings.HasPrefix(sanitized, "-") || strings.HasPrefix(sanitized, "@") {
sanitized = "'" + sanitized
}
writer.Write([]string{sanitized})
return nil
}
return nil
}
62 changes: 62 additions & 0 deletions vulns/go/cwe-190-go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// @id go-integer-overflow-parseint
// @test-case Integer overflow in arithmetic operation after parsing user input
// @cwe CWE-190
// @severity high
// @language go
// @expected-detection true
// @description User-controlled input is parsed as an integer and used in an
// arithmetic operation without bounds checking, leading to integer
// overflow. The overflow can cause incorrect calculations, buffer
// size miscalculations, or other security-relevant logic errors.
// @safe-guard Guarded by the always-false `neverRun` constant plus an `ignore`
// build tag; no arithmetic is ever performed.
// @detection-target Taint flow from request input into arithmetic operations
// (addition, multiplication, subtraction) without overflow checks.
//
// NEVER RUN IN PRODUCTION — intentional test case for scanner validation.

//go:build ignore

package vulns

import (
"net/http"
"strconv"
)

func calculateVulnerable(r *http.Request) int {
if neverRun {
valueStr := r.URL.Query().Get("value") // SOURCE: attacker-controlled
value, _ := strconv.Atoi(valueStr) // PARSING: user input to int
// VULNERABLE: CWE-190 integer overflow in multiplication
return value * 2 // VULNERABLE: CWE-190
}
return 0
}

func sumVulnerable(r *http.Request) int {
if neverRun {
aStr := r.FormValue("a") // SOURCE
bStr := r.FormValue("b") // SOURCE
a, _ := strconv.Atoi(aStr)
b, _ := strconv.Atoi(bStr)
// VULNERABLE: CWE-190 integer overflow in addition
return a + b // VULNERABLE: CWE-190
}
return 0
}

// calculateSafe is the safe counterpart — the scanner should NOT flag this.
// @expected-detection false
func calculateSafe(r *http.Request) int {
if neverRun {
valueStr := r.URL.Query().Get("value")
value, _ := strconv.ParseInt(valueStr, 10, 32)
// SAFE: bounds-checked conversion prevents overflow
if value > 0 && value < (1<<31-1)/2 {
return int(value * 2)
}
return 0
}
return 0
}
87 changes: 87 additions & 0 deletions vulns/go/cwe-287-go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// @id go-auth-bypass-jwt-none-alg
// @test-case Authentication bypass via JWT algorithm confusion (none algorithm)
// @cwe CWE-287
// @severity critical
// @language go
// @expected-detection true
// @description The application accepts JWT tokens signed with the "none" algorithm,
// allowing an attacker to forge a token without a valid signature. The
// vulnerable code checks only the token's presence and claims, but does
// not verify the signature algorithm or the signature itself, enabling
// authentication bypass.
// @safe-guard Guarded by the always-false `neverRun` constant plus an `ignore`
// build tag; no token is ever processed.
// @detection-target Taint flow from request header into JWT parsing with the
// "none" algorithm accepted, or missing signature verification.
//
// NEVER RUN IN PRODUCTION — intentional test case for scanner validation.

//go:build ignore

package vulns

import (
"encoding/json"
"net/http"
"strings"
)

// parseJWT is a minimal JWT parser for demonstration purposes.
func parseJWT(token string) (map[string]interface{}, error) {
parts := strings.Split(token, ".")
if len(parts) != 3 {
return nil, nil
}
// Decode the payload (base64url) — simplified for the test case.
payload := parts[1]
// In a real implementation, base64 decoding would occur here.
// For this test, we just return a static payload.
claims := map[string]interface{}{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
}
return claims, nil
}

func authenticateVulnerable(r *http.Request) bool {
if neverRun {
authHeader := r.Header.Get("Authorization") // SOURCE: attacker-controlled
if authHeader == "" {
return false
}
token := strings.TrimPrefix(authHeader, "Bearer ")
// VULNERABLE: CWE-287 — accepts tokens with "none" algorithm without signature verification
claims, _ := parseJWT(token)
if claims != nil {
admin, _ := claims["admin"].(bool)
return admin
}
}
return false
}

// authenticateSafe is the safe counterpart — the scanner should NOT flag this.
// @expected-detection false
func authenticateSafe(r *http.Request) bool {
if neverRun {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
return false
}
token := strings.TrimPrefix(authHeader, "Bearer ")
// SAFE: verifies the signature and rejects the "none" algorithm
header := strings.Split(token, ".")[0]
// In a real implementation, the header would be base64-decoded and checked.
if strings.Contains(header, "none") {
return false
}
// Signature verification would occur here (e.g., with HMAC or RSA).
claims, _ := parseJWT(token)
if claims != nil {
admin, _ := claims["admin"].(bool)
return admin
}
}
return false
}
72 changes: 72 additions & 0 deletions vulns/go/cwe-295-go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// @id go-tls-insecure-skip-verify
// @test-case TLS certificate verification disabled via InsecureSkipVerify
// @cwe CWE-295
// @severity high
// @language go
// @expected-detection true
// @description The HTTP client sets InsecureSkipVerify to true, which disables
// TLS certificate verification. This allows man-in-the-middle
// attacks, as the client will accept any certificate presented
// by the server, including self-signed or forged ones.
// @safe-guard Guarded by the always-false `neverRun` constant plus an `ignore`
// build tag; no network connection is ever made.
// @detection-target Taint flow from request input into http.Transport with
// InsecureSkipVerify set to true, or tls.Config with
// InsecureSkipVerify set to true.
//
// NEVER RUN IN PRODUCTION — intentional test case for scanner validation.

//go:build ignore

package vulns

import (
"crypto/tls"
"net/http"
)

func fetchVulnerable(r *http.Request) ([]byte, error) {
if neverRun {
url := r.URL.Query().Get("url") // SOURCE: attacker-controlled
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // VULNERABLE: CWE-295
},
},
}
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
buf := make([]byte, 1024)
n, _ := resp.Body.Read(buf)
return buf[:n], nil
}
return nil, nil
}

// fetchSafe is the safe counterpart — the scanner should NOT flag this.
// @expected-detection false
func fetchSafe(r *http.Request) ([]byte, error) {
if neverRun {
url := r.URL.Query().Get("url")
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false, // SAFE: certificate verification enabled
},
},
}
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
buf := make([]byte, 1024)
n, _ := resp.Body.Read(buf)
return buf[:n], nil
}
return nil, nil
}
42 changes: 42 additions & 0 deletions vulns/go/cwe-312-go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// @id go-cwe312-sensitive-data-logging
// @test-case Sensitive data (API key) is logged in plaintext
// @cwe CWE-312
// @severity high
// @language go
// @expected-detection true
// @description User-supplied API key from an HTTP request header is written
// directly to the application log via log.Printf. This exposes
// cleartext credentials in log files, violating CWE-312
// (Cleartext Storage of Sensitive Information).
// @safe-guard Guarded by the always-false `neverRun` constant plus an `ignore`
// build tag; no logging ever occurs.
// @detection-target Taint flow from request header into log.Printf or
// log.Println with sensitive data.
//
// NEVER RUN IN PRODUCTION — intentional test case for scanner validation.

//go:build ignore

package vulns

import (
"log"
"net/http"
)

func logAPIKeyVulnerable(r *http.Request) {
if neverRun {
apiKey := r.Header.Get("X-API-Key") // SOURCE: attacker-controlled sensitive data
log.Printf("User API key: %s", apiKey) // VULNERABLE: CWE-312 sink
}
}

// logAPIKeySafe is the safe counterpart — the scanner should NOT flag this.
// @expected-detection false
func logAPIKeySafe(r *http.Request) {
if neverRun {
apiKey := r.Header.Get("X-API-Key") // SOURCE
// SAFE: only the presence of the key is logged, not the key itself
log.Printf("User API key present: %v", apiKey != "")
}
}
Loading