Skip to content

Commit

Permalink
Process triggers and notifications also on exception during ActiveSca…
Browse files Browse the repository at this point in the history
…ns sendAndReceive. Fixes #7004

Signed-off-by: Dennis Kniep <kniepdennis@gmail.com>
  • Loading branch information
denniskniep committed Jan 14, 2022
1 parent 0e49dcb commit 0d4ba97
Show file tree
Hide file tree
Showing 20 changed files with 663 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
// ZAP: 2020/11/17 Use new TechSet#getAllTech().
// ZAP: 2020/11/26 Use Log4j2 getLogger() and deprecate Log4j1.x.
// ZAP: 2021/07/20 Correct message updated with the scan rule ID header (Issue 6689).
// ZAP: 2022/01/04 Process triggers and notifications also on exception during sendAndReceive (Issue
// 7004).
package org.parosproxy.paros.core.scanner;

import java.io.IOException;
Expand All @@ -94,6 +96,7 @@
import org.parosproxy.paros.network.HttpStatusCode;
import org.zaproxy.zap.control.AddOn;
import org.zaproxy.zap.extension.anticsrf.ExtensionAntiCSRF;
import org.zaproxy.zap.extension.ascan.ScannerTaskResult;
import org.zaproxy.zap.extension.custompages.CustomPage;
import org.zaproxy.zap.model.Tech;
import org.zaproxy.zap.model.TechSet;
Expand Down Expand Up @@ -309,16 +312,24 @@ protected void sendAndReceive(
// ZAP: Runs the "beforeScan" methods of any ScannerHooks
parent.performScannerHookBeforeScan(message, this);

if (isFollowRedirect) {
parent.getHttpSender().sendAndReceive(message, getParent().getRedirectRequestConfig());
} else {
parent.getHttpSender().sendAndReceive(message, false);
try {
if (isFollowRedirect) {
parent.getHttpSender()
.sendAndReceive(message, getParent().getRedirectRequestConfig());
} else {
parent.getHttpSender().sendAndReceive(message, false);
}
} catch (IOException e) {
// TODO: How to update HistoryRef with error Response?
message.setHistoryRef(null);
message.setErrorResponse(e);
// ZAP: Notify parent
parent.notifyNewMessage(this, new ScannerTaskResult(message, e.getLocalizedMessage()));
return;
}

// ZAP: Notify parent
parent.notifyNewMessage(this, message);

// ZAP: Set the history reference back and run the "afterScan" methods of any ScannerHooks
// ZAP: Set the history reference back and run the "afterScan" methods of any
// ScannerHooks
parent.performScannerHookAfterScan(message, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.network.HttpSender;
import org.parosproxy.paros.network.HttpStatusCode;
import org.zaproxy.zap.extension.ascan.ScannerTaskResult;
import org.zaproxy.zap.model.StructuralNode;

public class Analyser {
Expand Down Expand Up @@ -519,7 +520,7 @@ private void sendAndReceive(HttpMessage msg) throws HttpException, IOException {

httpSender.sendAndReceive(msg, parent.getRedirectRequestConfig());
requestCount++;
parent.notifyNewMessage(msg);
parent.notifyNewMessage(new ScannerTaskResult(msg));
}

public int getDelayInMs() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
import org.parosproxy.paros.network.HttpSender;
import org.zaproxy.zap.extension.alert.ExtensionAlert;
import org.zaproxy.zap.extension.ascan.ScanPolicy;
import org.zaproxy.zap.extension.ascan.ScannerTaskResult;
import org.zaproxy.zap.extension.ascan.filters.FilterResult;
import org.zaproxy.zap.extension.ascan.filters.ScanFilter;
import org.zaproxy.zap.extension.custompages.CustomPage;
Expand Down Expand Up @@ -646,7 +647,7 @@ private boolean scanMessage(Plugin plugin, int messageId) {
private boolean obtainResponse(HistoryReference hRef, HttpMessage message) {
try {
getHttpSender().sendAndReceive(message);
notifyNewMessage(message);
notifyNewMessage(new ScannerTaskResult(message));
requestCount++;
return true;
} catch (IOException e) {
Expand Down Expand Up @@ -835,26 +836,26 @@ private void notifyHostComplete() {
* Notifies interested parties that a new message was sent (and received).
*
* <p>{@link Plugin Plugins} should call {@link #notifyNewMessage(Plugin)} or {@link
* #notifyNewMessage(Plugin, HttpMessage)}, instead.
* #notifyNewMessage(Plugin, ScannerTaskResult)}, instead.
*
* @param msg the new HTTP message
* @param scannerTaskResult contains the new HTTP message
* @since 1.2.0
*/
public void notifyNewMessage(HttpMessage msg) {
parentScanner.notifyNewMessage(msg);
public void notifyNewMessage(ScannerTaskResult scannerTaskResult) {
parentScanner.notifyNewMessage(scannerTaskResult);
}

/**
* Notifies that the given {@code plugin} sent (and received) the given HTTP message.
*
* @param plugin the plugin that sent the message
* @param message the message sent
* @param scannerTaskResult contains the message sent
* @throws IllegalArgumentException if the given {@code plugin} is {@code null}.
* @since 2.5.0
* @see #notifyNewMessage(Plugin)
*/
public void notifyNewMessage(Plugin plugin, HttpMessage message) {
parentScanner.notifyNewMessage(message);
public void notifyNewMessage(Plugin plugin, ScannerTaskResult scannerTaskResult) {
parentScanner.notifyNewMessage(scannerTaskResult);
notifyNewMessage(plugin);
}

Expand All @@ -867,7 +868,7 @@ public void notifyNewMessage(Plugin plugin, HttpMessage message) {
* @param plugin the plugin that sent a non-HTTP message
* @throws IllegalArgumentException if the given parameter is {@code null}.
* @since 2.5.0
* @see #notifyNewMessage(Plugin, HttpMessage)
* @see #notifyNewMessage(Plugin, ScannerTaskResult)
*/
public void notifyNewMessage(Plugin plugin) {
if (plugin == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.extension.ascan.ActiveScanEventPublisher;
import org.zaproxy.zap.extension.ascan.ScanPolicy;
import org.zaproxy.zap.extension.ascan.ScannerTaskResult;
import org.zaproxy.zap.extension.ascan.filters.ScanFilter;
import org.zaproxy.zap.extension.ruleconfig.RuleConfigParam;
import org.zaproxy.zap.extension.script.ScriptCollection;
Expand Down Expand Up @@ -455,10 +456,10 @@ public boolean isPaused() {
return pause;
}

public void notifyNewMessage(HttpMessage msg) {
public void notifyNewMessage(ScannerTaskResult scannerTaskResult) {
for (int i = 0; i < listenerList.size(); i++) {
ScannerListener listener = listenerList.get(i);
listener.notifyNewMessage(msg);
listener.notifyNewTaskResult(scannerTaskResult);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
package org.parosproxy.paros.core.scanner;

import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.extension.ascan.ScannerTaskResult;

public interface ScannerListener {

Expand All @@ -41,8 +42,8 @@ public interface ScannerListener {

void alertFound(Alert alert);

// ZAP: Added notifyNewMessage
void notifyNewMessage(HttpMessage msg);
// ZAP: Added notifyNewTaskResult
void notifyNewTaskResult(ScannerTaskResult scannerTaskResult);

/**
* Added to notify reason for filtering message from scanning.
Expand Down
53 changes: 53 additions & 0 deletions zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
package org.parosproxy.paros.network;

import java.net.HttpCookie;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -74,11 +75,14 @@
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;
import javax.net.ssl.SSLException;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.model.HistoryReference;
import org.parosproxy.paros.model.Model;
import org.zaproxy.zap.eventBus.Event;
Expand Down Expand Up @@ -1239,4 +1243,53 @@ public Map<String, String> toEventData() {
public String getType() {
return MESSAGE_TYPE;
}

public void setErrorResponse(Exception cause) {
StringBuilder strBuilder = new StringBuilder(250);
if (cause instanceof SSLException) {
strBuilder.append(Constant.messages.getString("network.ssl.error.connect"));
strBuilder.append(this.getRequestHeader().getURI().toString()).append('\n');
strBuilder
.append(Constant.messages.getString("network.ssl.error.exception"))
.append(cause.getMessage())
.append('\n');
strBuilder
.append(Constant.messages.getString("network.ssl.error.exception.rootcause"))
.append(ExceptionUtils.getRootCauseMessage(cause))
.append('\n');
strBuilder.append(
Constant.messages.getString(
"network.ssl.error.help",
Constant.messages.getString("network.ssl.error.help.url")));

strBuilder.append("\n\nStack Trace:\n");
for (String stackTraceFrame : ExceptionUtils.getRootCauseStackTrace(cause)) {
strBuilder.append(stackTraceFrame).append('\n');
}
} else {
strBuilder
.append(cause.getClass().getName())
.append(": ")
.append(cause.getLocalizedMessage())
.append("\n\nStack Trace:\n");
for (String stackTraceFrame : ExceptionUtils.getRootCauseStackTrace(cause)) {
strBuilder.append(stackTraceFrame).append('\n');
}
}

String message = strBuilder.toString();

HttpResponseHeader responseHeader;
try {
responseHeader = new HttpResponseHeader("HTTP/1.1 400 ZAP IO Error");
responseHeader.setHeader(HttpHeader.CONTENT_TYPE, "text/plain; charset=UTF-8");
responseHeader.setHeader(
HttpHeader.CONTENT_LENGTH,
Integer.toString(message.getBytes(StandardCharsets.UTF_8).length));
this.setResponseHeader(responseHeader);
this.setResponseBody(message);
} catch (HttpMalformedHeaderException e) {
log.error("Failed to create error response:", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ public ActiveScanTableModel getMessagesTableModel() {
}

@Override
public void notifyNewMessage(final HttpMessage msg) {
public void notifyNewTaskResult(final ScannerTaskResult scannerTaskResult) {
HttpMessage msg = scannerTaskResult.getHttpMessage();
HistoryReference hRef = msg.getHistoryRef();
if (hRef == null) {
try {
Expand All @@ -299,17 +300,18 @@ public void notifyNewMessage(final HttpMessage msg) {
if (this.rcTotals.getTotal() > this.maxResultsToList) {
removeFirstHistoryReferenceInEdt();
}
addHistoryReferenceInEdt(hRef);
addHistoryReferenceInEdt(hRef, scannerTaskResult);
}
}

private void addHistoryReferenceInEdt(final HistoryReference hRef) {
private void addHistoryReferenceInEdt(
final HistoryReference hRef, ScannerTaskResult scannerTaskResult) {
EventQueue.invokeLater(
new Runnable() {

@Override
public void run() {
messagesTableModel.addHistoryReference(hRef);
messagesTableModel.addEntry(hRef, scannerTaskResult);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.core.scanner.HostProcess;
import org.parosproxy.paros.core.scanner.ScannerListener;
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.model.ScanController;
import org.zaproxy.zap.model.ScanListenner2;
Expand Down Expand Up @@ -75,7 +74,7 @@ public class ActiveScanPanel extends ScanPanel2<ActiveScan, ScanController<Activ
new FilterMessageTableModel();

private ExtensionActiveScan extension;
private HistoryReferencesTable messagesTable;
private ActiveScanTable messagesTable;
private ZapTable filterMessageTable;

private JButton policyButton = null;
Expand Down Expand Up @@ -281,7 +280,7 @@ private void resetFilterMessageTable() {

private HistoryReferencesTable getMessagesTable() {
if (messagesTable == null) {
messagesTable = new HistoryReferencesTable(EMPTY_RESULTS_MODEL);
messagesTable = new ActiveScanTable(EMPTY_RESULTS_MODEL);
messagesTable.setName(MESSAGE_CONTAINER_NAME);
messagesTable.setAutoCreateColumnsFromModel(false);
}
Expand Down Expand Up @@ -371,7 +370,7 @@ private void updateRequestCount() {
}

@Override
public void notifyNewMessage(HttpMessage msg) {}
public void notifyNewTaskResult(ScannerTaskResult scannerTaskResult) {}

private void updateNewAlertCount() {
ActiveScan ac = this.getSelectedScanner();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2022 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.ascan;

public class ActiveScanProcessedCellItem implements Comparable<ActiveScanProcessedCellItem> {

private final boolean successful;
private final String label;

public ActiveScanProcessedCellItem(boolean successful, String label) {
this.successful = successful;
this.label = label;
}

public boolean isSuccessful() {
return successful;
}

public String getLabel() {
return label;
}

@Override
public String toString() {
return label;
}

@Override
public int hashCode() {
return 31 * (successful ? 1231 : 1237);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ActiveScanProcessedCellItem other = (ActiveScanProcessedCellItem) obj;
if (successful != other.successful) {
return false;
}
return true;
}

@Override
public int compareTo(ActiveScanProcessedCellItem other) {
if (other == null) {
return 1;
}
if (successful && !other.successful) {
return 1;
} else if (!successful && other.successful) {
return -1;
}
return label.compareTo(other.label);
}
}

0 comments on commit 0d4ba97

Please sign in to comment.