Graphql Introspection in Adonisjs with Basic Auth
Graphql Introspection in Adonisjs with Basic Auth — how this specific combination creates or exposes the vulnerability
GraphQL introspection in an AdonisJS application exposes the schema, queries, and mutations when the introspection endpoint is reachable. When Basic Auth is used for HTTP-level protection but not enforced for the GraphQL route, unauthenticated or partially authenticated attackers can perform introspection to discover the schema. This combination creates a vulnerability because the protection mechanism (Basic Auth) is bypassed or not applied to the GraphQL entry point, allowing attackers to map the API surface without valid credentials.
In AdonisJS, GraphQL servers are typically implemented via packages such as adonisjs-graphql-client or custom HTTP handlers. If the route serving GraphQL requests does not validate credentials before passing the request to the GraphQL layer, introspection queries like the following can be executed by an unauthenticated client:
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
types {
...FullType
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
name
description
type {
...TypeRef
}
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
name
type {
...TypeRef
}
}
enumValues(includeDeprecated: true) {
name
description
}
possibleTypes {
...TypeRef
}
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
If the response returns a 200 status with schema data, the GraphQL endpoint is vulnerable. Attackers can use this information to identify sensitive types, queries, and mutations, which can then be targeted for further attacks such as BOLA/IDOR or property-level authorization issues. middleBrick would flag this as a finding under the BOLA/IDOR and Property Authorization checks when it detects that introspection is allowed on an endpoint that should be restricted.
Additionally, Basic Auth over HTTP without TLS exposes credentials in base64 encoding, making them trivial to intercept. Even when TLS is used, relying solely on Basic Auth for GraphQL does not prevent introspection unless the server explicitly disables it. middleBrick’s checks in this scenario would surface both the introspection exposure and missing transport hardening as actionable findings.
Basic Auth-Specific Remediation in Adonisjs — concrete code fixes
To secure GraphQL introspection in AdonisJS while using Basic Auth, you must enforce authentication before allowing the request to reach the GraphQL handler. This involves adding a route-level or middleware-level check that validates credentials and blocks introspection for unauthenticated requests.
First, ensure your GraphQL route is protected by a route middleware that validates Basic Auth credentials. Define a custom middleware, for example auth.basic.ts:
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class AuthBasicMiddleware {
public async handle({ request, response, auth }: HttpContextContract, next: () => Promise) {
const user = await auth.check()
if (!user) {
response.status(401).send({ error: 'Unauthorized' })
return
}
await next()
}
}
Register this middleware in start/kernel.ts:
import { HttpServerSettings } from '@ioc:Adonis/Core/HttpServer'
import AuthBasicMiddleware from 'App/Middleware/AuthBasic'
const serverHooks: HttpServerSettings['hooks'] = {
before: [
{ name: 'authBasic', global: false },
],
}
export default serverHooks
Then apply the middleware to your GraphQL route in routes.ts:
import Route from '@ioc:Adonis/Core/Route'
import AuthBasicMiddleware from 'App/Middleware/AuthBasic'
Route.post('/graphql', AuthBasicMiddleware, async ({ request }) => {
const { query, operationName, variables } = request.body()
// Pass to GraphQL handler
})
For Basic Auth specifically, configure your auth provider to validate username and password against your user model. In auth.ts configuration:
import { BaseAuthProvider } from '@ioc:Adonis/Addons/Auth'
export const authProviders: AuthProviders = {
username: {
driver: 'base',
model: () => import('App/Models/User'),
password: {
enableSave: true,
provider: 'bcrypt',
},
},
}
And an example login route that uses Basic Auth headers:
import Route from '@ioc:Adonis/Core/Route'
import { schema, rules } from '@ioc:Adonis/Core/Validator'
import Hash from '@ioc:Adonis/Core/Hash'
Route.post('/login', async ({ request, response }) => {
const bodySchema = schema.create({
username: schema.string.optional(),
password: schema.string(),
})
const { username, password } = await request.validate({ schema: bodySchema })
// If using Basic Auth via headers, parse them directly
const basicUser = request.authUser // depends on your auth setup
if (basicUser && await Hash.verify(basicUser.password, password)) {
response.header('Authorization', `Basic ${Buffer.from(`${basicUser.username}:${password}`).toString('base64')}`)
response.send({ authenticated: true })
} else {
response.status(401).send({ error: 'Invalid credentials' })
}
})
With these changes, introspection is only available to clients that provide valid Basic Auth credentials. middleBrick scans can then verify whether the protection is effective and whether introspection remains exposed in authenticated contexts.
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 |