// scan results
scan-2843
Completedhttps://github.com/acme-corp/web-platform • main
8
Total
2
Critical
2
High
2
Medium
2
Low
SQL Injection in User Authentication
User input is directly concatenated into SQL query without parameterization, allowing attackers to bypass authentication or extract database contents.
Vulnerable Code
const query = `SELECT * FROM users WHERE email = '${email}' AND password = '${password}'`;
const result = await db.execute(query);Suggested Fix
const query = 'SELECT * FROM users WHERE email = ? AND password = ?'; const result = await db.execute(query, [email, hashedPassword]);
Hardcoded API Secret Key
Production API secret key is hardcoded in source code. If the repository is public or compromised, attackers gain full API access.
Vulnerable Code
const API_SECRET = "sk_live_a1b2c3d4e5f6g7h8i9j0";
Suggested Fix
const API_SECRET = process.env.API_SECRET_KEY;
if (!API_SECRET) throw new Error("API_SECRET_KEY not configured");Cross-Site Scripting (XSS) via innerHTML
User-supplied content is rendered using dangerouslySetInnerHTML without sanitization, enabling stored XSS attacks.
Vulnerable Code
<div dangerouslySetInnerHTML={{ __html: comment.body }} />Suggested Fix
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(comment.body) }} />Path Traversal in File Download
The file download endpoint does not validate the requested path, allowing attackers to read arbitrary files from the server filesystem.
Vulnerable Code
const filePath = path.join('/uploads', req.query.filename);
const file = fs.readFileSync(filePath);
res.send(file);Suggested Fix
const filename = path.basename(req.query.filename); // Strip directory traversal
const filePath = path.join('/uploads', filename);
if (!filePath.startsWith('/uploads/')) {
return res.status(403).send('Forbidden');
}
const file = fs.readFileSync(filePath);
res.send(file);Missing Rate Limiting on Login Endpoint
The login endpoint has no rate limiting, making it vulnerable to brute-force password attacks.
Vulnerable Code
export async function POST(req: Request) {
const { email, password } = await req.json();Suggested Fix
import { rateLimit } from '@/lib/rate-limit';
const limiter = rateLimit({ interval: 60_000, uniqueTokenPerInterval: 500 });
export async function POST(req: Request) {
await limiter.check(req, 5); // 5 attempts per minute
const { email, password } = await req.json();Insecure Cookie Configuration
Session cookies are set without Secure, HttpOnly, and SameSite flags, making them vulnerable to interception and CSRF attacks.
Vulnerable Code
res.setHeader('Set-Cookie', `session=${token}; Path=/`);Suggested Fix
res.setHeader('Set-Cookie', `session=${token}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=86400`);Verbose Error Messages in Production
Stack traces and internal error details are exposed to clients in production, potentially revealing system architecture.
Vulnerable Code
res.status(500).json({
error: err.message,
stack: err.stack,
});Suggested Fix
const isDev = process.env.NODE_ENV === 'development';
res.status(500).json({
error: isDev ? err.message : 'Internal server error',
...(isDev && { stack: err.stack }),
});Missing Content-Security-Policy Header
No CSP header is configured, increasing the risk of XSS and data injection attacks.
Vulnerable Code
const nextConfig = {};
export default nextConfig;Suggested Fix
const nextConfig = {
headers: async () => [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-inline';"
}]
}]
};
export default nextConfig;