Fix Business Logic Errors in Fastify
Business logic errors are the 'logic bombs' of the application layer. Unlike syntax errors or memory leaks, these vulnerabilities occur when the application's flow is manipulated to perform actions not intended by the developer. In the Fastify ecosystem, this frequently manifests as Broken Object Level Authorization (BOLA) or state-machine bypasses where users manipulate IDs or status fields to gain unauthorized access or skip payment steps.
The Vulnerable Pattern
fastify.patch('/api/orders/:orderId', async (request, reply) => { const { orderId } = request.params; const { status } = request.body;// VULNERABILITY: This code trusts the orderId and status implicitly. // An attacker can change any orderId to ‘delivered’ or ‘cancelled’ without owning it. const order = await db.orders.update({ id: orderId }).set({ status });
return { success: true, order }; });
The Secure Implementation
The fix implements two critical security layers. First, it enforces Resource Ownership by including the authenticated 'userId' in the database query, ensuring users can only modify their own data. Second, it implements a State Machine validation. By defining 'validTransitions', we prevent an attacker from manually setting an order status to 'SHIPPED' or 'REFUNDED' without going through the proper payment or administrative workflows. In Fastify, always use 'preHandler' hooks to verify identity and keep your business logic strictly governed by server-side state, never client-side claims.
fastify.patch('/api/orders/:orderId', { preHandler: [fastify.authenticate] }, async (request, reply) => { const { orderId } = request.params; const { status } = request.body; const userId = request.user.id;// FIX 1: Verify Ownership (Prevent IDOR/BOLA) const order = await db.orders.findOne({ id: orderId, ownerId: userId }); if (!order) { return reply.code(404).send({ error: ‘Order not found or unauthorized’ }); }
// FIX 2: Enforce State Machine (Prevent Logic Bypass) const validTransitions = { ‘PENDING’: [‘CANCELLED’, ‘PAID’], ‘PAID’: [‘SHIPPED’] }; if (!validTransitions[order.status].includes(status)) { return reply.code(400).send({ error: ‘Invalid status transition’ }); }
const updatedOrder = await db.orders.update({ id: orderId }).set({ status }); return { success: true, updatedOrder }; });
Your Fastify API
might be exposed to Business Logic Errors
74% of Fastify apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.