Skip to content

Commit

Permalink
Add show comments tool (#379)
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Bennetts <psiinon@gmail.com>
  • Loading branch information
psiinon authored and thc202 committed Nov 22, 2019
1 parent 40a4a9f commit bb40130
Show file tree
Hide file tree
Showing 15 changed files with 457 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added 'Toggle Script' tool, allowing user-made scripts to be toggled on and off from the HUD [#335](https://github.com/zaproxy/zap-hud/issues/335)
- Tweet link on completing the tutorial
- Comments tool which shows all of the HTML comments on a page [#378](https://github.com/zaproxy/zap-hud/issues/378)

### Fixed
- Dialogue windows close properly when the Escape key is pressed [#71](https://github.com/zaproxy/zap-hud/issues/71)
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/zaproxy/zap/extension/hud/HudParam.java
Expand Up @@ -31,6 +31,7 @@
import org.zaproxy.zap.eventBus.Event;
import org.zaproxy.zap.extension.api.ZapApiIgnore;
import org.zaproxy.zap.extension.hud.tutorial.pages.AjaxSpiderPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.CommentsPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.HistoryPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.HudConfigPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.ToggleScriptPage;
Expand Down Expand Up @@ -299,6 +300,7 @@ protected void updateConfigsImpl(int fileVersion) {
addTutorialUpdate(HistoryPage.NAME);
}
if (fileVersion <= 3) {
addTutorialUpdate(CommentsPage.NAME);
addTutorialUpdate(ToggleScriptPage.NAME);
}
getConfig().setProperty(PARAM_TUTORIAL_UPDATES, tutorialUpdates);
Expand Down
Expand Up @@ -43,6 +43,7 @@
import org.zaproxy.zap.extension.hud.tutorial.pages.AlertsPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.AttackModePage;
import org.zaproxy.zap.extension.hud.tutorial.pages.BreakPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.CommentsPage;
import org.zaproxy.zap.extension.hud.tutorial.pages.CompletePage;
import org.zaproxy.zap.extension.hud.tutorial.pages.EnablePage;
import org.zaproxy.zap.extension.hud.tutorial.pages.ErrorPage;
Expand Down Expand Up @@ -108,6 +109,7 @@ public TutorialProxyServer(ExtensionHUD extension) {
prev = addPage(new ActiveScanPage(this, prev));
prev = addPage(new AttackModePage(this, prev));
prev = addPage(new ToolConfigPage(this, prev));
prev = addPage(new CommentsPage(this, prev));
prev = addPage(new ToggleScriptPage(this, prev));
prev = addPage(new HtmlReportPage(this, prev));
prev = addPage(new HudConfigPage(this, prev));
Expand Down
@@ -0,0 +1,50 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2019 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.zap.extension.hud.tutorial.pages;

import org.zaproxy.zap.extension.hud.tutorial.TutorialPage;
import org.zaproxy.zap.extension.hud.tutorial.TutorialProxyServer;

public class CommentsPage extends TutorialPage {

public static final String NAME = "Comments";

public CommentsPage(TutorialProxyServer tutorialProxyServer) {
this(tutorialProxyServer, null);
}

public CommentsPage(TutorialProxyServer tutorialProxyServer, TutorialPage prev) {
super(tutorialProxyServer, prev);
}

@Override
public String getName() {
return NAME;
}

@Override
public String getHtml() {
String html = super.getHtml();
if (!this.isTaskCompleted()) {
html = html.replace("<!-- KEY -->", this.setTaskToken());
}
return html;
}
}
Expand Up @@ -62,6 +62,7 @@ hud.tutorial.page.alertsnotifications.alert.title.3 = Example High Level Notific
hud.tutorial.page.alertsnotifications.alert.description = An example alert - this description will usually have more useful information in it!
hud.tutorial.page.attackmode = Attack Mode
hud.tutorial.page.break = Break
hud.tutorial.page.comments = Comments
hud.tutorial.page.complete = Complete
hud.tutorial.page.enable = Enable
hud.tutorial.page.frames = Frames
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions src/main/zapHomeFiles/hud/management.js
Expand Up @@ -138,6 +138,16 @@ function windowMessageListener(event) {
return;
}

break;
case 'showComments.count':
if (message.count === parseInt(message.count, 10) &&
message.suspicious === parseInt(message.suspicious, 10)) {
limitedData.count = message.count;
limitedData.suspicious = message.suspicious;
navigator.serviceWorker.controller.postMessage(limitedData);
return;
}

break;
default:
break;
Expand Down Expand Up @@ -169,6 +179,18 @@ function serviceWorkerMessageListener(event) {
parent.postMessage({action: 'showEnable.count'}, document.referrer);
break;

case 'showComments.on':
parent.postMessage({action: 'showComments.on', suspicious: message.suspicious}, document.referrer);
break;

case 'showComments.off':
parent.postMessage({action: 'showComments.off'}, document.referrer);
break;

case 'showComments.count':
parent.postMessage({action: 'showComments.count', suspicious: message.suspicious}, document.referrer);
break;

case 'commonAlerts.alert':
parent.postMessage(message, document.referrer);
break;
Expand Down
128 changes: 120 additions & 8 deletions src/main/zapHomeFiles/hud/target/inject.js
Expand Up @@ -165,7 +165,7 @@ const injection = (function () {
document.getElementById(MANAGEMENT).style.height = '0px';
}

// TODO put this code in a separate file and inject ?
// TODO showEnable section - put this code in a separate file and inject ?
let showEnabled = false;
let showEnabledCount = 0;
let showEnableTypeHiddenFields = [];
Expand Down Expand Up @@ -269,12 +269,12 @@ const injection = (function () {
} else {
// Count the number of hidden fields
const inputs = document.querySelectorAll('input');
for (let index = 0; index < inputs.length; ++index) {
if (inputs[index].type === 'hidden') {
for (const element of inputs) {
if (element.type === 'hidden') {
count++;
} else if (inputs[index].style.display === 'none') {
} else if (element.style.display === 'none') {
count++;
} else if (inputs[index].style.visibility === 'hidden') {
} else if (element.style.visibility === 'hidden') {
count++;
}
}
Expand All @@ -290,9 +290,9 @@ const injection = (function () {
let el = document.getElementById(id);
if (!el) {
const els = document.getElementsByName(id);
for (let i = 0; i < els.length; i++) {
if (els[i] instanceof HTMLInputElement) {
el = els[i];
for (const element of els) {
if (element instanceof HTMLInputElement) {
el = element;
break;
}
}
Expand Down Expand Up @@ -323,6 +323,106 @@ const injection = (function () {
}
}

// End of showEnable section

// TODO showComments section - put this code in a separate file and inject ?
let commentImages = [];

function includeComment(commentNode) {
return commentNode.textContent.trim().length > 0;
}

function isSuspiciousComment(commentNode, suspiciousList) {
const textUc = commentNode.textContent.toUpperCase();
for (const element of suspiciousList) {
if (textUc.includes(element)) {
return true;
}
}

return false;
}

function showCommentsOn(suspiciousList) {
const x = document.evaluate('//comment()', document, null, XPathResult.ANY_TYPE, null);
let count = 0;
const comments = [];
let comment = x.iterateNext();
// Can't change the DOM while iterating through the results, so put them in a list
while (comment) {
if (includeComment(comment)) {
comments.push(comment);
}

comment = x.iterateNext();
}

const first = document.body.firstChild;
comments.forEach(comment => {
count += 1;
const img = new Image(16, 16);
img.src = ZAP_HUD_FILES + '/image/balloon.png';
img.title = comment.textContent;
img.id = 'zapHudComment-' + count;
img.style.zIndex = '1000000';
img.addEventListener('click', () => {
navigator.clipboard.writeText(comment.textContent);
});

if (isSuspiciousComment(comment, suspiciousList)) {
img.src = ZAP_HUD_FILES + '/image/balloon-yellow-exclamation.png';
}

try {
if (document.body.contains(comment)) {
comment.parentNode.insertBefore(img, comment);
} else if (first) {
// Keep the same 'first' node to keep the comments in order
document.body.insertBefore(img, first);
} else {
// Nothing in the body, unlikely but possible
document.body.append(img);
}

commentImages.push(img);
} catch (error) {
console.log('Failed to add comment icon ' + error.message);
}
});
}

function showCommentsOff() {
commentImages.forEach(img => {
img.remove();
});
commentImages = [];
}

function showCommentsCount(suspiciousList) {
const x = document.evaluate('//comment()', document, null, XPathResult.ANY_TYPE, null);
let count = 0;
let sus = 0;
let comment = x.iterateNext();

while (comment) {
if (includeComment(comment)) {
count += 1;
if (isSuspiciousComment(comment, suspiciousList)) {
sus += 1;
}
}

comment = x.iterateNext();
}

// Send to the management frame with the shared secret
const iframe = document.getElementById(MANAGEMENT);
iframe.contentWindow.postMessage({action: 'showComments.count', tabId,
count, suspicious: sus, sharedSecret: ZAP_SHARED_SECRET}, ZAP_HUD_FILES);
}

// End of showComments section

function showZapAlertInternal(alertId) {
// Send to the management frame with the shared secret
const iframe = document.getElementById(MANAGEMENT);
Expand Down Expand Up @@ -435,6 +535,18 @@ const injection = (function () {
showEnableCount();
break;

case 'showComments.on':
showCommentsOn(message.suspicious);
break;

case 'showComments.off':
showCommentsOff();
break;

case 'showComments.count':
showCommentsCount(message.suspicious);
break;

case 'commonAlerts.alert':
highlightAlert(message);
break;
Expand Down

0 comments on commit bb40130

Please sign in to comment.