Graphql Introspection in Fiber with Jwt Tokens
Graphql Introspection in Fiber with Jwt Tokens — how this specific combination creates or exposes the vulnerability
GraphQL introspection is a feature that allows clients to query the schema structure, types, and operations of a GraphQL API at runtime. In a Fiber-based Go application, enabling introspection without proper access controls can expose the full API surface to unauthenticated or insufficiently authenticated requests. When JWT tokens are used for authorization, misconfiguration can lead to scenarios where introspection is accessible without valid token validation or where tokens are accepted but not properly verified before introspection is allowed.
The combination becomes a vulnerability when introspection endpoints are publicly reachable and JWT validation is either missing, incomplete, or applied inconsistently. For example, if middleware checks for a JWT only on certain routes but introspection is mounted at a path like /graphql without strict token requirements, an attacker can send an introspection query without any token or with a malformed token and obtain the full schema. This can reveal sensitive types, queries, mutations, and relationships that should remain hidden.
Additionally, if the JWT implementation does not enforce token binding or scope validation, introspection may be allowed for tokens that lack the necessary permissions. Attackers can leverage this to map the API surface and identify endpoints for further exploitation, such as BOLA/IDOR or property-level authorization issues. middleBrick’s scan checks for exposed introspection combined with weak JWT validation as part of its Authentication and Input Validation checks, highlighting the risk when these controls are not properly aligned.
Real-world patterns include using graphql.NewServer with a schema that inadvertently allows introspection in production, while JWT middleware is applied to downstream resolvers but not to the introspection handler itself. This inconsistency means that even though tokens are required for business operations, the schema structure remains exposed. middleBrick’s OpenAPI/Swagger spec analysis can detect mismatches between declared security schemes and runtime behavior, including whether introspection is reachable without authentication.
In secure designs, introspection should be disabled in production or strictly gated behind the same JWT validation and authorization checks applied to all other GraphQL operations. This ensures that only authenticated and authorized clients can inspect the schema, reducing the risk of information leakage that could aid further attacks.
Jwt Tokens-Specific Remediation in Fiber — concrete code fixes
To remediate GraphQL introspection risks in Fiber when using JWT tokens, enforce consistent token validation across all endpoints, including introspection routes. Below are concrete code examples demonstrating secure practices.
1. JWT validation middleware applied globally
Ensure JWT middleware is applied to all routes, and avoid bypassing it for specific paths such as /graphql.
// main.go
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/jwt"
)
func main() {
app := fiber.New()
config := jwt.Config{
SigningKey: jwt.SigningKey{Key: []byte("your-secret-key")},
ContextKey: "user",
SigningMethod: "HS256",
}
// Apply JWT middleware globally
app.Use(jwt.New(config).Verify)
app.Post("/graphql", func(c *fiber.Ctx) error {
// At this point, c.Locals("user") contains validated claims
// Proceed with GraphQL handling
return c.SendString("GraphQL response")
})
app.Listen(":3000")
}
2. Disable introspection in production or gate it behind authorization
Disable introspection in production environments or explicitly check JWT claims before allowing introspection queries.
// handlers.go
package main
import (
"github.com/99designs/gqlgen/graphql"
"github.com/gofiber/fiber/v2"
)
func GraphQLHandler(schema graphql.HandlerRoot) fiber.Handler {
return func(c *fiber.Ctx) error {
// Validate JWT and extract claims
user := c.Locals("user")
if user == nil {
return c.Status(fiber.StatusUnauthorized).SendString("Unauthorized")
}
// Example: allow introspection only for admin role claims
// Implement custom logic to inspect query and reject introspection if not permitted
// For simplicity, we assume a helper function handles this
if isIntrospectionQuery(c) && !hasPermission(user, "introspect") {
return c.Status(fiber.StatusForbidden).SendString("Forbidden: introspection not allowed")
}
// Proceed with GraphQL handling using schema
return nil
}
}
func isIntrospectionQuery(c *fiber.Ctx) bool {
// Simplified check; in practice, parse the GraphQL query body
body := c.Body()
return len(body) > 0 && (string(body) == `{ __schema { queryType { name } } }`)
}
func hasPermission(user interface{}, perm string) bool {
// Implement role/claim-based permission check
return true
}
3. Use environment-based configuration to control introspection
Control introspection behavior based on environment variables to ensure it is disabled in production.
// config.go
package main
import (
"os"
)
var allowIntrospection = os.Getenv("ALLOW_INTROSPECTION") == "true"
// In handler, check allowIntrospection before permitting introspection queries
By combining global JWT validation, explicit authorization checks, and environment-aware configuration, you can mitigate the risk of exposing schema information while maintaining secure token-based access in Fiber GraphQL services.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |