Skip to content

Instantly share code, notes, and snippets.

@aviat
Created January 17, 2022 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aviat/f448c86b5d4ac5428e4622139be9dfbf to your computer and use it in GitHub Desktop.
Save aviat/f448c86b5d4ac5428e4622139be9dfbf to your computer and use it in GitHub Desktop.
// From The Web Application Hacker's Handbook edition #2
// Build: go build chapter2.go
// Usage: ./chapter2 your_input_string
// 5. An input validation mechanism designed to block cross-site scripting
// attacks performs the following sequence of steps on an item of input:
// 1. Strip any <script> expressions that appear.
// 2. Truncate the input to 50 characters.
// 3. Remove any quotation marks within the input.
// 4. URL-decode the input.
// 5. If any items were deleted, return to step 1.
//
// Can you bypass this validation mechanism to smuggle the following data past it?
// "><script>alert("foo")</script>
package main
import (
"fmt"
"os"
"math"
"strings"
"net/url"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: ", os.Args[0], "<input string>")
os.Exit(1)
}
str := os.Args[1]
result := str
err := error(nil)
for replaced := true ; replaced ; {
script_removed := strings.ReplaceAll(result, "<script", "")
min := math.Min(float64(len(script_removed)), 50)
truncated := script_removed[0:int(min)]
quotes_removed := strings.ReplaceAll(truncated, "\"", "")
replaced = (len(quotes_removed) != len(truncated))
result, err = url.QueryUnescape(quotes_removed)
if err != nil {
fmt.Fprintln(os.Stderr, "Error unescaping: ", err)
os.Exit(1)
}
}
if result == "\"><script>alert(\"foo\")</script>" {
fmt.Println("Success!")
} else {
fmt.Println("Failure.")
}
fmt.Println("Result: ", result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment