├── .gitignore ├── LICENSE ├── README.md ├── config.json ├── no-csrf-before-method-override.js ├── no-timing-attacks.js ├── no-unsafe-regex.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Adam Baldwin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-rules 2 | 3 | Collection of various eslint-rules 4 | 5 | 6 | # How to use 7 | ``` 8 | eslint --reset -c config.json --rulesdir . [file.js] [dir] 9 | ``` 10 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-unsafe-regex": 0, 4 | "no-timing-attacks": 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /no-csrf-before-method-override.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check and see if CSRF middleware is before methodOverride 3 | * @author Adam Baldwin 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Rule Definition 8 | //------------------------------------------------------------------------------ 9 | 10 | 11 | module.exports = function(context) { 12 | 13 | "use strict"; 14 | var csrf = false; 15 | 16 | return { 17 | "CallExpression": function(node) { 18 | var token = context.getTokens(node)[0], 19 | nodeType = token.type, 20 | nodeValue = token.value; 21 | 22 | if (nodeValue === "express") { 23 | if (node.callee.property.name === "methodOverride" && csrf) { 24 | context.report(node, "express.csrf() middleware found before express.methodOverride()"); 25 | } 26 | if (node.callee.property.name === "csrf") { 27 | // Keep track of found CSRF 28 | csrf = true; 29 | } 30 | } 31 | } 32 | }; 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /no-timing-attacks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Looks for potential hot spot string comparisons 3 | * @author Adam Baldwin 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Rule Definition 8 | //------------------------------------------------------------------------------ 9 | 10 | var keywords = '((' + [ 11 | 'password', 12 | 'secret', 13 | 'api', 14 | 'token', 15 | 'auth', 16 | 'pass', 17 | 'hash' 18 | ].join(')|(') + '))'; 19 | 20 | var re = new RegExp('^' + keywords + '$', 'im'); 21 | 22 | function containsKeyword (node) { 23 | if (node.type === 'Identifier') { 24 | if (re.test(node.name)) 25 | return true; 26 | } 27 | return 28 | } 29 | 30 | module.exports = function(context) { 31 | 32 | "use strict"; 33 | 34 | return { 35 | "IfStatement": function(node) { 36 | if (node.test && node.test.type === 'BinaryExpression') { 37 | if (node.test.operator === '==' || node.test.operator === '===' || node.test.operator === '!=' || node.test.operator === '!==') { 38 | 39 | if (node.test.left) { 40 | var left = containsKeyword(node.test.left); 41 | if (left) { 42 | return context.report(node, "Potential timing attack, left side: " + left); 43 | } 44 | } 45 | 46 | if (node.test.right) { 47 | var right = containsKeyword(node.test.right); 48 | if (right) { 49 | return context.report(node, "Potential timing attack, right side: " + right); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | }; 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /no-unsafe-regex.js: -------------------------------------------------------------------------------- 1 | var safe = require('safe-regex'); 2 | /** 3 | * Check if the regex is evil or not using the safe-regex module 4 | * @author Adam Baldwin 5 | */ 6 | 7 | //------------------------------------------------------------------------------ 8 | // Rule Definition 9 | //------------------------------------------------------------------------------ 10 | 11 | module.exports = function(context) { 12 | 13 | "use strict"; 14 | 15 | return { 16 | "Literal": function(node) { 17 | var token = context.getTokens(node)[0], 18 | nodeType = token.type, 19 | nodeValue = token.value; 20 | 21 | if (nodeType === "RegularExpression") { 22 | if (!safe(nodeValue)) { 23 | context.report(node, "Unsafe Regular Expression"); 24 | } 25 | } 26 | } 27 | }; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-rules", 3 | "version": "0.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [ 13 | "eslint", 14 | "lint", 15 | "security" 16 | ], 17 | "author": "Adam Baldwin", 18 | "license": "MIT", 19 | "dependencies": { 20 | "safe-regex": "0.0.0" 21 | } 22 | } 23 | --------------------------------------------------------------------------------