Auth Bypass in Adonisjs with Oracle Db
Auth Bypass in Adonisjs with Oracle Db — how this specific combination creates or exposes the vulnerability
AdonisJS is a Node.js web framework that relies on its authentication layer to guard access routes. When integrating with Oracle Database, developers often use an ORM such as Lucid to manage users and sessions. If query building, model binding, or raw query usage is misconfigured, an attacker can bypass intended access controls.
One common pattern is authenticating a user against an auth:api guard and then assuming the application will enforce row-level constraints for subsequent Oracle queries. However, if route or model logic does not explicitly scope queries by the authenticated user ID, the application may return or modify data belonging to other users. This becomes an Auth Bypass/IDOR when the attacker manipulates identifiers (e.g., changing :id in a URL) and the backend uses those identifiers directly in Oracle SQL without validating ownership.
An example vulnerability occurs when an endpoint uses a raw Oracle bind variable but does not include the user’s identity in the WHERE clause. Consider a route like /api/users/:id that constructs an Oracle query as follows:
const userQuery = `SELECT * FROM users WHERE id = :userId`;
const result = await Database.query(userQuery, { userId: request.params.id });
If the developer neglects to include the authenticated user’s ID in the filter (for example, relying on session middleware to enforce ownership), an attacker can supply any numeric ID and potentially access other users’ records. AdonisJS’s session/cookie handling does not automatically restrict SQL predicates; it is the developer’s responsibility to ensure every Oracle query respects the authenticated subject.
Additional risk occurs when using dynamic schema or table names in Oracle without strict validation. If an endpoint interpolates identifiers based on user input (e.g., tenant or schema name), an attacker may leverage malformed input to pivot across logical boundaries. Although AdonisJS provides hooks to sanitize inputs, failing to apply them consistently across all Oracle interactions can expose authentication bypass pathways.
The combination of AdonisJS’s flexible route model binding and Oracle’s procedural capabilities increases the surface for logic flaws. Without explicit row ownership checks and parameterized bind variables, attackers can traverse authentication boundaries by manipulating identifiers or leveraging overly permissive query construction.
Oracle Db-Specific Remediation in Adonisjs — concrete code fixes
Remediation centers on ensuring every Oracle query incorporates the authenticated user’s identity and uses safe bind patterns. Below are concrete, secure examples for AdonisJS with Oracle Database.
1. Always scope queries by authenticated subject. After authentication, retrieve the user’s ID from the auth session and include it in the SQL WHERE clause:
import { DateTime } from 'luxon';
import User from 'App/Models/User';
export default class UsersController {
async show({ auth, params, response }) {
const user = await auth.authenticate();
const targetId = params.id;
// Safe: bind variables and ownership check
const row = await Database.from('users')
.where('id', targetId)
.andWhere('owner_id', user.id)
.first();
if (!row) {
return response.notFound();
}
return row;
}
}
2. Use parameterized bind variables for all Oracle inputs to prevent injection and ensure consistent typing. Avoid string concatenation or raw interpolation:
const safeQuery = `
SELECT profile_data FROM user_profiles
WHERE user_id = :uid AND status = :status
`;
const rows = await Database.query(safeQuery, {
uid: authenticatedUser.id,
status: 'active'
});
3. When using raw PL/SQL or stored procedures, validate and bind all inputs. Do not embed identifiers in executable strings:
const proc = `BEGIN user_pkg.get_details(:userId, :result); END;`;
const cursor = await Database.execute(proc, {
userId: authenticatedUser.id,
result: { type: Database.CURSOR }
});
4. Apply strict input validation for path and query parameters. Use AdonisJS schema validation to ensure IDs are integers and conform to expected patterns before they reach Oracle:
import { schema } from '@ioc:Adonis/Core/Validator';
const userSchema = schema.create({
id: schema.number([
schema.unsigned(),
schema.range({ min: 1 })
])
});
export default class UsersController {
public async show({ request, auth, response }) {
const payload = request.validate({ schema: userSchema });
const row = await Database.from('users')
.where('id', payload.id)
.andWhere('owner_id', auth.user.id)
.first();
return response.ok(row);
}
}
5. For multi-tenant or schema-segregated Oracle environments, enforce tenant identification at the connection or query level. Do not rely solely on session context:
const tenantId = this.getUserTenantId(auth.user);
const tenantQuery = `SELECT * FROM ${tenantId}_schema.users WHERE id = :uid`;
// Prefer schema-qualified bind variables over dynamic schema names
const safeTenantQuery = `SELECT * FROM users WHERE tenant_id = :tid AND id = :uid`;
const safeRows = await Database.query(safeTenantQuery, {
tid: tenantId,
uid: userId
});
By combining authenticated scoping, strict validation, and parameterized Oracle binds, developers can close Auth Bypass vectors in AdonisJS applications.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |