Fix BOLA (Broken Object Level Authorization) in NestJS
Generated remediation sketch. GuardAPI the product only gates GET BOLA in CI.
BOLA (Broken Object Level Authorization) is the #1 API threat. In NestJS, it occurs when you trust a route parameter like :id without verifying if the authenticated user (req.user) actually owns that resource. If your service just does findOne(id), you're wide open for horizontal privilege escalation.
The Vulnerable Pattern
@Get(':id')
@UseGuards(JwtAuthGuard)
async getInvoice(@Param('id') id: string) {
// VULNERABILITY: Any authenticated user can fetch any invoice ID.
// No check to see if the invoice belongs to the user.
return this.invoiceService.findOne(id);
}
The Secure Implementation
To kill BOLA in NestJS, you must enforce ownership at the database query level or via a custom Guard/Interceptor. 1. Never trust the ID in the URL. 2. Always extract the requester's identity from the JWT/Session. 3. Scope your SQL/NoSQL queries so they include the owner identifier (e.g., WHERE id = :id AND user_id = :current_user). 4. For complex logic, implement a 'PolicyGuard' or 'CaslAbility' to evaluate permissions before the controller logic executes.
@Get(':id') @UseGuards(JwtAuthGuard) async getInvoice(@Param('id') id: string, @Req() req) { const userId = req.user.id; const invoice = await this.invoiceService.findOne(id);// SECURE: Explicit ownership check if (!invoice || invoice.ownerId !== userId) { throw new ForbiddenException(‘You do not have access to this resource’); }
return invoice; }
// ALTERNATIVE (Scoped Query): // return this.invoiceService.findOne({ where: { id, ownerId: userId } });
Prove it on the next pull request
This page is a generated code sketch, not a GuardAPI scan. After you scope the query by tenant, fail the GitHub job when tenant B can still GET tenant A's object. GET-only. Tokens stay in GitHub Secrets.
- uses: GuardAPI/ghost-api@v6
with:
api-key: ${{ secrets.GUARD_API_KEY }}
openapi-path: ./openapi.json
base-url: ${{ secrets.STAGING_API_URL }}
token-a: ${{ secrets.TOKEN_USER_A }}
token-b: ${{ secrets.TOKEN_USER_B }}
About this page
Framework notes in /guides are generated sketches kept for URL stability. They are not human pentest reports and they are not GuardAPI scan output. The product is a GET-only BOLA merge gate. Maintained by GuardAPI. Questions: support@guard-api.com