From d0c8cfeed6387cd4650d9856482f89c6c057b9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Fri, 31 Jan 2020 14:53:20 +0100 Subject: [PATCH] feat(cookie): add support for cookies and tokens (#67) --- README.md | 2 +- __tests__/Utils.test.js | 34 ++++++++++++++++++++++++++++++++++ bin/is-website-vulnerable.js | 15 +++++++++++---- src/Utils.js | 15 +++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c770c53..1804188 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Finds publicly known security vulnerabilities in a website's frontend JavaScript Using Node.js's `npx` to run a one-off scan of a website: ```bash -npx is-website-vulnerable https://example.com [--json] [--js-lib] [--mobile|--desktop] [--chromePath] +npx is-website-vulnerable https://example.com [--json] [--js-lib] [--mobile|--desktop] [--chromePath] [--cookie] [--token] ``` The CLI will gracefully handle cases where the URL to scan is missing by prompting you to enter it: diff --git a/__tests__/Utils.test.js b/__tests__/Utils.test.js index 3becdc8..5bbbd8b 100644 --- a/__tests__/Utils.test.js +++ b/__tests__/Utils.test.js @@ -83,4 +83,38 @@ describe('Utils', () => { expect(Utils.parseDevice(argv)).toEqual(device) expect(Utils.hasDevice(argv)).toEqual(true) }) + + test('hasAutentication & parseAutentication with none flag', async () => { + const argv = {} + expect(Utils.parseAutentication(argv)).toEqual({}) + expect(Utils.hasAutentication(argv)).toEqual(false) + }) + + test('hasAutentication & parseAutentication with cookie flag', async () => { + const argv = { cookie: 'This is the COOKIE content' } + expect(Utils.parseAutentication(argv)).toEqual({ + Cookie: 'This is the COOKIE content' + }) + expect(Utils.hasAutentication(argv)).toEqual(true) + }) + + test('hasAutentication & parseAutentication with token flag', async () => { + const argv = { token: 'This is the TOKEN content' } + expect(Utils.parseAutentication(argv)).toEqual({ + Authorization: 'Bearer This is the TOKEN content' + }) + expect(Utils.hasAutentication(argv)).toEqual(true) + }) + + test('hasAutentication & parseAutentication with token and cookie flags', async () => { + const argv = { + cookie: 'This is the COOKIE content', + token: 'This is the TOKEN content' + } + expect(Utils.parseAutentication(argv)).toEqual({ + Cookie: 'This is the COOKIE content', + Authorization: 'Bearer This is the TOKEN content' + }) + expect(Utils.hasAutentication(argv)).toEqual(true) + }) }) diff --git a/bin/is-website-vulnerable.js b/bin/is-website-vulnerable.js index 0dbb474..9b91260 100755 --- a/bin/is-website-vulnerable.js +++ b/bin/is-website-vulnerable.js @@ -4,7 +4,7 @@ const os = require('os') const debug = require('debug')('is-website-vulnerable') -const argv = require('yargs').argv +const { argv } = require('yargs') const { Audit, RenderConsole, RenderJson, Utils } = require('../index') const promptUrlInput = require('./prompt-url-input') @@ -17,9 +17,16 @@ function detectEnvironment() { } function getLighthouseOptions() { - const lighthouseOpts = Utils.hasDevice(argv) - ? { emulatedFormFactor: Utils.parseDevice(argv) } - : {} + const lighthouseOpts = {} + + if (Utils.hasDevice(argv)) { + lighthouseOpts.emulatedFormFactor = Utils.parseDevice(argv) + } + + if (Utils.hasAutentication(argv)) { + lighthouseOpts.extraHeaders = Utils.parseAutentication(argv) + } + const { chromePath } = argv const chromeOpts = chromePath ? { chromePath } : {} diff --git a/src/Utils.js b/src/Utils.js index 883c3a5..c8e8190 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -42,5 +42,20 @@ module.exports = { }, hasDevice: function(argv) { return argv.mobile || argv.desktop || argv.none || false + }, + parseAutentication: function(argv) { + const extraHeaders = {} + if (argv.cookie) { + extraHeaders.Cookie = argv.cookie + } + + if (argv.token) { + extraHeaders.Authorization = `Bearer ${argv.token}` + } + + return extraHeaders + }, + hasAutentication: function(argv) { + return ['cookie', 'token'].some(prop => Object.hasOwnProperty.call(argv, prop)) } }