Skip to content

Commit

Permalink
Client: Flag nodes that redirect when spidered
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Bennetts <psiinon@gmail.com>
  • Loading branch information
psiinon committed Dec 20, 2024
1 parent 1e1a421 commit 585b5bc
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,15 @@ public boolean addComponentToNode(ClientNode node, ClientSideComponent component
return false;
}

public boolean setRedirect(String originalUrl, String redirectedUrl) {
ClientNode node = this.clientTree.setRedirect(originalUrl, redirectedUrl);
if (node != null) {
this.clientNodeChanged(node);
return true;
}
return false;
}

public void deleteNodes(List<ClientNode> nodes) {
this.clientTree.deleteNodes(nodes);
if (View.isInitialised()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,28 @@ public boolean addComponentToNode(ClientNode node, ClientSideComponent component
}
return componentAdded;
}

public ClientNode setRedirect(String originalUrl, String redirectedUrl) {
ClientNode node = getNode(originalUrl, false, false);
if (node != null) {
node.getUserObject().setRedirect(true);
node.getUserObject().setVisited(true);
node.getUserObject()
.addComponent(
new ClientSideComponent(
ClientSideComponent.REDIRECT,
null,
originalUrl,
redirectedUrl,
ClientSideComponent.REDIRECT,
null,
null,
-1));
return node;
}
LOGGER.debug("setRedirect, no node for URL {}", originalUrl);
return null;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@
package org.zaproxy.addon.client.internal;

import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.sf.json.JSONObject;
import org.parosproxy.paros.Constant;
import org.zaproxy.addon.client.ExtensionClientIntegration;

@Getter
@AllArgsConstructor
public class ClientSideComponent {

public static String REDIRECT = "Redirect";

private String tagName;
private String id;
private String parentUrl;
Expand Down Expand Up @@ -74,31 +80,10 @@ public String getTypeForDisplay() {
}
}

public String getTagName() {
return tagName;
}

public String getId() {
return id;
}

public String getParentUrl() {
return parentUrl;
}

public String getHref() {
return href;
}

public String getText() {
return text;
}

public String getType() {
return type;
}

public boolean isStorageEvent() {
if (type == null) {
return false;
}
switch (type) {
case "Cookies", "localStorage", "sessionStorage":
return true;
Expand All @@ -107,14 +92,6 @@ public boolean isStorageEvent() {
}
}

public String getTagType() {
return tagType;
}

public int getFormId() {
return formId;
}

@Override
public int hashCode() {
return Objects.hash(href, id, parentUrl, tagName, text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class ClientSideDetails {
private String url;
private boolean visited;
private boolean storage;
private boolean redirect;

private Set<ClientSideComponent> components = new HashSet<>();

Expand Down Expand Up @@ -72,4 +73,12 @@ public boolean isStorage() {
protected void setStorage(boolean storage) {
this.storage = storage;
}

public boolean isRedirect() {
return redirect;
}

public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ private void addUriToAddedNodesModel(final String uri) {
});
}

protected void setRedirect(String originalUrl, String redirectedUrl) {
ThreadUtils.invokeLater(() -> extClient.setRedirect(originalUrl, redirectedUrl));
}

@Override
public int getProgress() {
if (finished && !stopped) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public void run() {
startTime = System.currentTimeMillis();
wd.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(this.timeout));
wd.get(url);
String actualUrl = wd.getCurrentUrl();
if (!url.equals(actualUrl)) {
clientSpider.setRedirect(url, actualUrl);
}
ok = true;
} catch (Exception e) {
LOGGER.warn("Task failed {} {}", url, e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ public class ClientMapTreeCellRenderer extends DefaultTreeCellRenderer {
ExtensionClientIntegration.getIcon("sitemap-application-blue.png");
private static final ImageIcon LEAF_ICON =
ExtensionClientIntegration.getIcon("blue-document.png");
private static final ImageIcon LEAF_NOT_VISITED_ICON =
ExtensionClientIntegration.getIcon("blue-document--minus.png");
private static final ImageIcon FRAGMENT_ICON =
ExtensionClientIntegration.getIcon("blue-document-number.png");
private static final ImageIcon FRAGMENT_NOT_VISITED_ICON =
ExtensionClientIntegration.getIcon("blue-document-number-minus.png");
private static final ImageIcon FOLDER_OPEN_ICON =
ExtensionClientIntegration.getIcon("blue-folder-horizontal-open.png");
private static final ImageIcon FOLDER_CLOSED_ICON =
ExtensionClientIntegration.getIcon("blue-folder-horizontal.png");
private static final ImageIcon NOT_VISITED_OVERLAY =
ExtensionClientIntegration.getIcon("overlay-minus.png");
private static final ImageIcon REDIRECT_OVERLAY =
ExtensionClientIntegration.getIcon("overlay-redirect.png");
private static final ImageIcon DATABASE_ICON =
ExtensionClientIntegration.getIcon("database.png");

Expand Down Expand Up @@ -83,27 +83,23 @@ public Component getTreeCellRendererComponent(
setPreferredSize(null); // clears the preferred size, making the node visible
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

// folder / file icons with scope 'target' if relevant
if (node.isRoot()) {
component.add(wrap(ROOT_ICON)); // 'World' icon
component.add(wrap(ROOT_ICON));
} else {
ClientSideDetails csd = node.getUserObject();
OverlayIcon icon;
if (csd.isStorage()) {
icon = new OverlayIcon(DATABASE_ICON);
} else if (leaf) {
if (csd.isVisited()) {
if (csd.getUrl().contains("#")) {
icon = new OverlayIcon(FRAGMENT_ICON);
} else {
icon = new OverlayIcon(LEAF_ICON);
}
if (csd.getUrl().contains("#")) {
icon = new OverlayIcon(FRAGMENT_ICON);
} else {
if (csd.getUrl().contains("#")) {
icon = new OverlayIcon(FRAGMENT_NOT_VISITED_ICON);
} else {
icon = new OverlayIcon(LEAF_NOT_VISITED_ICON);
}
icon = new OverlayIcon(LEAF_ICON);
}
if (!csd.isVisited()) {
icon.add(NOT_VISITED_OVERLAY);
} else if (csd.isRedirect()) {
icon.add(REDIRECT_OVERLAY);
}
} else {
if (expanded) {
Expand Down
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -336,4 +338,32 @@ void shouldClearTheMap() {
// Then
assertThat(map.getRoot().getChildCount(), is(0));
}

@Test
void shouldSetKnownRedirectDetails() {
// Given
ClientNode node1 = map.getOrAddNode(BBB_DDD_URL + "/", false, false);

// When
ClientNode node2 = map.setRedirect(BBB_DDD_URL + "/", AAA_URL);
Set<ClientSideComponent> components = node2.getUserObject().getComponents();
ClientSideComponent c0 = components.iterator().next();

// Then
assertThat(node1, is(node2));
assertThat(node2.getUserObject().isVisited(), is(true));
assertThat(node2.getUserObject().isRedirect(), is(true));
assertThat(components.size(), is(1));
assertThat(c0.getTagName(), is("Redirect"));
assertThat(c0.getHref(), is(AAA_URL));
}

@Test
void shouldIngnoreUnknownRedirectDetails() {
// Given / When
ClientNode node = map.setRedirect(BBB_DDD_URL + "/", AAA_URL);

// Then
assertThat(node, is(nullValue()));
}
}

0 comments on commit 585b5bc

Please sign in to comment.