Skip to content

Instantly share code, notes, and snippets.

@ejcx
Last active April 27, 2019 07:10
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ejcx/14e057bdfa815e251585 to your computer and use it in GitHub Desktop.
Save ejcx/14e057bdfa815e251585 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"encoding/json"
"fmt"
"log"
"os"
"strings"
)
func main() {
responseHeaders := make(map[string]string)
// Read a bunch of headers from Stdin.
r := bufio.NewReader(os.Stdin)
for {
l, p, err := r.ReadLine()
// If you hit an error, just log it and go home.
if err != nil {
if len(responseHeaders) == 0 {
log.Fatalf("Error reading headers: %s", err.Error())
} else {
break
}
}
if p {
log.Fatalf("Too long. cURL is trolling")
}
// Split on a colon. It's required.
kv := strings.SplitN(string(l), ":", 2)
if len(kv) != 2 {
responseHeaders[kv[0]] = ""
continue
}
// Remove all colons. Trolly headers won't matter...
headerName := strings.ToLower(strings.TrimSpace(kv[0]))
headerValue := strings.ToLower(strings.TrimSpace(kv[1]))
responseHeaders[headerName] = headerValue
}
// We want something understandable. Let's find only vulnerable.
hasBadAcao := false
hasAcac := false
hostName := ""
for headerName, headerValue := range responseHeaders {
if headerName == "access-control-allow-origin" {
if strings.Contains(headerValue, "evil.com") {
hostName = strings.Replace(headerValue, "evil.com", "", 1)
hasBadAcao = true
}
}
if headerName == "access-control-allow-credentials" {
if strings.Contains(headerValue, "true") {
hasAcac = true
}
}
}
if hasBadAcao && hasAcac {
responseHeaders["x-hostname"] = hostName
pwned, err := json.Marshal(responseHeaders)
if err != nil {
log.Fatalf("Couldn't marshal: %s", err.Error())
}
fmt.Println(string(pwned))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment