

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345# JavaScript Security Misconfiguration (OWASP A05:2021)67<rule>8name: javascript_security_misconfiguration9description: Detect and prevent security misconfigurations in JavaScript applications as defined in OWASP Top 10:2021-A051011actions:12 - type: enforce13 conditions:14 # Pattern 1: Missing or Insecure HTTP Security Headers15 - pattern: "app\\.use\\([^)]*?\\)\\s*(?!.*(?:helmet|frameguard|hsts|noSniff|xssFilter|contentSecurityPolicy))"16 location: "(?:app|server|index)\\.(?:js|ts)$"17 message: "Missing HTTP security headers. Consider using Helmet.js to set secure HTTP headers."1819 # Pattern 2: Insecure CORS Configuration20 - pattern: "app\\.use\\(cors\\(\\{[^}]*?origin\\s*:\\s*['\"]\\*['\"]\\s*\\}\\)\\)"21 message: "Insecure CORS configuration. Avoid using wildcard (*) for CORS origin in production environments."2223 # Pattern 3: Exposed Environment Variables in Client-Side Code24 - pattern: "process\\.env\\.[A-Z_]+"25 location: "(?:src|components|pages)"26 message: "Exposing environment variables in client-side code. Only use environment variables with NEXT_PUBLIC_, REACT_APP_, or VITE_ prefixes for client-side code."2728 # Pattern 4: Insecure Cookie Settings29 - pattern: "(?:cookie|cookies|session)\\([^)]*?\\{[^}]*?(?:secure\\s*:\\s*false|httpOnly\\s*:\\s*false|sameSite\\s*:\\s*['\"]none['\"])"30 message: "Insecure cookie configuration. Set secure:true, httpOnly:true, and appropriate sameSite value for cookies."3132 # Pattern 5: Missing Content Security Policy33 - pattern: "app\\.use\\([^)]*?helmet\\([^)]*?\\{[^}]*?contentSecurityPolicy\\s*:\\s*false"34 message: "Content Security Policy (CSP) is disabled. Enable and configure CSP to prevent XSS attacks."3536 # Pattern 6: Debug Information Exposure37 - pattern: "app\\.use\\([^)]*?morgan\\(['\"]dev['\"]\\)|console\\.(?:log|debug|info|warn|error)\\("38 location: "(?:app|server|index)\\.(?:js|ts)$"39 message: "Debug information might be exposed in production. Ensure logging is properly configured based on the environment."4041 # Pattern 7: Insecure Server Configuration42 - pattern: "app\\.disable\\(['\"]x-powered-by['\"]\\)"43 negative_pattern: true44 location: "(?:app|server|index)\\.(?:js|ts)$"45 message: "X-Powered-By header is not disabled. Use app.disable('x-powered-by') to hide technology information."4647 # Pattern 8: Directory Listing Enabled48 - pattern: "express\\.static\\([^)]*?\\{[^}]*?index\\s*:\\s*false"49 message: "Directory listing might be enabled. Set index:true or provide an index file to prevent directory listing."5051 # Pattern 9: Missing Rate Limiting52 - pattern: "app\\.(?:get|post|put|delete|patch)\\([^)]*?['\"](?:/api|/login|/register|/auth)['\"]"53 negative_pattern: "(?:rateLimit|rateLimiter|limiter|throttle)"54 message: "Missing rate limiting for sensitive endpoints. Implement rate limiting to prevent brute force attacks."5556 # Pattern 10: Insecure WebSocket Configuration57 - pattern: "new\\s+WebSocket\\([^)]*?\\)|io\\.on\\(['\"]connection['\"]"58 negative_pattern: "(?:wss://|https://)"59 message: "Potentially insecure WebSocket connection. Use secure WebSocket (wss://) in production."6061 # Pattern 11: Hardcoded Configuration Values62 - pattern: "(?:apiKey|secret|password|token|credentials)\\s*=\\s*['\"][^'\"]+['\"]"63 message: "Hardcoded configuration values. Use environment variables or a secure configuration management system."6465 # Pattern 12: Insecure SSL/TLS Configuration66 - pattern: "https\\.createServer\\([^)]*?\\{[^}]*?rejectUnauthorized\\s*:\\s*false"67 message: "Insecure SSL/TLS configuration. Never set rejectUnauthorized:false in production."6869 # Pattern 13: Missing Security Middleware70 - pattern: "express\\(\\)|require\\(['\"]express['\"]\\)"71 negative_pattern: "(?:helmet|cors|rateLimit|bodyParser\\.json\\(\\{\\s*limit|express\\.json\\(\\{\\s*limit)"72 location: "(?:app|server|index)\\.(?:js|ts)$"73 message: "Missing essential security middleware. Consider using helmet, cors, rate limiting, and request size limiting."7475 # Pattern 14: Insecure Error Handling76 - pattern: "app\\.use\\([^)]*?function\\s*\\([^)]*?err[^)]*?\\)\\s*\\{[^}]*?res\\.status[^}]*?err(?:\\.message|\\.stack)"77 message: "Insecure error handling. Avoid exposing error details like stack traces to clients in production."7879 # Pattern 15: Outdated Dependencies Warning80 - pattern: "(?:\"dependencies\"|\"devDependencies\")\\s*:\\s*\\{[^}]*?['\"](?:express|react|vue|angular|next|nuxt|axios)['\"]\\s*:\\s*['\"]\\^?\\d+\\.\\d+\\.\\d+['\"]"81 location: "package\\.json$"82 message: "Check for outdated dependencies. Regularly update dependencies to avoid known vulnerabilities."8384 - type: suggest85 message: |86 **JavaScript Security Configuration Best Practices:**8788 1. **HTTP Security Headers:**89 - Use Helmet.js to set secure HTTP headers90 - Configure Content Security Policy (CSP)91 - Example:92```javascript93 const helmet = require('helmet');9495 // Basic usage96 app.use(helmet());9798 // Custom CSP configuration99 app.use(100 helmet.contentSecurityPolicy({101 directives: {102 defaultSrc: ["'self'"],103 scriptSrc: ["'self'", "'unsafe-inline'", 'trusted-cdn.com'],104 styleSrc: ["'self'", "'unsafe-inline'", 'trusted-cdn.com'],105 imgSrc: ["'self'", 'data:', 'trusted-cdn.com'],106 connectSrc: ["'self'", 'api.yourdomain.com'],107 fontSrc: ["'self'", 'trusted-cdn.com'],108 objectSrc: ["'none'"],109 mediaSrc: ["'self'"],110 frameSrc: ["'none'"],111 upgradeInsecureRequests: [],112 },113 })114 );115```116117 2. **Secure CORS Configuration:**118 - Specify allowed origins explicitly119 - Configure appropriate CORS options120 - Example:121```javascript122 const cors = require('cors');123124 // Define allowed origins125 const allowedOrigins = [126 'https://yourdomain.com',127 'https://app.yourdomain.com',128 'https://admin.yourdomain.com'129 ];130131 // Configure CORS132 app.use(cors({133 origin: function(origin, callback) {134 // Allow requests with no origin (like mobile apps, curl, etc.)135 if (!origin) return callback(null, true);136137 if (allowedOrigins.indexOf(origin) === -1) {138 const msg = 'The CORS policy for this site does not allow access from the specified Origin.';139 return callback(new Error(msg), false);140 }141142 return callback(null, true);143 },144 methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],145 credentials: true,146 maxAge: 86400 // 24 hours147 }));148```149150 3. **Environment-Based Configuration:**151 - Use different configurations for development and production152 - Validate configuration at startup153 - Example:154```javascript155 const express = require('express');156 const helmet = require('helmet');157 const morgan = require('morgan');158159 const app = express();160161 // Environment-specific configuration162 if (process.env.NODE_ENV === 'production') {163 // Production settings164 app.use(helmet());165 app.use(morgan('combined'));166 app.set('trust proxy', 1); // Trust first proxy167168 // Disable X-Powered-By header169 app.disable('x-powered-by');170 } else {171 // Development settings172 app.use(morgan('dev'));173 }174175 // Validate required environment variables176 const requiredEnvVars = ['DATABASE_URL', 'JWT_SECRET'];177 for (const envVar of requiredEnvVars) {178 if (!process.env[envVar]) {179 console.error(`Error: Environment variable ${envVar} is required`);180 process.exit(1);181 }182 }183```184185 4. **Secure Cookie Configuration:**186 - Set secure, httpOnly, and sameSite attributes187 - Use signed cookies when appropriate188 - Example:189```javascript190 const session = require('express-session');191192 app.use(session({193 secret: process.env.SESSION_SECRET,194 name: 'sessionId', // Custom cookie name instead of default195 cookie: {196 secure: process.env.NODE_ENV === 'production', // HTTPS only in production197 httpOnly: true, // Prevents client-side JS from reading the cookie198 sameSite: 'lax', // Controls when cookies are sent with cross-site requests199 maxAge: 3600000, // 1 hour in milliseconds200 domain: process.env.NODE_ENV === 'production' ? '.yourdomain.com' : undefined201 },202 resave: false,203 saveUninitialized: false204 }));205```206207 5. **Request Size Limiting:**208 - Limit request body size to prevent DoS attacks209 - Example:210```javascript211 // Using express built-in middleware212 app.use(express.json({ limit: '10kb' }));213 app.use(express.urlencoded({ extended: true, limit: '10kb' }));214215 // Or using body-parser216 const bodyParser = require('body-parser');217 app.use(bodyParser.json({ limit: '10kb' }));218 app.use(bodyParser.urlencoded({ extended: true, limit: '10kb' }));219```220221 6. **Proper Error Handling:**222 - Use a centralized error handler223 - Don't expose sensitive information in error responses224 - Example:225```javascript226 // Custom error class227 class AppError extends Error {228 constructor(message, statusCode) {229 super(message);230 this.statusCode = statusCode;231 this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';232 this.isOperational = true;233234 Error.captureStackTrace(this, this.constructor);235 }236 }237238 // Global error handling middleware239 app.use((err, req, res, next) => {240 err.statusCode = err.statusCode || 500;241 err.status = err.status || 'error';242243 // Different handling for development and production244 if (process.env.NODE_ENV === 'development') {245 res.status(err.statusCode).json({246 status: err.status,247 error: err,248 message: err.message,249 stack: err.stack250 });251 } else if (process.env.NODE_ENV === 'production') {252 // Only send operational errors to the client253 if (err.isOperational) {254 res.status(err.statusCode).json({255 status: err.status,256 message: err.message257 });258 } else {259 // Log programming or unknown errors260 console.error('ERROR 💥', err);261262 // Send generic message263 res.status(500).json({264 status: 'error',265 message: 'Something went wrong'266 });267 }268 }269 });270```271272 7. **Rate Limiting:**273 - Apply rate limiting to sensitive endpoints274 - Use different limits for different endpoints275 - Example:276```javascript277 const rateLimit = require('express-rate-limit');278279 // Create a rate limiter for API endpoints280 const apiLimiter = rateLimit({281 windowMs: 15 * 60 * 1000, // 15 minutes282 max: 100, // limit each IP to 100 requests per windowMs283 standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers284 legacyHeaders: false, // Disable the `X-RateLimit-*` headers285 message: 'Too many requests from this IP, please try again after 15 minutes'286 });287288 // Create a stricter rate limiter for authentication endpoints289 const authLimiter = rateLimit({290 windowMs: 15 * 60 * 1000, // 15 minutes291 max: 5, // limit each IP to 5 login attempts per windowMs292 standardHeaders: true,293 legacyHeaders: false,294 message: 'Too many login attempts from this IP, please try again after 15 minutes'295 });296297 // Apply rate limiters to routes298 app.use('/api/', apiLimiter);299 app.use('/api/auth/', authLimiter);300```301302 8. **Secure WebSocket Configuration:**303 - Use secure WebSocket connections (wss://)304 - Implement authentication for WebSocket connections305 - Example:306```javascript307 const http = require('http');308 const https = require('https');309 const socketIo = require('socket.io');310 const fs = require('fs');311312 let server;313314 // Create secure server in production315 if (process.env.NODE_ENV === 'production') {316 const options = {317 key: fs.readFileSync('/path/to/private.key'),318 cert: fs.readFileSync('/path/to/certificate.crt')319 };320 server = https.createServer(options, app);321 } else {322 server = http.createServer(app);323 }324325 const io = socketIo(server, {326 cors: {327 origin: process.env.NODE_ENV === 'production'328 ? 'https://yourdomain.com'329 : 'http://localhost:3000',330 methods: ['GET', 'POST'],331 credentials: true332 }333 });334335 // WebSocket authentication middleware336 io.use((socket, next) => {337 const token = socket.handshake.auth.token;338339 if (!token) {340 return next(new Error('Authentication error'));341 }342343 // Verify token344 // ...345346 next();347 });348```349350 9. **Security Dependency Management:**351 - Regularly update dependencies352 - Use tools like npm audit or Snyk353 - Example:354```javascript355 // package.json scripts356 {357 "scripts": {358 "audit": "npm audit",359 "audit:fix": "npm audit fix",360 "outdated": "npm outdated",361 "update": "npm update",362 "prestart": "npm audit --production"363 }364 }365```366367 10. **Secure Logging Configuration:**368 - Configure logging based on environment369 - Avoid logging sensitive information370 - Example:371```javascript372 const winston = require('winston');373374 // Define log levels375 const levels = {376 error: 0,377 warn: 1,378 info: 2,379 http: 3,380 debug: 4,381 };382383 // Define log level based on environment384 const level = () => {385 const env = process.env.NODE_ENV || 'development';386 return env === 'development' ? 'debug' : 'warn';387 };388389 // Define log format390 const format = winston.format.combine(391 winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }),392 winston.format.printf(393 (info) => `${info.timestamp} ${info.level}: ${info.message}`394 )395 );396397 // Define transports398 const transports = [399 new winston.transports.Console(),400 new winston.transports.File({401 filename: 'logs/error.log',402 level: 'error',403 }),404 new winston.transports.File({ filename: 'logs/all.log' }),405 ];406407 // Create the logger408 const logger = winston.createLogger({409 level: level(),410 levels,411 format,412 transports,413 });414415 module.exports = logger;416```417418 - type: validate419 conditions:420 # Check 1: Helmet usage421 - pattern: "helmet\\(\\)|frameguard\\(\\)|hsts\\(\\)|noSniff\\(\\)|xssFilter\\(\\)|contentSecurityPolicy\\(\\)"422 message: "Using Helmet.js or individual HTTP security headers middleware."423424 # Check 2: Secure CORS configuration425 - pattern: "cors\\(\\{[^}]*?origin\\s*:\\s*(?!['\"]*\\*)['\"]"426 message: "Using secure CORS configuration with specific origins."427428 # Check 3: Environment-based configuration429 - pattern: "process\\.env\\.NODE_ENV\\s*===\\s*['\"]production['\"]"430 message: "Implementing environment-specific configuration."431432 # Check 4: Secure cookie settings433 - pattern: "cookie\\s*:\\s*\\{[^}]*?secure\\s*:\\s*true[^}]*?httpOnly\\s*:\\s*true"434 message: "Using secure cookie configuration."435436 # Check 5: Request size limiting437 - pattern: "(?:express|bodyParser)\\.json\\(\\{[^}]*?limit\\s*:"438 message: "Implementing request size limiting."439440metadata:441 priority: high442 version: 1.0443 tags:444 - security445 - javascript446 - nodejs447 - browser448 - configuration449 - owasp450 - language:javascript451 - framework:express452 - framework:react453 - framework:vue454 - framework:angular455 - category:security456 - subcategory:misconfiguration457 - standard:owasp-top10458 - risk:a05-security-misconfiguration459 references:460 - "https://owasp.org/Top10/A05_2021-Security_Misconfiguration/"461 - "https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html"462 - "https://expressjs.com/en/advanced/best-practice-security.html"463 - "https://helmetjs.github.io/"464 - "https://github.com/OWASP/NodeGoat"465 - "https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html"466 - "https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html"467</rule>468
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-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 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 | |
| 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-security-misconfiguration)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.