diff --git a/CHANGELOG.md b/CHANGELOG.md index e78c905..920b996 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,48 @@ # CHANGELOG + +## [0.7.3] - 2020-09-30 + +### Added + +- Security HTTP headers using Helmet +- Add XSS Attack Protectio + ## [0.7.2] - 2020-05-08 + ### Fixed -- Fix bodyParser.raw cannot read file contents + +- Fix bodyParser.raw cannot read file contents ## [0.7.1] - 2020-05-05 + ### Fixed -- Fix basicController.crud router + +- Fix basicController.crud router ## [0.6.1] - 2019-04-22 + ### Added + - Merge bodyParser options [0.6.1]: https://github.com/kata-ai/merapi-plugin-express/compare/v0.6.0...v0.6.1 ## [0.6.0] - 2019-03-12 + ### Added + - Add bodyParser.raw() [0.6.0]: https://github.com/kata-ai/merapi-plugin-express/compare/v0.5.0...v0.6.0 ## [0.5.0] - 2018-01-24 + ### Added + - Resolve verify function in bodyParser options ### Fixed + - Express tests [0.5.0]: https://github.com/kata-ai/merapi-plugin-express/compare/v0.4.0...v0.5.0 diff --git a/index.js b/index.js index 348b087..d308b3b 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,11 @@ "use strict"; const express = require("express"); +const helmet = require("helmet"); const bodyParser = require("body-parser"); const router = require("./lib/router"); const getfn = require("./lib/getfn"); +const xssDetection = require("./lib/xss"); module.exports = function (merapi) { @@ -14,6 +16,7 @@ module.exports = function (merapi) { this.apps.push(name); return function* (config, injector, logger) { let app = express(); + app.use(helmet()); let getFn = getfn(injector); @@ -35,6 +38,8 @@ module.exports = function (merapi) { app.use(bodyParser.urlencoded(Object.assign({ extended: true }, bodyParserOptions))); // app.use(bodyParser.raw(Object.assign({ type: "*/*" }, bodyParserOptions))); + app.use(xssDetection) + let isRoutesInMiddleware = false; for (let i = 0; i < middleware.length; i++) { diff --git a/lib/xss.js b/lib/xss.js new file mode 100644 index 0000000..8b0936d --- /dev/null +++ b/lib/xss.js @@ -0,0 +1,47 @@ +"use strict"; + +const xssDetection = function (req, res, next) { + const keys = getJsonKeys(req.body) + + for (const key of keys) { + const value = eval('req.body' + key) + if (typeof value == 'string') { + if (isXssAttack(value)) { + res.json({ message: 'XSS Attack Detection !' }); + return + } + } + } + + next() +} + +function getJsonKeys(body) { + const keys = []; + + function f(o, s) { + if (!o) { + return + } + + if (s) { + keys.push(s) + } + + [o] == o || Object.keys(o).map(k => f(o[k], k = s ? (isNumeric(k) ? `${s}[${k}]` : `${s}.${k}`) : (isNumeric(k) ? `[${k}]` : `.${k}`))) + } + + f(body) + + return keys +} + +function isNumeric(value) { + return /^-?\d+$/.test(value); +} + +function isXssAttack(value) { + return /\<(|\s+)script(|\s+)\>|\<\/(|\s+)script(|\s+)\>/g.test(value); +} + +module.exports = xssDetection \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4bd8038..4bb9e20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "merapi-plugin-express", - "version": "0.7.2-fix1", + "version": "0.7.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1392,6 +1392,11 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "helmet": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.1.1.tgz", + "integrity": "sha512-Avg4XxSBrehD94mkRwEljnO+6RZx7AGfk8Wa6K1nxaU+hbXlFOhlOIMgPfFqOYQB/dBCsTpootTGuiOG+CHiQA==" + }, "hoek": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", @@ -3769,4 +3774,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 59bed51..5fd1cd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "merapi-plugin-express", - "version": "0.7.2-fix1", + "version": "0.7.3", "description": "Merapi Plugin for Express App", "main": "index.js", "scripts": { @@ -27,6 +27,7 @@ "dependencies": { "body-parser": "^1.15.2", "express": "^4.14.0", + "helmet": "^4.1.1", "merapi": "^0.21.0", "type-check": "^0.3.2" }, @@ -39,4 +40,4 @@ "mocha-lcov-reporter": "^1.3.0", "supertest": "^3.0.0" } -} +} \ No newline at end of file