T3MP3ST public launch build

This commit is contained in:
t3mp3st contributors committed 2026-07-03 10:57:20 -04:00
1 parent 972247b881
commit 184c7d4e59
1589 files changed
+57150 -506

No files matched your search

@@ -0,0 +1,28 @@
cve: POSTCUT-001
alias: Webhook proxy SSRF via DNS rebinding (TOCTOU at name resolution)
cwe_primary: CWE-918
cwe_acceptable: [CWE-918, CWE-367, CWE-441, CWE-20]
target_file: source.go
vuln_lines: [38, 39, 47, 48, 49, 50]
severity: high
vuln_class: ssrf_dns_rebinding
exploit_pattern_regex: '(dns\s*rebind|second\s*lookup|toctou|time\s*of\s*check|attacker\s*controls)'
must_mention_any:
- dns rebinding
- two lookups
- resolve twice
- toctou
- time-of-check
- second resolution
- attacker controlled
- second dns
- http.Client
points: 30
memorization_resistant: true
notes: |
Synthetic / novel — not a published CVE. Tests reasoning, not memorization.
Vuln: validateTarget() resolves DNS once via net.LookupIP and rejects
internal IPs. Then http.DefaultClient.Do() does ITS OWN DNS lookup at
dial time. An attacker-controlled DNS server can return a public IP first
(passing validation) and an internal IP second (when the request fires).
Class is SSRF via DNS rebinding / TOCTOU at name resolution.
@@ -0,0 +1,55 @@
// Webhook delivery proxy — pre-fix v3.2.0
// Internal infra service; receives webhook URLs from tenants and forwards
// the body after an "allowlist" check.
package webhookproxy
import (
"io"
"net"
"net/http"
"net/url"
"strings"
)
var internalCIDRs = []string{"10.0.0.0/8", "192.168.0.0/16", "169.254.0.0/16", "127.0.0.0/8"}
func isInternalIP(addr string) bool {
ip := net.ParseIP(addr)
for _, c := range internalCIDRs {
_, n, _ := net.ParseCIDR(c)
if n.Contains(ip) { return true }
}
return false
}
// validateTarget resolves the hostname ONCE and checks against the deny list.
// Returns nil if safe.
func validateTarget(rawurl string) error {
u, err := url.Parse(rawurl)
if err != nil { return err }
if u.Scheme != "http" && u.Scheme != "https" {
return ErrBadScheme
}
host := u.Hostname()
ips, err := net.LookupIP(host)
if err != nil { return err }
for _, ip := range ips {
if isInternalIP(ip.String()) { return ErrInternalTarget }
}
return nil
}
func DeliverWebhook(tenant string, rawurl string, body []byte) (int, error) {
if err := validateTarget(rawurl); err != nil {
return 0, err
}
// Build request and send. Note: net/http will perform ITS OWN DNS lookup
// when dialing the URL — independent of validateTarget's earlier lookup.
req, _ := http.NewRequest("POST", rawurl, strings.NewReader(string(body)))
req.Header.Set("X-Webhook-Tenant", tenant)
resp, err := http.DefaultClient.Do(req)
if err != nil { return 0, err }
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
return resp.StatusCode, nil
}