Graphql Introspection in Adonisjs with Cockroachdb
Graphql Introspection in Adonisjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
GraphQL introspection in an AdonisJS application backed by CockroachDB can expose schema details that aid reconnaissance for further attacks. Introspection is a first-class GraphQL feature that returns types, queries, and mutations; when enabled in production, it allows an unauthenticated or low-privilege caller to map the API surface. In AdonisJS, this typically occurs when the GraphQL server is configured without disabling introspection or applying schema-based guards. Because AdonisJS often serves a unified GraphQL endpoint, the introspection response can reveal database-related patterns such as custom scalars, resolver naming conventions, and relationships that map to CockroachDB tables and columns.
The combination introduces risk if introspection is accessible while CockroachDB error messages or logging behaviors inadvertently disclose additional context. For example, a malicious actor can use introspection to identify queries like userByEmail or fields that trigger SQL under the hood. If input validation is weak, these discovered queries become targets for injection or property-level authorization bypass (BOLA/IDOR). Introspection does not require authentication by default in many GraphQL setups in AdonisJS, especially during development or if the schema is registered without guards. This unauthenticated surface, paired with CockroachDB’s precise error feedback on malformed queries, can guide an attacker toward data extraction or inference about schema structure.
Moreover, because AdonisJS can generate models and resolvers that directly reference CockroachDB tables, introspection may expose field names and relation paths that align with database columns. When rate limiting is not enforced strictly, automated probes can iterate over discovered queries to test for sensitive data exposure or excessive data retrieval. Even without credentials, an attacker can use introspection to build a query inventory for later stages such as BFLA/Privilege Escalation or unsafe consumption. The risk is not that introspection changes CockroachDB behavior, but that it hands an attacker a blueprint of what to target, making the database surface more predictable.
Cockroachdb-Specific Remediation in Adonisjs — concrete code fixes
To mitigate GraphQL introspection risks in AdonisJS with CockroachDB, you should disable introspection in production and enforce strict schema-level controls. Below are concrete steps and code examples.
1. Disable introspection in production
Configure your GraphQL server to reject introspection queries when not in development. In AdonisJS, this is typically done where you build the GraphQL server instance.
// start/graphql.ts
import { Server } from '@ioc:AdonisJS/Addons/GraphQL'
export const graphqlServer = Server.make('main', {
introspection: () => {
const env = import.meta.env.get('NODE_ENV')
return env === 'development'
},
})
2. Apply schema-based authorization
Use a schema filter to hide sensitive queries and fields unless the caller is authenticated and authorized. This reduces what introspection can reveal.
// start/schema.ts
import { schema } from '@ioc:AdonisJS/Addons/GraphQL'
export const graphqlSchema = schema({
query: {
user: schema.permissions({ allow: ['authenticated'] }),
post: schema.permissions({ allow: ['authenticated'] }),
},
mutation: {
createUser: schema.permissions({ allow: ['admin'] }),
},
})
3. Parameterized queries with CockroachDB to prevent injection
Ensure resolvers use parameterized SQL rather than string concatenation. Below is an example resolver using the CockroachDB client from AdonisJS.
// app/Resolvers/UserResolver.ts
import { DateTime } from 'luxon'
import { Database } from '@ioc:AdonisJS/Lucid/Database'
export class UserResolver {
public async userByEmail(_, { email }: { email: string }) {
const user = await Database.from('users')
.where('email', email)
.limit(1)
.select('id', 'name', 'role')
.thrownIfEmpty()
return user
}
public async users(_, __, { auth }: any) {
const user = auth.getUserOrFail()
// Enforce BOLA: users can only view their own record unless admin
if (!user.isAdmin) {
return await Database.from('users')
.where('id', user.id)
.select('id', 'name', 'email')
}
return await Database.from('users')
.select('id', 'name', 'email', 'role')
}
}
4. Input validation and sanitization
Validate arguments before they reach the resolver to reduce unexpected CockroachDB errors that could leak stack traces or hints about schema objects.
// app/Validators/UserValidator.ts
import { schema } from '@ioc:AdonisJS/Core/Validator'
export const userByEmailSchema = schema.create({
email: schema.string.optional([
'trim',
'normalize_utf8',
schema.email(),
]),
})
5. Error masking and logging hygiene
Ensure CockroachDB errors are not exposed directly to API responses. Wrap database calls to return generic messages while logging details securely for investigation.
// app/Helpers/errorHandler.ts
export function safeDbCall(fn: () => Promise) {
return fn().catch((err) => {
// Log full error internally
Logger.error('DB error', { err: err.message, stack: err.stack })
// Return a generic error to caller
throw new Error('Request failed')
})
}
6. Rate limiting and monitoring
Apply rate limiting at the route or middleware level to prevent automated abuse of discovered queries.
// start/hooks.ts
import Route from '@ioc:AdonisJS/Core/Route'
Route.group(() => {
Route.resource('users', 'UserController').apiOnly()
}).middleware([
'rateLimit:10,1m',
])
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 |