CVE-2022-25850 (published 2022-05-01T16:15Z)

The package github.com/hoppscotch/proxyscotch before 1.0.0 are vulnerable to Server-side Request Forgery (SSRF) when interceptor mode is set to proxy. It occurs when an HTTP request is made by a backend server to an untrusted URL submitted by a user. It leads to a leakage of sensitive information from the server.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-918
cwe_name: Server-Side Request Forgery (SSRF)
description: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
extended_description: By providing URLs to unexpected hosts or ports, attackers can make it appear that the server is sending the request, possibly bypassing access controls such as firewalls that prevent the attackers from accessing the URLs directly. The server can be used as a proxy to conduct port scanning of hosts in internal networks, use other URLs such as that can access documents on the system (using file://), or use other protocols such as gopher:// or tftp://, which may provide greater control over the contents of requests.
         

Fix information:
repo_url: https://github.com/hoppscotch/proxyscotch
commit_details: repo_url: https://github.com/hoppscotch/proxyscotch
author: Andrew Bastin
author_date: 2022-01-24 15:52:33+05:30
msg: feat: ability to have a blacklist of target urls for proxy to make calls to
repository: repo_url: https://github.com/hoppscotch/proxyscotch
repo_name: hoppscotch/proxyscotch
description: 📡 A simple proxy server created for https://hoppscotch.io
repo_language: Go
owner: hoppscotch
file_changes: filename: proxy.go
change_type: ModificationType.MODIFY
diff: @@ -24,6 +24,7 @@ var (
 	sessionFingerprint string
 	allowedOrigins     []string
 	bannedOutputs      []string
+	bannedDests        []string
 )
 
 type Request struct {
@@ -49,6 +50,16 @@ type Response struct {
 	Headers    map[string]string `json:"headers"`
 }
 
+func isAllowedDest(dest string) bool {
+	for _, b := range bannedDests {
+		if b == dest {
+			return false
+		}
+	}
+
+	return true
+}
+
 func isAllowedOrigin(origin string) bool {
 	if allowedOrigins[0] == "*" {
 		return true
@@ -68,6 +79,7 @@ func Initialize(
 	proxyURL string,
 	initialAllowedOrigins string,
 	initialBannedOutputs string,
+	initialBannedDests string,
 	onStatusChange statusChangeFunction,
 	withSSL bool,
 	finished chan bool,
@@ -75,6 +87,11 @@ func Initialize(
 	if initialBannedOutputs != "" {
 		bannedOutputs = strings.Split(initialBannedOutputs, ",")
 	}
+	if initialBannedDests != "" {
+		bannedDests = strings.Split(initialBannedDests, ",")
+	} else {
+		bannedDests = []string{}
+	}
 	allowedOrigins = strings.Split(initialAllowedOrigins, ",")
 	accessToken = initialAccessToken
 	sessionFingerprint = uuid.New().String()
@@ -209,6 +226,13 @@ func proxyHandler(response http.ResponseWriter, request *http.Request) {
 	proxyRequest.Method = requestData.Method
 	proxyRequest.URL, _ = url.Parse(requestData.Url)
 
+	// Block requests to illegal destinations
+	if !isAllowedDest(proxyRequest.URL.Hostname()) {
+		log.Print("A request to a banned destination was made.")
+		_, _ = fmt.Fprintln(response, "{\"success\": false, \"data\":{\"message\":\"(Proxy Error) Request cannot be to this destination.\"}}")
+		return
+	}
+
 	var params = proxyRequest.URL.Query()
 
 	for k, v := range requestData.Params {

programming_language: Go
filename: server.go
change_type: ModificationType.MODIFY
diff: @@ -12,10 +12,12 @@ func main() {
 	tokenPtr := flag.String("token", "", "the Proxy Access Token used to restrict access to the server.")
 	allowedOriginsPtr := flag.String("allowed-origins", "*", "a comma separated list of allowed origins.")
 	bannedOutputsPtr := flag.String("banned-outputs", "", "a comma separated list of banned outputs.")
+	bannedDestsPtr := flag.String("banned-dests", "", "a comma separated list of banned proxy destinations.")
+
 	flag.Parse()
 
 	finished := make(chan bool)
-	libproxy.Initialize(*tokenPtr, *hostPtr, *allowedOriginsPtr, *bannedOutputsPtr, onProxyStateChangeServer, false, finished)
+	libproxy.Initialize(*tokenPtr, *hostPtr, *allowedOriginsPtr, *bannedOutputsPtr, *bannedDestsPtr, onProxyStateChangeServer, false, finished)
 
 	<-finished
 }

programming_language: Go