Xss Cross Site Scripting in Fiber with Api Keys
Xss Cross Site Scripting in Fiber with Api Keys — how this specific combination creates or exposes the vulnerability
Cross-site scripting (XSS) in a Fiber application becomes significantly more severe when API keys are involved because the keys can be exposed to the browser and subsequently exfiltrated. XSS occurs when untrusted data is included in a page without proper validation or escaping, allowing an attacker to execute arbitrary JavaScript in the victim’s browser. When API keys are used for client-side authorization (e.g., passed in query parameters or response bodies that the frontend renders), an XSS flaw can directly leak these secrets.
Consider a Fiber route that echoes a query parameter into an HTML response without escaping:
package main
import (
"github.com/gofiber/fiber/v2"
"strings"
)
func main() {
app := fiber.New()
app.Get("/search", func(c *fiber.Ctx) error {
query := c.Query("q", "")
// Unsafe: directly embedding user input into HTML
return c.Send(strings.ReplaceAll("<h1>Results for: "+query+"</h1>", "\n", ""))
})
app.Listen(":3000")
}
If an API key is passed as q (e.g., /search?q=sk_live_xxx), the key is reflected into the HTML response. An attacker can craft a malicious link containing a stolen key or use a stored XSS vector to persistently harvest keys from other users. Because API keys often authorize access to backend services, exposure via XSS can lead to unauthorized access, data breaches, and lateral compromise.
In the context of middleBrick’s 12 security checks, this scenario would surface under Input Validation and Data Exposure. The scanner detects reflection points and missing output encoding, highlighting the risk that API keys can be exfiltrated via script execution. XSS against API key handling is especially dangerous when keys are used for server-side calls from the client or when the response includes sensitive data that the attacker can read through the browser session.
Api Keys-Specific Remediation in Fiber — concrete code fixes
To mitigate XSS when using API keys in Fiber, ensure that any user-controlled data is properly escaped before inclusion in HTML, and avoid embedding API keys in client-rendered contexts. Prefer storing keys in HttpOnly cookies or server-side sessions, and use short-lived tokens where possible. When API keys must be used on the client, do not echo them in HTML; instead, use secure, same-site storage mechanisms and strict Content Security Policy.
Below are concrete, safe code examples for handling API keys in Fiber.
1) Do not reflect API keys in HTML
Never directly concatenate user input or sensitive identifiers into HTML. Instead, treat them as data, not markup.
package main
import (
"github.com/gofiber/fiber/v2"
"net/http"
)
func main() {
app := fiber.New()
app.Get("/profile", func(c *fiber.Ctx) error {
// Safe: do not include API key in HTML; serve JSON with proper headers
c.Set("Content-Type", "application/json")
// Assume key is stored server-side; do not echo to client
return c.JSON(fiber.Map{
"message": "profile data",
})
})
app.Listen(":3000")
}
2) Use context values and server-side session storage
Store API keys server-side (e.g., in a secure store or encrypted session) and use user identifiers in signed cookies. Do not pass raw keys to the client.
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/session/v2"
)
func main() {
app := fiber.New()
store := session.NewMemoryStore()
app.Get("/data", func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
apiKey, ok := sess.Get("api_key").(string)
if !ok {
return c.SendStatus(fiber.StatusUnauthorized)
}
// Use apiKey server-side for backend calls; do not send to client
return c.JSON(fiber.Map{"ok": true})
})
app.Listen(":3000")
}
3) Escape output if user data must be rendered
If you must include user data in HTML, escape it according to the context (HTML body, attribute, JavaScript). Use a template engine with auto-escaping or manually escape.
package main
import (
"github.com/gofiber/fiber/v2"
"html"
)
func main() {
app := fiber.New()
app.Get("/hello", func(c *fiber.Ctx) error {
name := html.EscapeString(c.Query("name", "Guest"))
// Safe: escaped before embedding in HTML body
return c.Send("<div>Hello, " + name + "</div>")
})
app.Listen(":3000")
}
4) Enforce strict Content Security Policy
Add CSP headers to reduce the impact of any potential XSS by disallowing inline scripts and unauthorized sources.
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/cors"
)
func main() {
app := fiber.New()
app.Use(cors.New(cors.Config{
AllowOrigins: "https://yourdomain.com",
AllowHeaders: "Content-Type, Authorization",
}))
// CSP mitigations (example header)
app.Use(func(c *fiber.Ctx) error {
c.Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self';")
return c.Next()
})
app.Listen(":3000")
}Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |