Controlled and secure external site redirects
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/redirect", func(c *gin.Context) {
destination := c.Query("url")
c.Redirect(302, destination)
})
r.Run()
}
The code above is a simple Go application that uses the Gin framework. It sets up a GET endpoint at
/redirect
that takes a
url
parameter from the query string and then redirects the user to that URL.
However, the problem with this code is that it does not validate or control the
url
parameter. This means that an attacker could manipulate the
url
parameter to redirect users to a malicious website. This is known as an uncontrolled external site redirect vulnerability.
For example, an attacker could craft a link like
http://yourwebsite.com/redirect?url=http://maliciouswebsite.com
and trick users into clicking it. When the users click the link, they would be redirected to
http://maliciouswebsite.com
without realizing it. This could lead to various attacks such as phishing or stealing of user credentials.
package main
import (
"github.com/gin-gonic/gin"
"net/url"
"strings"
)
var trustedDomains = []string{
"www.trusteddomain1.com",
"www.trusteddomain2.com",
// add more trusted domains here
}
func main() {
r := gin.Default()
r.GET("/redirect", func(c *gin.Context) {
destination := c.Query("url")
parsedUrl, err := url.Parse(destination)
if err != nil {
c.String(400, "Invalid URL")
return
}
if !isTrustedDomain(parsedUrl.Host) {
c.String(400, "Untrusted domain")
return
}
c.Redirect(303, destination)
})
r.Run()
}
func isTrustedDomain(domain string) bool {
for _, trustedDomain := range trustedDomains {
if strings.EqualFold(domain, trustedDomain) {
return true
}
}
return false
}
The updated code includes several security measures to prevent uncontrolled external site redirects.
1. Input Validation: The URL provided in the query parameter is parsed using Go's
url.Parse
function. If the URL is not valid, the function will return an error, and the server will respond with a 400 status code and an "Invalid URL" message.
2. Whitelisting Trusted Domains: A list of trusted domains is maintained. When a redirect request is made, the host of the provided URL is checked against this list. If the host is not in the list of trusted domains, the server will respond with a 400 status code and an "Untrusted domain" message.
3. Safe Redirect Method: Instead of using a 302 redirect, a 303 redirect is used. This ensures that the HTTP method cannot be changed upon redirection.
Please note that this code does not include all the recommended security measures such as rate limiting, redirect confirmation page, and regular updates and patches for dependencies. These measures should also be implemented as part of a comprehensive security strategy.