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
18 changes: 18 additions & 0 deletions AUDIT-OWASP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# OWASP Top 10 Security Audit

## Summary
0 critical, 2 high, 1 medium findings

## Findings by Category

### A06: Vulnerable and Outdated Components (High)
- **Finding:** The `govulncheck` tool identified 13 vulnerabilities in the Go standard library, stemming from an outdated Go version.
- **Remediation:** It is recommended to upgrade the project's Go version to the latest stable release to mitigate these vulnerabilities.

### A10: Server-Side Request Forgery (SSRF) (High)
- **Finding:** The `RDAPLookupDomainWithTimeout`, `RDAPLookupIPWithTimeout`, and `RDAPLookupASNWithTimeout` functions constructed request URLs by directly embedding user-provided inputs. This could have allowed a malicious actor to craft inputs that would cause the server to make requests to internal resources.
- **Remediation:** All user-provided inputs (`domain`, `ip`, and `asn`) are now sanitized using `url.PathEscape()` before being included in the request URL, preventing path traversal and other SSRF-style attacks.

### A03: Injection (Medium)
- **Finding:** The `DNSLookup...` functions did not sanitize the `domain` parameter, which could have led to unexpected behavior if special characters were provided as input.
- **Remediation:** The `domain` parameter is now validated using a regular expression to ensure it conforms to a valid domain name format, mitigating the risk of injection attacks.
23 changes: 19 additions & 4 deletions dns_tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"net"
"net/http"
"net/url"
"regexp"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -259,6 +260,14 @@
return DNSLookupWithTimeout(domain, recordType, 10*time.Second)
}

// isValidDomain validates the domain name against a simple regex to prevent injection
func isValidDomain(domain string) bool {
// A simple regex to match valid domain name characters.
// This is not a full validation, but it prevents common injection attacks.
match, _ := regexp.MatchString(`^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$`, domain)
return match
}

// DNSLookupWithTimeout performs a DNS lookup with a custom timeout
func DNSLookupWithTimeout(domain string, recordType DNSRecordType, timeout time.Duration) DNSLookupResult {
start := time.Now()
Expand All @@ -268,6 +277,12 @@
Timestamp: start,
}

if !isValidDomain(domain) {
result.Error = "invalid domain format"
result.LookupTimeMs = time.Since(start).Milliseconds()
return result
}

ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

Expand Down Expand Up @@ -651,9 +666,9 @@
serverURL, ok := rdapServers[tld]
if !ok {
// Try to use IANA bootstrap
serverURL = fmt.Sprintf("https://rdap.org/domain/%s", domain)
serverURL = fmt.Sprintf("https://rdap.org/domain/%s", url.PathEscape(domain))
} else {
serverURL = serverURL + "domain/" + domain
serverURL = serverURL + "domain/" + url.PathEscape(domain)
}

client := &http.Client{Timeout: timeout}
Expand All @@ -663,7 +678,7 @@
result.LookupTimeMs = time.Since(start).Milliseconds()
return result
}
defer resp.Body.Close()

Check failure on line 681 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 681 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 681 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 681 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

body, err := io.ReadAll(resp.Body)
if err != nil {
Expand Down Expand Up @@ -709,7 +724,7 @@
}

// Use rdap.org as a universal redirector
serverURL := fmt.Sprintf("https://rdap.org/ip/%s", ip)
serverURL := fmt.Sprintf("https://rdap.org/ip/%s", url.PathEscape(ip))

client := &http.Client{Timeout: timeout}
resp, err := client.Get(serverURL)
Expand All @@ -718,7 +733,7 @@
result.LookupTimeMs = time.Since(start).Milliseconds()
return result
}
defer resp.Body.Close()

Check failure on line 736 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 736 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 736 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 736 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

body, err := io.ReadAll(resp.Body)
if err != nil {
Expand Down Expand Up @@ -760,7 +775,7 @@
asnNum := strings.TrimPrefix(strings.ToUpper(asn), "AS")

// Use rdap.org as a universal redirector
serverURL := fmt.Sprintf("https://rdap.org/autnum/%s", asnNum)
serverURL := fmt.Sprintf("https://rdap.org/autnum/%s", url.PathEscape(asnNum))

client := &http.Client{Timeout: timeout}
resp, err := client.Get(serverURL)
Expand All @@ -769,7 +784,7 @@
result.LookupTimeMs = time.Since(start).Milliseconds()
return result
}
defer resp.Body.Close()

Check failure on line 787 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 787 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 787 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-gonum

Error return value of `resp.Body.Close` is not checked (errcheck)

Check failure on line 787 in dns_tools.go

View workflow job for this annotation

GitHub Actions / build-test-wasm

Error return value of `resp.Body.Close` is not checked (errcheck)

body, err := io.ReadAll(resp.Body)
if err != nil {
Expand Down
Loading