Skip to content
Open
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
5 changes: 5 additions & 0 deletions internal/modules/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ func ParseYAMLModule(path string) (*YAMLModule, error) {
if err != nil {
return nil, fmt.Errorf("read module file: %w", err)
}
return parseYAMLModuleBytes(data)
}

// parseYAMLModuleBytes unmarshals and validates a module definition from raw
// bytes. ParseYAMLModule wraps it after reading the file off disk.
func parseYAMLModuleBytes(data []byte) (*YAMLModule, error) {
var ym YAMLModule
if err := yaml.Unmarshal(data, &ym); err != nil {
return nil, fmt.Errorf("parse yaml: %w", err)
Expand Down
28 changes: 28 additions & 0 deletions internal/modules/yaml_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package modules

import "testing"

func FuzzParseYAMLModule(f *testing.F) {
f.Add([]byte("id: t\ntype: http\n"))
f.Add([]byte("id: x\ntype: http\nhttp:\n matchers:\n - type: word\n words: [foo]\n"))
f.Add([]byte("type: http\n"))
f.Add([]byte("id: x\ntype: dns\n"))
f.Add([]byte(""))
f.Add([]byte("id: x\ntype: http\nhttp:\n matchers-condition: xor\n"))

f.Fuzz(func(t *testing.T, data []byte) {
parseYAMLModuleBytes(data)
})
}
39 changes: 39 additions & 0 deletions internal/scan/js/endpoints_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package js

import (
"slices"
"testing"
)

func FuzzExtractEndpoints(f *testing.F) {
f.Add(`fetch("/api/users")`, "https://example.com/app.js")
f.Add(`url: "https://cdn.example.com/v1/data.json"`, "")
f.Add(`const p = "../relative/path"`, "https://example.com/a/b/")
f.Add(`"text/html"`, "https://example.com")
f.Add("", "")
f.Add(`axios.get("/x").then()`, "not a url")

f.Fuzz(func(t *testing.T, content, baseURL string) {
got := ExtractEndpoints(content, baseURL)
for _, e := range got {
if e == "" {
t.Fatal("ExtractEndpoints returned an empty endpoint")
}
}
if !slices.IsSorted(got) {
t.Fatalf("ExtractEndpoints result not sorted: %v", got)
}
})
}
41 changes: 41 additions & 0 deletions internal/scan/js/secrets_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package js

import (
"strings"
"testing"
)

func FuzzScanSecrets(f *testing.F) {
f.Add(`const key = "AKIAIOSFODNN7EXAMPLE"`, "https://example.com/app.js")
f.Add(`apikey: "sk-1234567890abcdefghij"`, "")
f.Add("ghp_0123456789abcdefghijklmnopqrstuvwxyz01", "src")
f.Add("-----BEGIN RSA PRIVATE KEY-----", "")
f.Add(`var token = ""`, "")
f.Add("", "")
f.Add("aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "js")

f.Fuzz(func(t *testing.T, content, srcURL string) {
for _, m := range ScanSecrets(content, srcURL) {
// a reported match must be a non-empty run lifted verbatim from the
// input; anything else means the capture-group indexing is off
if m.Match == "" {
t.Fatalf("empty Match for rule %q", m.Rule)
}
if !strings.Contains(content, m.Match) {
t.Fatalf("Match %q (rule %q) not found in input", m.Match, m.Rule)
}
}
})
}
41 changes: 41 additions & 0 deletions internal/scan/jwt_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package scan

import "testing"

func FuzzAnalyzeJWT(f *testing.F) {
f.Add("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.sig")
f.Add("eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.")
f.Add("a.b.c")
f.Add("..")
f.Add("")
f.Add("not-a-jwt")

f.Fuzz(func(t *testing.T, raw string) {
analyzeJWT("fuzz", raw)
})
}

func FuzzDecodeJWTSegment(f *testing.F) {
f.Add("eyJhbGciOiJIUzI1NiJ9")
f.Add("eyJzdWIiOiIxMjM0In0")
f.Add("bm90LWpzb24")
f.Add("!!!!")
f.Add("")
f.Add("eyJhIjp7ImIiOnsiYyI6MX19fQ")

f.Fuzz(func(t *testing.T, seg string) {
decodeJWTSegment(seg)
})
}
32 changes: 32 additions & 0 deletions internal/scan/openapi_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package scan

import "testing"

func FuzzParseOpenAPISpec(f *testing.F) {
f.Add([]byte(`{"openapi":"3.0.0","paths":{"/x":{"get":{}}}}`))
f.Add([]byte(`{"swagger":"2.0","paths":{"/y":{}}}`))
f.Add([]byte("openapi: 3.0.0\npaths:\n /z:\n get: {}\n"))
f.Add([]byte(`{"paths":{}}`))
f.Add([]byte("not a spec"))
f.Add([]byte(""))
f.Add([]byte("{"))

f.Fuzz(func(t *testing.T, body []byte) {
spec, ok := parseOpenAPISpec(body)
if ok && spec == nil {
t.Fatal("parseOpenAPISpec returned ok with a nil spec")
}
})
}
29 changes: 29 additions & 0 deletions internal/scan/probe_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
: :
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
: ▄█ █ █▀ · BSD 3-Clause License :
: :
: (c) 2022-2026 vmfunc, xyzeva, :
: lunchcat alumni & contributors :
: :
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
*/

package scan

import "testing"

func FuzzExtractTitle(f *testing.F) {
f.Add([]byte("<html><head><title>Hi</title></head></html>"))
f.Add([]byte("<TITLE class=x> spaced </TITLE>"))
f.Add([]byte("<title>unclosed"))
f.Add([]byte("<title></title>"))
f.Add([]byte("no title here"))
f.Add([]byte(""))
f.Add([]byte("<title>a</title><title>b</title>"))

f.Fuzz(func(t *testing.T, body []byte) {
extractTitle(body)
})
}
Loading