From bb1eb55539c248b7adb7955570184ecc229f4f10 Mon Sep 17 00:00:00 2001 From: Pamplemousse Date: Mon, 4 Feb 2019 12:57:04 +0100 Subject: [PATCH 1/4] Inject the front-end-tracker in the page's Will be needed to feed the bottom-drawer with storage or DOM events. --- package-lock.json | 13 +++++ package.json | 1 + .../zap/extension/hud/ExtensionHUD.java | 6 +++ .../zaproxy/zap/extension/hud/HtmlEditor.java | 9 ++++ .../org/zaproxy/zap/extension/hud/HudAPI.java | 2 +- .../hud/target/front-end-tracker.js | 1 + .../zap/extension/hud/HtmlEditorUnitTest.java | 47 +++++++++++++++++++ 7 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/main/zapHomeFiles/hud/target/front-end-tracker.js diff --git a/package-lock.json b/package-lock.json index 4c6635326..c6c41efe2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -741,6 +741,14 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "@zaproxy/front-end-tracker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@zaproxy/front-end-tracker/-/front-end-tracker-1.0.0.tgz", + "integrity": "sha512-MAcFIE7WIFJEG7/gVDQTrw4HcQr1CVfzvaS2LINbPZ32AB/H6gKo6lXgfdMf8TEtznFdKgDKwKahfhi6vnATBw==", + "requires": { + "pubsub-js": "^1.6.0" + } + }, "acorn": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", @@ -6932,6 +6940,11 @@ "safe-buffer": "^5.1.2" } }, + "pubsub-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.7.0.tgz", + "integrity": "sha512-Pb68P9qFZxnvDipHMuj9oT1FoIgBcXJ9C9eWdHCLZAnulaUoJ3+Y87RhGMYilWpun6DMWVmvK70T4RP4drZMSA==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", diff --git a/package.json b/package.json index 10a300f83..db2f618b6 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ }, "homepage": "https://github.com/zaproxy/zap-hud/wiki", "dependencies": { + "@zaproxy/front-end-tracker": "^1.0.0", "localforage": "^1.5.0", "vue": "^2.6.8", "vue-i18n": "^8.8.2" diff --git a/src/main/java/org/zaproxy/zap/extension/hud/ExtensionHUD.java b/src/main/java/org/zaproxy/zap/extension/hud/ExtensionHUD.java index 2ac710c06..1adbf35d5 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/ExtensionHUD.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/ExtensionHUD.java @@ -405,9 +405,15 @@ public boolean onHttpResponseReceive(HttpMessage msg) { try { HtmlEditor htmlEd = new HtmlEditor(msg); String hudScript = this.api.getFile(msg, HUD_HTML); + String frontEndTrackerScript = + ""; // These are the only files that use FILE_PREFIX hudScript = hudScript.replace("<>", api.getUrlPrefix(api.getSite(msg))); + + htmlEd.injectAtStartOfHead(frontEndTrackerScript); htmlEd.injectAtStartOfBody(hudScript); htmlEd.rewriteHttpMessage(); diff --git a/src/main/java/org/zaproxy/zap/extension/hud/HtmlEditor.java b/src/main/java/org/zaproxy/zap/extension/hud/HtmlEditor.java index 72e3f6dbd..1ff807bb2 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/HtmlEditor.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/HtmlEditor.java @@ -39,6 +39,15 @@ public HtmlEditor(HttpMessage msg) { this.outputDocument = new OutputDocument(source); } + public void injectAtStartOfHead(String inject) { + List headTags = this.source.getAllStartTags("head"); + + if (headTags.size() > 0) { + this.outputDocument.insert(headTags.get(0).getEnd(), inject); + this.changed = true; + } + } + public void injectAtStartOfBody(String inject) { List bodyTags = this.source.getAllStartTags("body"); diff --git a/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java b/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java index 5618adf97..3f5beda9d 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java @@ -100,7 +100,7 @@ public class HudAPI extends ApiImplementor { /** The only files that can be included on domain */ private static final List DOMAIN_FILE_WHITELIST = - Arrays.asList(new String[] {"inject.js"}); + Arrays.asList(new String[] {"inject.js", "front-end-tracker.js"}); private ApiImplementor hudFileProxy; private String hudFileUrl; diff --git a/src/main/zapHomeFiles/hud/target/front-end-tracker.js b/src/main/zapHomeFiles/hud/target/front-end-tracker.js new file mode 100644 index 000000000..4a798f8a1 --- /dev/null +++ b/src/main/zapHomeFiles/hud/target/front-end-tracker.js @@ -0,0 +1 @@ +!function(){return function t(e,n,o){function r(i,c){if(!n[i]){if(!e[i]){var a="function"==typeof require&&require;if(!c&&a)return a(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[i]={exports:{}};e[i][0].call(l.exports,function(t){return r(e[i][1][t]||t)},l,l.exports,t,e,n,o)}return n[i].exports}for(var s="function"==typeof require&&require,i=0;i{(new t.Hook).setOptions(t.options)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./events.js":1,"./hooks/event-listener-hook.js":2,"./hooks/storage-hook":3,"pubsub-js":5}],5:[function(t,e,n){!function(t,o){"use strict";var r={};t.PubSub=r;var s=t.define;!function(t){var e={},n=-1;function o(t){var e;for(e in t)if(t.hasOwnProperty(e))return!0;return!1}function r(t,e,n){try{t(e,n)}catch(t){setTimeout(function(t){return function(){throw t}}(t),0)}}function s(t,e,n){t(e,n)}function i(t,n,o,i){var c,a=e[n],u=i?s:r;if(e.hasOwnProperty(n))for(c in a)a.hasOwnProperty(c)&&u(a[c],t,o)}function c(t,n,r,s){var c=function(t,e,n){return function(){var o=String(t),r=o.lastIndexOf(".");for(i(t,t,e,n);-1!==r;)o=o.substr(0,r),r=o.lastIndexOf("."),i(t,o,e,n)}}(t="symbol"==typeof t?t.toString():t,n,s),a=function(t){var n=String(t),r=Boolean(e.hasOwnProperty(n)&&o(e[n])),s=n.lastIndexOf(".");for(;!r&&-1!==s;)n=n.substr(0,s),s=n.lastIndexOf("."),r=Boolean(e.hasOwnProperty(n)&&o(e[n]));return r}(t);return!!a&&(!0===r?c():setTimeout(c,0),!0)}t.publish=function(e,n){return c(e,n,!1,t.immediateExceptions)},t.publishSync=function(e,n){return c(e,n,!0,t.immediateExceptions)},t.subscribe=function(t,o){if("function"!=typeof o)return!1;t="symbol"==typeof t?t.toString():t,e.hasOwnProperty(t)||(e[t]={});var r="uid_"+String(++n);return e[t][r]=o,r},t.subscribeOnce=function(e,n){var o=t.subscribe(e,function(){t.unsubscribe(o),n.apply(this,arguments)});return t},t.clearAllSubscriptions=function(){e={}},t.clearSubscriptions=function(t){var n;for(n in e)e.hasOwnProperty(n)&&0===n.indexOf(t)&&delete e[n]},t.unsubscribe=function(n){var o,r,s,i="string"==typeof n&&(e.hasOwnProperty(n)||function(t){var n;for(n in e)if(e.hasOwnProperty(n)&&0===n.indexOf(t))return!0;return!1}(n)),c=!i&&"string"==typeof n,a="function"==typeof n,u=!1;if(!i){for(o in e)if(e.hasOwnProperty(o)){if(r=e[o],c&&r[n]){delete r[n],u=n;break}if(a)for(s in r)r.hasOwnProperty(s)&&r[s]===n&&(delete r[s],u=!0)}return u}t.clearSubscriptions(n)}}(r),"function"==typeof s&&s.amd?s(function(){return r}):"object"==typeof n&&(void 0!==e&&e.exports&&(n=e.exports=r),n.PubSub=r,e.exports=n=r)}("object"==typeof window&&window||this)},{}]},{},[4,2,3]); \ No newline at end of file diff --git a/src/test/java/org/zaproxy/zap/extension/hud/HtmlEditorUnitTest.java b/src/test/java/org/zaproxy/zap/extension/hud/HtmlEditorUnitTest.java index b7a9709f1..62ed3df18 100644 --- a/src/test/java/org/zaproxy/zap/extension/hud/HtmlEditorUnitTest.java +++ b/src/test/java/org/zaproxy/zap/extension/hud/HtmlEditorUnitTest.java @@ -36,14 +36,25 @@ public void testNoBodyTag() { genericTestWithNoBodyTag(""); } + @Test + public void testNoHeadTag() { + genericTestWithNoHeadTag(""); + } + @Test public void testCommentedBody() { genericTestWithNoBodyTag(""); } + @Test + public void testCommentedHead() { + genericTestWithNoHeadTag(""); + } + @Test public void testSimpleHtml() { genericTestWithBodyTag("" + EOB_TOKEN + ""); + genericTestWithHeadTag("" + EOB_TOKEN + ""); } @Test @@ -71,6 +82,12 @@ public void testMultipleBodyTags() { genericTestWithBodyTag("" + EOB_TOKEN + ""); } + @Test + public void testMultipleHeadTags() { + genericTestWithHeadTag( + "" + EOB_TOKEN + ""); + } + private void genericTestWithBodyTag(String htmlBody) { // Given HttpMessage msg = new HttpMessage(); @@ -100,4 +117,34 @@ private void genericTestWithNoBodyTag(String htmlBody) { assertFalse(htmlEd.isChanged()); assertTrue(msg.getResponseBody().toString().equals(htmlBody)); } + + private void genericTestWithHeadTag(String htmlBody) { + // Given + HttpMessage msg = new HttpMessage(); + msg.setResponseBody(htmlBody); + HtmlEditor htmlEd = new HtmlEditor(msg); + + // When + htmlEd.injectAtStartOfHead(INJECT_TOKEN); + htmlEd.rewriteHttpMessage(); + + // Then + assertTrue(htmlEd.isChanged()); + assertTrue(msg.getResponseBody().toString().indexOf(INJECT_TOKEN + EOB_TOKEN) > 0); + } + + private void genericTestWithNoHeadTag(String htmlBody) { + // Given + HttpMessage msg = new HttpMessage(); + msg.setResponseBody(htmlBody); + HtmlEditor htmlEd = new HtmlEditor(msg); + + // When + htmlEd.injectAtStartOfHead(INJECT_TOKEN); + htmlEd.rewriteHttpMessage(); + + // Then + assertFalse(htmlEd.isChanged()); + assertTrue(msg.getResponseBody().toString().equals(htmlBody)); + } } From 047d8ccbc8f34e655a0f927d75f8d78fcd6e035c Mon Sep 17 00:00:00 2001 From: Pamplemousse Date: Wed, 6 Feb 2019 12:53:30 +0100 Subject: [PATCH 2/4] Refacto in bottom-drawer There will be other tabs, so try to make the current content generic. * css will not impact only history tab * there will be other messages passing, so rename current events related to history to be specificly for it --- src/main/zapHomeFiles/hud/drawer.html | 4 ++-- src/main/zapHomeFiles/hud/drawer.js | 8 ++++---- src/main/zapHomeFiles/hud/libraries/spectre.css | 4 ++-- src/main/zapHomeFiles/hud/tools/history.js | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/zapHomeFiles/hud/drawer.html b/src/main/zapHomeFiles/hud/drawer.html index 6281c13f0..38d528719 100644 --- a/src/main/zapHomeFiles/hud/drawer.html +++ b/src/main/zapHomeFiles/hud/drawer.html @@ -57,7 +57,7 @@ - +
@@ -173,4 +173,4 @@
- \ No newline at end of file + diff --git a/src/main/zapHomeFiles/hud/drawer.js b/src/main/zapHomeFiles/hud/drawer.js index 57b82ea61..59bed9f3e 100644 --- a/src/main/zapHomeFiles/hud/drawer.js +++ b/src/main/zapHomeFiles/hud/drawer.js @@ -84,11 +84,11 @@ Vue.component('history', { }) .catch(utils.errorHandler) - eventBus.$on('setMessages', data => { + eventBus.$on('setHistoryMessages', data => { this.messages = data.messages; }) - eventBus.$on('updateMessages', data => { + eventBus.$on('updateHistoryMessages', data => { this.messages = this.messages.concat(data.messages); let count = data.messages.length; @@ -421,8 +421,8 @@ navigator.serviceWorker.addEventListener('message', event => { var port = event.ports[0]; switch(action) { - case 'updateMessages': - eventBus.$emit('updateMessages', { + case 'updateHistoryMessages': + eventBus.$emit('updateHistoryMessages', { messages: event.data.messages, port: port }); diff --git a/src/main/zapHomeFiles/hud/libraries/spectre.css b/src/main/zapHomeFiles/hud/libraries/spectre.css index a013189bf..1dbad93e6 100644 --- a/src/main/zapHomeFiles/hud/libraries/spectre.css +++ b/src/main/zapHomeFiles/hud/libraries/spectre.css @@ -534,8 +534,8 @@ html { border-bottom-width: .1rem; } - .table-history td, - .table-history th { + .table-bottom-drawer td, + .table-bottom-drawer th { padding: .1em .6em .1em .6em; white-space: nowrap; } diff --git a/src/main/zapHomeFiles/hud/tools/history.js b/src/main/zapHomeFiles/hud/tools/history.js index a9c086435..dc78d3a83 100644 --- a/src/main/zapHomeFiles/hud/tools/history.js +++ b/src/main/zapHomeFiles/hud/tools/history.js @@ -130,7 +130,7 @@ var History = (function() { message.code = event.detail.statusCode; message.id = event.detail.historyReferenceId; - utils.messageAllTabs('drawer', {action: 'updateMessages', messages: [message]}) + utils.messageAllTabs('drawer', {action: 'updateHistoryMessages', messages: [message]}) .catch(utils.errorHandler); tool.messages.push(message); From 759fb20e95382fb289c62111612f812bf3a8d45d Mon Sep 17 00:00:00 2001 From: Pamplemousse Date: Wed, 6 Feb 2019 16:25:03 +0100 Subject: [PATCH 3/4] Add storage events in bottom-drawer --- src/main/zapHomeFiles/hud/drawer.html | 25 ++++- src/main/zapHomeFiles/hud/drawer.js | 51 +++++++++ src/main/zapHomeFiles/hud/target/inject.js | 17 ++- src/main/zapHomeFiles/hud/tools/storage.js | 101 ++++++++++++++++++ .../UIMessages/UIMessages.properties | 6 ++ 5 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 src/main/zapHomeFiles/hud/tools/storage.js diff --git a/src/main/zapHomeFiles/hud/drawer.html b/src/main/zapHomeFiles/hud/drawer.html index 38d528719..91defff29 100644 --- a/src/main/zapHomeFiles/hud/drawer.html +++ b/src/main/zapHomeFiles/hud/drawer.html @@ -20,6 +20,9 @@ + + + @@ -70,7 +73,6 @@ - + +
{{ message.time }}