

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345# JavaScript Insecure Design (OWASP A04:2021)67<rule>8name: javascript_insecure_design9description: Detect and prevent insecure design patterns in JavaScript applications as defined in OWASP Top 10:2021-A041011actions:12 - type: enforce13 conditions:14 # Pattern 1: Lack of Rate Limiting15 - pattern: "app\\.(?:get|post|put|delete|patch)\\([^)]*?\\)\\s*(?!.*(?:rateLimiter|limiter|throttle|rateLimit))"16 location: "(?:routes|api|controllers)"17 message: "Potential lack of rate limiting in API endpoint. Consider implementing rate limiting to prevent abuse."1819 # Pattern 2: Insecure Direct Object Reference (IDOR)20 - pattern: "(?:findById|getById|findOne)\\([^)]*?(?:req\\.|request\\.|params\\.|query\\.|body\\.|user\\.|input\\.|form\\.)[^)]*?\\)\\s*(?!.*(?:authorization|permission|access|canAccess|isAuthorized|checkPermission))"21 location: "(?:routes|api|controllers)"22 message: "Potential Insecure Direct Object Reference (IDOR) vulnerability. Implement proper authorization checks before accessing objects by ID."2324 # Pattern 3: Lack of Input Validation25 - pattern: "(?:req\\.|request\\.|params\\.|query\\.|body\\.|user\\.|input\\.|form\\.)[a-zA-Z0-9_]+\\s*(?!.*(?:validate|sanitize|check|schema|joi|yup|zod|validator|isValid))"26 location: "(?:routes|api|controllers)"27 message: "Potential lack of input validation. Implement proper validation for all user inputs."2829 # Pattern 4: Hardcoded Business Logic30 - pattern: "if\\s*\\([^)]*?(?:role\\s*===\\s*['\"]admin['\"]|isAdmin\\s*===\\s*true|user\\.role\\s*===\\s*['\"]admin['\"])\\s*\\)"31 message: "Hardcoded business logic for authorization. Consider using a more flexible role-based access control system."3233 # Pattern 5: Lack of Proper Error Handling34 - pattern: "catch\\s*\\([^)]*?\\)\\s*\\{[^}]*?(?:console\\.(?:log|error))[^}]*?\\}"35 negative_pattern: "(?:res\\.status|next\\(err|next\\(error|errorHandler)"36 message: "Improper error handling. Avoid only logging errors without proper handling or user feedback."3738 # Pattern 6: Insecure Authentication Design39 - pattern: "(?:password|token|secret|key)\\s*===\\s*(?:req\\.|request\\.|params\\.|query\\.|body\\.|user\\.|input\\.|form\\.)"40 message: "Insecure authentication design. Avoid direct string comparison for passwords or tokens."4142 # Pattern 7: Lack of Proper Logging43 - pattern: "app\\.(?:get|post|put|delete|patch)\\([^)]*?\\)\\s*(?!.*(?:log|logger|winston|bunyan|morgan|audit))"44 location: "(?:routes|api|controllers)"45 message: "Lack of proper logging in API endpoint. Implement logging for security-relevant events."4647 # Pattern 8: Insecure Defaults48 - pattern: "new\\s+(?:Session|Cookie|JWT)\\([^)]*?\\{[^}]*?(?:secure\\s*:\\s*false|httpOnly\\s*:\\s*false|sameSite\\s*:\\s*['\"]none['\"])"49 message: "Insecure default configuration. Avoid setting secure:false, httpOnly:false, or sameSite:'none' for cookies or sessions."5051 # Pattern 9: Lack of Proper Access Control52 - pattern: "router\\.(?:get|post|put|delete|patch)\\([^)]*?\\)\\s*(?!.*(?:authenticate|authorize|requireAuth|isAuthenticated|checkAuth|verifyToken|passport\\.authenticate))"53 location: "(?:routes|api|controllers)"54 message: "Potential lack of access control in route definition. Implement proper authentication and authorization middleware."5556 # Pattern 10: Insecure File Operations57 - pattern: "(?:fs\\.(?:readFile|writeFile|appendFile|readdir|stat|access|open|unlink)|require)\\([^)]*?(?:(?:\\+|\\$\\{|\\`)[^)]*?(?:__dirname|__filename|process\\.cwd\\(\\)|path\\.(?:resolve|join)))"58 negative_pattern: "path\\.normalize|path\\.resolve|path\\.join"59 message: "Insecure file operations. Use path.normalize() and validate file paths to prevent directory traversal attacks."6061 # Pattern 11: Lack of Proper Secrets Management62 - pattern: "(?:apiKey|secret|password|token|credentials)\\s*=\\s*(?:process\\.env\\.[A-Z_]+|config\\.[a-zA-Z0-9_]+|['\"][^'\"]+['\"])"63 negative_pattern: "(?:vault|secretsManager|keyVault|secretClient)"64 message: "Insecure secrets management. Consider using a dedicated secrets management solution instead of environment variables or configuration files."6566 # Pattern 12: Insecure Randomness67 - pattern: "Math\\.random\\(\\)"68 location: "(?:auth|security|token|password|key|iv|nonce|salt)"69 message: "Insecure randomness. Use crypto.randomBytes() or a similar cryptographically secure random number generator for security-sensitive operations."7071 # Pattern 13: Lack of Proper Input Sanitization for Templates72 - pattern: "(?:template|render|compile|ejs\\.render|handlebars\\.compile|pug\\.render)\\([^)]*?(?:(?:\\+|\\$\\{|\\`)[^)]*?(?:req\\.|request\\.|params\\.|query\\.|body\\.|user\\.|input\\.|form\\.))"73 message: "Potential template injection vulnerability. Sanitize user input before using in templates."7475 # Pattern 14: Insecure WebSocket Implementation76 - pattern: "new\\s+WebSocket\\([^)]*?\\)|io\\.on\\(['\"]connection['\"]"77 negative_pattern: "(?:authenticate|authorize|verifyClient|beforeConnect)"78 message: "Potentially insecure WebSocket implementation. Implement proper authentication and authorization for WebSocket connections."7980 # Pattern 15: Insecure Cross-Origin Resource Sharing (CORS)81 - pattern: "(?:cors\\(\\{[^}]*?origin\\s*:\\s*['\"]\\*['\"]|app\\.use\\(cors\\(\\{[^}]*?origin\\s*:\\s*['\"]\\*['\"])"82 message: "Insecure CORS configuration. Avoid using wildcard (*) for CORS origin in production environments."8384 - type: suggest85 message: |86 **JavaScript Secure Design Best Practices:**8788 1. **Defense in Depth Strategy:**89 - Implement multiple layers of security controls90 - Don't rely on a single security mechanism91 - Example:92```javascript93 // Multiple layers of protection94 app.use(helmet()); // HTTP security headers95 app.use(rateLimit()); // Rate limiting96 app.use(cors({ origin: allowedOrigins })); // Restricted CORS97 app.use(express.json({ limit: '10kb' })); // Request size limiting98 app.use(sanitize()); // Input sanitization99```100101 2. **Proper Access Control:**102 - Implement role-based access control (RBAC)103 - Use middleware for authorization checks104 - Example:105```javascript106 // Role-based middleware107 const requireRole = (role) => {108 return (req, res, next) => {109 if (!req.user) {110 return res.status(401).json({ error: 'Unauthorized' });111 }112113 if (req.user.role !== role) {114 return res.status(403).json({ error: 'Forbidden' });115 }116117 next();118 };119 };120121 // Apply to routes122 router.get('/admin/users',123 authenticate,124 requireRole('admin'),125 adminController.listUsers126 );127```128129 3. **Rate Limiting:**130 - Implement rate limiting for all API endpoints131 - Use different limits for different endpoints based on sensitivity132 - Example:133```javascript134 const rateLimit = require('express-rate-limit');135136 // General API rate limit137 const apiLimiter = rateLimit({138 windowMs: 15 * 60 * 1000, // 15 minutes139 max: 100, // limit each IP to 100 requests per windowMs140 standardHeaders: true,141 legacyHeaders: false,142 });143144 // More strict limit for authentication endpoints145 const authLimiter = rateLimit({146 windowMs: 15 * 60 * 1000,147 max: 5, // limit each IP to 5 login attempts per windowMs148 standardHeaders: true,149 legacyHeaders: false,150 });151152 // Apply rate limiters153 app.use('/api/', apiLimiter);154 app.use('/api/auth/', authLimiter);155```156157 4. **Input Validation:**158 - Validate all user inputs using schema validation159 - Implement both client and server-side validation160 - Example:161```javascript162 const Joi = require('joi');163164 // Define validation schema165 const userSchema = Joi.object({166 username: Joi.string().alphanum().min(3).max(30).required(),167 email: Joi.string().email().required(),168 password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{8,30}$')).required(),169 role: Joi.string().valid('user', 'admin').default('user')170 });171172 // Validation middleware173 const validateUser = (req, res, next) => {174 const { error } = userSchema.validate(req.body);175 if (error) {176 return res.status(400).json({ error: error.details[0].message });177 }178 next();179 };180181 // Apply validation182 router.post('/users', validateUser, userController.create);183```184185 5. **Proper Error Handling:**186 - Implement centralized error handling187 - Avoid exposing sensitive information in error messages188 - Example:189```javascript190 // Centralized error handler191 app.use((err, req, res, next) => {192 // Log error for internal use193 console.error(err.stack);194195 // Send appropriate response to client196 const statusCode = err.statusCode || 500;197 res.status(statusCode).json({198 status: 'error',199 message: statusCode === 500 ? 'Internal server error' : err.message200 });201 });202203 // Custom error class204 class AppError extends Error {205 constructor(message, statusCode) {206 super(message);207 this.statusCode = statusCode;208 this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';209 this.isOperational = true;210211 Error.captureStackTrace(this, this.constructor);212 }213 }214215 // Usage in controllers216 if (!user) {217 return next(new AppError('User not found', 404));218 }219```220221 6. **Secure Authentication Design:**222 - Use secure password hashing (bcrypt, Argon2)223 - Implement proper session management224 - Use secure token validation225 - Example:226```javascript227 const bcrypt = require('bcrypt');228 const jwt = require('jsonwebtoken');229230 // Password hashing231 const hashPassword = async (password) => {232 const salt = await bcrypt.genSalt(12);233 return bcrypt.hash(password, salt);234 };235236 // Password verification237 const verifyPassword = async (password, hashedPassword) => {238 return await bcrypt.compare(password, hashedPassword);239 };240241 // Token generation242 const generateToken = (userId) => {243 return jwt.sign(244 { id: userId },245 process.env.JWT_SECRET,246 { expiresIn: '1h' }247 );248 };249250 // Token verification middleware251 const verifyToken = (req, res, next) => {252 const token = req.headers.authorization?.split(' ')[1];253254 if (!token) {255 return res.status(401).json({ error: 'No token provided' });256 }257258 try {259 const decoded = jwt.verify(token, process.env.JWT_SECRET);260 req.userId = decoded.id;261 next();262 } catch (error) {263 return res.status(401).json({ error: 'Invalid token' });264 }265 };266```267268 7. **Comprehensive Logging:**269 - Log security-relevant events270 - Include necessary context but avoid sensitive data271 - Use structured logging272 - Example:273```javascript274 const winston = require('winston');275276 // Create logger277 const logger = winston.createLogger({278 level: 'info',279 format: winston.format.json(),280 defaultMeta: { service: 'user-service' },281 transports: [282 new winston.transports.File({ filename: 'error.log', level: 'error' }),283 new winston.transports.File({ filename: 'combined.log' })284 ]285 });286287 // Logging middleware288 app.use((req, res, next) => {289 const start = Date.now();290291 res.on('finish', () => {292 const duration = Date.now() - start;293 logger.info({294 method: req.method,295 path: req.path,296 statusCode: res.statusCode,297 duration,298 ip: req.ip,299 userId: req.user?.id || 'anonymous'300 });301 });302303 next();304 });305306 // Security event logging307 logger.warn({308 event: 'failed_login',309 username: req.body.username,310 ip: req.ip,311 timestamp: new Date().toISOString()312 });313```314315 8. **Secure Configuration Management:**316 - Use environment-specific configurations317 - Validate configuration at startup318 - Example:319```javascript320 const Joi = require('joi');321322 // Define environment variables schema323 const envSchema = Joi.object({324 NODE_ENV: Joi.string().valid('development', 'production', 'test').required(),325 PORT: Joi.number().default(3000),326 DATABASE_URL: Joi.string().required(),327 JWT_SECRET: Joi.string().min(32).required(),328 JWT_EXPIRES_IN: Joi.string().default('1h'),329 CORS_ORIGIN: Joi.string().required()330 }).unknown();331332 // Validate environment variables333 const { error, value } = envSchema.validate(process.env);334335 if (error) {336 throw new Error(`Configuration validation error: ${error.message}`);337 }338339 // Use validated config340 const config = {341 env: value.NODE_ENV,342 port: value.PORT,343 db: {344 url: value.DATABASE_URL345 },346 jwt: {347 secret: value.JWT_SECRET,348 expiresIn: value.JWT_EXPIRES_IN349 },350 cors: {351 origin: value.CORS_ORIGIN.split(',')352 }353 };354355 module.exports = config;356```357358 9. **Secure File Operations:**359 - Validate and sanitize file paths360 - Use content-type validation for uploads361 - Implement file size limits362 - Example:363```javascript364 const path = require('path');365 const fs = require('fs');366367 // Secure file access function368 const getSecureFilePath = (userInput) => {369 // Define allowed directory370 const baseDir = path.resolve(__dirname, '../public/files');371372 // Normalize and resolve full path373 const normalizedPath = path.normalize(userInput);374 const fullPath = path.join(baseDir, normalizedPath);375376 // Ensure path is within allowed directory377 if (!fullPath.startsWith(baseDir)) {378 throw new Error('Invalid file path');379 }380381 return fullPath;382 };383384 // Usage385 try {386 const filePath = getSecureFilePath(req.params.filename);387 const fileContent = fs.readFileSync(filePath, 'utf8');388 res.send(fileContent);389 } catch (error) {390 next(error);391 }392```393394 10. **Secure WebSocket Implementation:**395 - Implement authentication for WebSocket connections396 - Validate and sanitize WebSocket messages397 - Example:398```javascript399 const http = require('http');400 const socketIo = require('socket.io');401 const jwt = require('jsonwebtoken');402403 const server = http.createServer(app);404 const io = socketIo(server);405406 // WebSocket authentication middleware407 io.use((socket, next) => {408 const token = socket.handshake.auth.token;409410 if (!token) {411 return next(new Error('Authentication error'));412 }413414 try {415 const decoded = jwt.verify(token, process.env.JWT_SECRET);416 socket.userId = decoded.id;417 next();418 } catch (error) {419 return next(new Error('Authentication error'));420 }421 });422423 io.on('connection', (socket) => {424 console.log(`User ${socket.userId} connected`);425426 // Join user to their own room for private messages427 socket.join(`user:${socket.userId}`);428429 // Message validation430 socket.on('message', (data) => {431 // Validate message data432 if (!data || !data.content || typeof data.content !== 'string') {433 return socket.emit('error', { message: 'Invalid message format' });434 }435436 // Process message437 // ...438 });439 });440```441442 - type: validate443 conditions:444 # Check 1: Rate limiting implementation445 - pattern: "(?:rateLimit|rateLimiter|limiter|throttle)\\([^)]*?\\)"446 message: "Implementing rate limiting for API protection."447448 # Check 2: Input validation449 - pattern: "(?:validate|sanitize|check|schema|joi|yup|zod|validator|isValid)"450 message: "Using input validation or schema validation."451452 # Check 3: Proper error handling453 - pattern: "(?:try\\s*\\{[^}]*?\\}\\s*catch\\s*\\([^)]*?\\)\\s*\\{[^}]*?(?:res\\.status|next\\(err|next\\(error|errorHandler))"454 message: "Implementing proper error handling."455456 # Check 4: Authentication middleware457 - pattern: "(?:authenticate|authorize|requireAuth|isAuthenticated|checkAuth|verifyToken|passport\\.authenticate)"458 message: "Using authentication middleware for routes."459460 # Check 5: Secure configuration461 - pattern: "(?:helmet|cors\\(\\{[^}]*?origin\\s*:\\s*(?!['\"]*\\*)['\"])"462 message: "Using secure HTTP headers and CORS configuration."463464metadata:465 priority: high466 version: 1.0467 tags:468 - security469 - javascript470 - nodejs471 - browser472 - design473 - owasp474 - language:javascript475 - framework:express476 - framework:react477 - framework:vue478 - framework:angular479 - category:security480 - subcategory:insecure-design481 - standard:owasp-top10482 - risk:a04-insecure-design483 references:484 - "https://owasp.org/Top10/A04_2021-Insecure_Design/"485 - "https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html"486 - "https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html"487 - "https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html"488 - "https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html"489 - "https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html"490 - "https://github.com/OWASP/NodeGoat"491</rule>492
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| ivangrynenko/cursorrules.cursor/rules/cursor-rules.mdc · 86 | Cursor rules | teststylearchgit+2 | 77/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/behat-steps.mdc · 86 | Cursor rules | lint-formatstyleperformanceagent-behaviour | 42/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/php-drupal-development-standards.mdc · 86 | Cursor rules | no sections | 34/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-insecure-design.mdc · 86 | Cursor rules | no sections | 40/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-cryptographic-failures.mdc · 86 | Cursor rules | security | 40/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-injection.mdc · 86 | Cursor rules | styledo-not | 51/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/node-dependencies.mdc · 86 | Cursor rules | no sections | 16/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/behat-ai-guide.mdc · 86 | Cursor rules | testtesting-strategydo-not | 45/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/new-pull-request.mdc · 86 | Cursor rules | archtesting-strategygitsecurity+3 | 58/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/accessibility-standards.mdc · 86 | Cursor rules | ui | 44/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/api-standards.mdc · 86 | Cursor rules | api | 44/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/build-optimization.mdc · 86 | Cursor rules | build | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/code-generation-standards.mdc · 86 | Cursor rules | lint-formatstyletypesdocs | 52/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/confluence-editing-standards.mdc · 86 | Cursor rules | stylearchsecuritydeployment | 60/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/debugging-standards.mdc · 86 | Cursor rules | no sections | 30/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/docker-compose-standards.mdc · 86 | Cursor rules | style | 62/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-authentication-failures.mdc · 86 | Cursor rules | security | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-broken-access-control.mdc · 86 | Cursor rules | stylesecurity | 52/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-cryptographic-failures.mdc · 86 | Cursor rules | security | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-database-standards.mdc · 86 | Cursor rules | database | 30/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4k | Cursor rules | teststylearchtypes+2 | 96/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-user-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 14 days ago | |
| hiromaily/go-crypto-wallet.cursor/rules/proto.mdc · 126 | Cursor rules | buildlint-formatstylearch+3 | 96/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/ivangrynenko-cursorrules-cursor-rules-javascript-insecure-design)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.