Insecure Design in Chi
How Insecure Design Manifests in Chi
Insecure design in Chi APIs often stems from missing or inadequate authorization checks that allow attackers to escalate privileges or access resources they shouldn't have permission to view. A common pattern is the failure to validate user ownership before returning data, creating a classic BOLA (Broken Object Level Authorization) vulnerability.
// Vulnerable Chi route - no authorization check
app.get('/api/users/:id', (req, res) => {
const userId = req.params.id;
db.query('SELECT * FROM users WHERE id = ?', [userId])
.then(user => res.json(user))
.catch(err => res.status(500).json({ error: 'Database error' }));
});
This endpoint returns user data for any ID provided in the URL without verifying that the requesting user actually has permission to view that specific user's information. An authenticated attacker can simply enumerate user IDs to access other users' data.
Another insecure design pattern in Chi applications is the absence of rate limiting on sensitive endpoints. Without proper rate limiting, APIs become vulnerable to brute force attacks, enumeration attacks, and denial of service.
// Vulnerable endpoint - no rate limiting
app.post('/api/login', (req, res) => {
const { email, password } = req.body;
User.authenticate(email, password)
.then(user => {
if (user) {
res.json({ token: generateJWT(user) });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});
});
Attackers can make unlimited login attempts, potentially discovering valid credentials through brute force. The same issue applies to password reset endpoints, account enumeration APIs, and any endpoint that returns different responses based on user existence.
Property-level authorization failures represent another insecure design pattern. APIs often return entire user objects or database records without considering which properties the requester should actually see.
// Vulnerable data exposure
app.get('/api/users/me', (req, res) => {
const userId = req.user.id;
db.query('SELECT * FROM users WHERE id = ?', [userId])
.then(user => res.json(user)) // Returns ALL properties
.catch(err => res.status(500).json({ error: 'Database error' }));
});
This returns sensitive fields like social security numbers, payment information, or internal system data to the authenticated user, when only basic profile information should be exposed.
Chi-Specific Detection
Detecting insecure design patterns in Chi applications requires both manual code review and automated scanning. For manual detection, look for these specific patterns in your Chi route handlers:
// Red flags to search for:
// 1. Direct database queries without authorization checks
app.get('/api/resource/:id', (req, res) => {
const id = req.params.id;
// NO check that req.user can access this resource
db.query('SELECT * FROM resources WHERE id = ?', [id])
.then(data => res.json(data));
});
// 2. Missing authorization middleware
app.use('/api/admin/*', (req, res, next) => {
// NO role-based access control
next();
});
// 3. Direct object returns without filtering
app.get('/api/profile', (req, res) => {
res.json(req.user); // Returns entire user object
});
Automated detection with middleBrick can identify these insecure design patterns through black-box scanning. The scanner tests for missing authorization by attempting to access resources with different user contexts and checking if access controls are properly enforced.
middleBrick's BOLA/IDOR checks specifically target Chi applications by:
- Testing if authenticated users can access other users' resources by manipulating IDs in URLs
- Checking if different privilege levels can access restricted endpoints
- Verifying that object ownership is properly validated before data exposure
- Scanning for missing rate limiting on authentication and sensitive endpoints
- Detecting property-level authorization failures where too much data is returned
The scanner provides specific findings with severity levels and remediation guidance tailored to Chi's routing patterns and middleware architecture.
Chi-Specific Remediation
Remediating insecure design in Chi applications requires implementing proper authorization checks and data filtering. Here are Chi-specific fixes for common vulnerabilities:
// Fix 1: Add authorization middleware
const authorizeResource = (req, res, next) => {
const resourceId = req.params.id;
const userId = req.user.id;
// Check if user owns this resource
db.query('SELECT owner_id FROM resources WHERE id = ?', [resourceId])
.then(resource => {
if (!resource || resource.owner_id !== userId) {
return res.status(403).json({ error: 'Access denied' });
}
next();
})
.catch(err => res.status(500).json({ error: 'Database error' }));
};
// Apply middleware to protected routes
app.get('/api/resources/:id', authorizeResource, (req, res) => {
const id = req.params.id;
db.query('SELECT * FROM resources WHERE id = ?', [id])
.then(resource => res.json(resource))
.catch(err => res.status(500).json({ error: 'Database error' }));
});
For role-based access control in Chi applications, create reusable middleware:
// Fix 2: Role-based authorization middleware
const requireRole = (role) => {
return (req, res, next) => {
if (!req.user || req.user.role !== role) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
};
// Protect admin routes
app.get('/api/admin/*', requireRole('admin'), (req, res) => {
res.json({ message: 'Admin dashboard' });
});
Property-level authorization requires filtering sensitive data before sending responses:
// Fix 3: Data filtering and property authorization
app.get('/api/users/me', (req, res) => {
const userId = req.user.id;
db.query('SELECT * FROM users WHERE id = ?', [userId])
.then(user => {
// Filter sensitive properties
const safeUser = {
id: user.id,
name: user.name,
email: user.email,
created_at: user.created_at
};
res.json(safeUser);
})
.catch(err => res.status(500).json({ error: 'Database error' }));
});
Rate limiting can be implemented using middleware like express-rate-limit:
// Fix 4: Rate limiting for sensitive endpoints
const rateLimit = require('express-rate-limit');
// Login attempts limiter
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each IP to 5 requests per windowMs
message: 'Too many login attempts, please try again later'
});
// Apply to login route
app.post('/api/login', loginLimiter, (req, res) => {
// Login logic here
});
For comprehensive security, integrate middleBrick into your Chi development workflow using the CLI or GitHub Action to catch insecure design patterns before deployment:
# Scan your Chi API endpoints
middlebrick scan https://api.yourdomain.com
# Or add to GitHub Actions
- name: Scan API Security
uses: middleBrick/middleBrick@v1
with:
url: https://api.yourdomain.com
fail-on-severity: high