From 2a60b13fa2b5ebe94e8928c66fcb713b1ab48f3d Mon Sep 17 00:00:00 2001 From: kingthorin Date: Sat, 6 Sep 2025 08:34:09 -0400 Subject: [PATCH] tech detection: Add link with sites tree button Signed-off-by: kingthorin --- addOns/wappalyzer/CHANGELOG.md | 1 + .../wappalyzer/ExtensionWappalyzer.java | 18 +---- .../zap/extension/wappalyzer/TechPanel.java | 72 +++++++++++++++++++ .../resources/help/contents/wappalyzer.html | 5 +- .../wappalyzer/resources/Messages.properties | 3 + 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/addOns/wappalyzer/CHANGELOG.md b/addOns/wappalyzer/CHANGELOG.md index ebe8cb664f4..b4f6cb274c0 100644 --- a/addOns/wappalyzer/CHANGELOG.md +++ b/addOns/wappalyzer/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased ### Changed - Maintenance changes. +- The Technology panel toolbar now includes a toggle button to link its displayed contents to the Sites Tree selection. ### Fixed - Icon sizing in the Technology table when a transparent placeholder needs to be used. diff --git a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java index d5c6a5d1520..a31ecb42fd1 100644 --- a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java +++ b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java @@ -56,14 +56,9 @@ import org.zaproxy.zap.extension.search.ExtensionSearch; import org.zaproxy.zap.utils.ThreadUtils; import org.zaproxy.zap.view.ScanPanel; -import org.zaproxy.zap.view.SiteMapListener; -import org.zaproxy.zap.view.SiteMapTreeCellRenderer; public class ExtensionWappalyzer extends ExtensionAdaptor - implements SessionChangedListener, - SiteMapListener, - ApplicationHolder, - ExampleAlertProvider { + implements SessionChangedListener, ApplicationHolder, ExampleAlertProvider { public static final String NAME = "ExtensionWappalyzer"; @@ -173,7 +168,6 @@ public void hook(ExtensionHook extensionHook) { super.hook(extensionHook); extensionHook.addSessionListener(this); - extensionHook.addSiteMapListener(this); if (hasView()) { @SuppressWarnings("unused") @@ -363,16 +357,6 @@ public void search(Pattern p, ExtensionSearch.Type type) { } } - @Override - public void nodeSelected(SiteNode node) { - // Event from SiteMapListenner - this.getTechPanel().siteSelected(normalizeSite(node.getHistoryReference().getURI())); - } - - @Override - public void onReturnNodeRendererComponent( - SiteMapTreeCellRenderer arg0, boolean arg1, SiteNode arg2) {} - @Override public void sessionAboutToChange(Session arg0) { // Ignore diff --git a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java index 1e1ed896a42..b88e9545ca4 100644 --- a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java +++ b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java @@ -39,10 +39,15 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JToggleButton; import javax.swing.JToolBar; +import javax.swing.JTree; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import javax.swing.table.TableCellRenderer; +import javax.swing.tree.TreePath; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.renderer.DefaultTableRenderer; import org.jdesktop.swingx.renderer.MappedValue; @@ -50,6 +55,7 @@ import org.parosproxy.paros.Constant; import org.parosproxy.paros.control.Control; import org.parosproxy.paros.extension.AbstractPanel; +import org.parosproxy.paros.model.SiteNode; import org.parosproxy.paros.view.View; import org.zaproxy.zap.utils.DisplayUtils; import org.zaproxy.zap.utils.SortedComboBoxModel; @@ -76,9 +82,13 @@ public class TechPanel extends AbstractPanel { private TechTableModel techModel = new TechTableModel(); private TableExportButton exportButton = null; + private ZapToggleButton linkWithSitesTreeButton; private ZapToggleButton enableButton = null; private JButton optionsButton; + private boolean linkWithSitesTreeSelection; + private LinkWithSitesTreeSelectionListener linkWithSitesTreeSelectionListener; + private static final Icon TRANSPARENT_ICON = new Icon() { @@ -167,6 +177,7 @@ private JToolBar getPanelToolbar() { panelToolbar.add( new JLabel(Constant.messages.getString("wappalyzer.toolbar.site.label"))); panelToolbar.add(getSiteSelect()); + panelToolbar.add(getLinkWithSitesTreeButton()); panelToolbar.add(getExportButton()); panelToolbar.add(getEnableToggleButton()); @@ -386,4 +397,65 @@ private JButton getOptionsButton() { } return optionsButton; } + + private JToggleButton getLinkWithSitesTreeButton() { + if (linkWithSitesTreeButton == null) { + linkWithSitesTreeButton = new ZapToggleButton(); + linkWithSitesTreeButton.setIcon( + new ImageIcon(TechPanel.class.getResource("/resource/icon/16/earth-grey.png"))); + linkWithSitesTreeButton.setToolTipText( + Constant.messages.getString( + "wappalyzer.toolbar.toggle.site.link.disabled.tooltip")); + linkWithSitesTreeButton.setSelectedIcon( + new ImageIcon(TechPanel.class.getResource("/resource/icon/16/094.png"))); + linkWithSitesTreeButton.setSelectedToolTipText( + Constant.messages.getString( + "wappalyzer.toolbar.toggle.site.link.enabled.tooltip")); + DisplayUtils.scaleIcon(linkWithSitesTreeButton); + setLinkWithSitesTreeSelection(true); + linkWithSitesTreeButton.addActionListener( + e -> { + linkWithSitesTreeSelection = linkWithSitesTreeButton.isSelected(); + setLinkWithSitesTreeSelection(linkWithSitesTreeSelection); + }); + } + return linkWithSitesTreeButton; + } + + public void setLinkWithSitesTreeSelection(boolean enabled) { + linkWithSitesTreeButton.setSelected(enabled); + final JTree sitesTree = View.getSingleton().getSiteTreePanel().getTreeSite(); + if (enabled) { + final TreePath selectionPath = sitesTree.getSelectionPath(); + if (selectionPath != null) { + siteSelected( + ExtensionWappalyzer.normalizeSite( + ((SiteNode) selectionPath.getLastPathComponent()) + .getHistoryReference() + .getURI())); + } + sitesTree.addTreeSelectionListener(getLinkWithSitesTreeSelectionListener()); + } else { + sitesTree.removeTreeSelectionListener(getLinkWithSitesTreeSelectionListener()); + } + } + + private LinkWithSitesTreeSelectionListener getLinkWithSitesTreeSelectionListener() { + if (linkWithSitesTreeSelectionListener == null) { + linkWithSitesTreeSelectionListener = new LinkWithSitesTreeSelectionListener(); + } + return linkWithSitesTreeSelectionListener; + } + + private class LinkWithSitesTreeSelectionListener implements TreeSelectionListener { + + @Override + public void valueChanged(TreeSelectionEvent e) { + siteSelected( + ExtensionWappalyzer.normalizeSite( + ((SiteNode) e.getPath().getLastPathComponent()) + .getHistoryReference() + .getURI())); + } + } } diff --git a/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html b/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html index d7d3e4e4f13..a5a061362bc 100644 --- a/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html +++ b/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html @@ -22,12 +22,15 @@

The Technology Tab

Selecting a regex will switch to the 'Search' tab and search through the history for that regex. Note: If multiple rows are selected the menu will not be displayed.

-Beside the site selection drop down is an Export button which can be used to export a CSV (comma separated values) file based on the +Beside the site selection drop down is a button (with a Globe icon) which controls whether or not the Technology tab's display is linked to the selection in the Sites Tree. +

+Next is an Export button which can be used to export a CSV (comma separated values) file based on the table information currently being displayed.

The toolbar also includes:

  • An enable/disable toggle button which controls whether the technology detection passive scan rule is functioning or not. This enabled state is persisted between ZAP sessions.
  • +
  • A button (with a gear icon) which will open the add-on's Options panel when clicked.

Reporting

diff --git a/addOns/wappalyzer/src/main/resources/org/zaproxy/zap/extension/wappalyzer/resources/Messages.properties b/addOns/wappalyzer/src/main/resources/org/zaproxy/zap/extension/wappalyzer/resources/Messages.properties index e8c83d19a55..edff7da5f1f 100644 --- a/addOns/wappalyzer/src/main/resources/org/zaproxy/zap/extension/wappalyzer/resources/Messages.properties +++ b/addOns/wappalyzer/src/main/resources/org/zaproxy/zap/extension/wappalyzer/resources/Messages.properties @@ -84,6 +84,9 @@ wappalyzer.toolbar.options.name = Options wappalyzer.toolbar.site.label = Site: wappalyzer.toolbar.site.select = -- Select Site -- +wappalyzer.toolbar.toggle.site.link.disabled.tooltip = Link with Sites Selection +wappalyzer.toolbar.toggle.site.link.enabled.tooltip = Unlink with Sites Selection + wappalyzer.toolbar.toggle.state.disabled = Disabled wappalyzer.toolbar.toggle.state.disabled.tooltip = Click to Enable Technology Detection wappalyzer.toolbar.toggle.state.enabled = Enabled