Skip to content

Commit 05bbdf7

Browse files
committed
fix(scan): correct deduplication logic and integrate custom tab
1 parent 7250f2e commit 05bbdf7

File tree

6 files changed

+93
-27
lines changed

6 files changed

+93
-27
lines changed

src/main/java/com/arqsz/burpgitleaks/BurpExtender.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.arqsz.burpgitleaks.config.PluginSettings;
88
import com.arqsz.burpgitleaks.config.RuleLoader;
99
import com.arqsz.burpgitleaks.config.RuleLoader.GitleaksConfiguration;
10+
import com.arqsz.burpgitleaks.scan.GitleaksAuditIssueHandler;
1011
import com.arqsz.burpgitleaks.scan.GitleaksHttpHandler;
1112
import com.arqsz.burpgitleaks.scan.GitleaksScanCheck;
1213
import com.arqsz.burpgitleaks.ui.GitleaksContextMenuProvider;
@@ -44,7 +45,9 @@ public void initialize(MontoyaApi api) {
4445
ConfigResult configResult = loadInitialConfiguration(api, settings);
4546
GitleaksConfiguration config = configResult.config;
4647

47-
var components = registerComponents(api, config, settings);
48+
TemplateManager templateManager = new TemplateManager(api.logging());
49+
50+
var components = registerComponents(api, config, settings, templateManager);
4851

4952
handleStartupFeedback(api, config, configResult.errorMsg());
5053

@@ -94,28 +97,29 @@ private ConfigResult loadInitialConfiguration(MontoyaApi api, PluginSettings set
9497
}
9598

9699
private RegisteredComponents registerComponents(MontoyaApi api, GitleaksConfiguration config,
97-
PluginSettings settings) {
98-
TemplateManager templateManager = new TemplateManager(api.logging());
100+
PluginSettings settings, TemplateManager templateManager) {
99101
this.issuesTab = new IssuesTab(api, ISSUES_TAB_NAME, templateManager);
100102

101103
if (settings.isShowIssuesTab()) {
102104
registerIssuesTab();
103105
}
104106

105-
GitleaksScanCheck scanCheck = new GitleaksScanCheck(api, config, settings, issuesTab);
107+
GitleaksScanCheck scanCheck = new GitleaksScanCheck(api, config, settings);
106108

107109
BurpSuiteEdition edition = api.burpSuite().version().edition();
108110

109111
if (edition == BurpSuiteEdition.COMMUNITY_EDITION) {
110112
api.logging().logToOutput("Community Edition detected: Activating manual traffic handler.");
111-
this.communityHttpHandler = new GitleaksHttpHandler(api, scanCheck, settings);
113+
this.communityHttpHandler = new GitleaksHttpHandler(api, scanCheck, settings, issuesTab);
112114
api.http().registerHttpHandler(communityHttpHandler);
113115
} else {
114116
api.scanner().registerPassiveScanCheck(scanCheck, ScanCheckType.PER_REQUEST);
117+
GitleaksAuditIssueHandler auditHandler = new GitleaksAuditIssueHandler(issuesTab, settings);
118+
api.scanner().registerAuditIssueHandler(auditHandler);
115119
}
116120

117121
GitleaksContextMenuProvider menuProvider = new GitleaksContextMenuProvider(api, scanCheck, settings,
118-
templateManager);
122+
templateManager, issuesTab);
119123
api.userInterface().registerContextMenuItemsProvider(menuProvider);
120124

121125
SettingsTab settingsTab = new SettingsTab(api, scanCheck, settings, config.rules(), (visible) -> {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.arqsz.burpgitleaks.scan;
2+
3+
import com.arqsz.burpgitleaks.config.PluginSettings;
4+
import com.arqsz.burpgitleaks.ui.IssuesTab;
5+
6+
import burp.api.montoya.scanner.audit.AuditIssueHandler;
7+
import burp.api.montoya.scanner.audit.issues.AuditIssue;
8+
9+
public class GitleaksAuditIssueHandler implements AuditIssueHandler {
10+
11+
private final IssuesTab issuesTab;
12+
private final PluginSettings settings;
13+
14+
public GitleaksAuditIssueHandler(IssuesTab issuesTab, PluginSettings settings) {
15+
this.issuesTab = issuesTab;
16+
this.settings = settings;
17+
}
18+
19+
@Override
20+
public void handleNewAuditIssue(AuditIssue auditIssue) {
21+
if (!settings.isShowIssuesTab()) {
22+
return;
23+
}
24+
25+
if (auditIssue.name().startsWith("Secret leakage")) {
26+
issuesTab.addIssue(auditIssue);
27+
}
28+
}
29+
}

src/main/java/com/arqsz/burpgitleaks/scan/GitleaksHttpHandler.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.concurrent.Executors;
55

66
import com.arqsz.burpgitleaks.config.PluginSettings;
7+
import com.arqsz.burpgitleaks.ui.IssuesTab;
78

89
import burp.api.montoya.MontoyaApi;
910
import burp.api.montoya.core.ToolType;
@@ -22,11 +23,14 @@ public class GitleaksHttpHandler implements HttpHandler {
2223
private final GitleaksScanCheck scanCheck;
2324
private final PluginSettings settings;
2425
private final ExecutorService executor;
26+
private final IssuesTab issuesTab;
2527

26-
public GitleaksHttpHandler(MontoyaApi api, GitleaksScanCheck scanCheck, PluginSettings settings) {
28+
public GitleaksHttpHandler(MontoyaApi api, GitleaksScanCheck scanCheck, PluginSettings settings,
29+
IssuesTab issuesTab) {
2730
this.api = api;
2831
this.scanCheck = scanCheck;
2932
this.settings = settings;
33+
this.issuesTab = issuesTab;
3034
this.executor = Executors.newFixedThreadPool(3);
3135
}
3236

@@ -65,6 +69,10 @@ private void runScan(HttpRequestResponse reqRes) {
6569

6670
for (AuditIssue issue : result.auditIssues()) {
6771
api.siteMap().add(issue);
72+
73+
if (settings.isShowIssuesTab()) {
74+
issuesTab.addIssue(issue);
75+
}
6876
}
6977
}
7078

src/main/java/com/arqsz/burpgitleaks/scan/GitleaksScanCheck.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import com.arqsz.burpgitleaks.config.GitleaksRule;
1414
import com.arqsz.burpgitleaks.config.PluginSettings;
1515
import com.arqsz.burpgitleaks.config.RuleLoader.GitleaksConfiguration;
16-
import com.arqsz.burpgitleaks.ui.IssuesTab;
1716
import com.arqsz.burpgitleaks.utils.Entropy;
1817
import com.google.re2j.Matcher;
1918
import com.google.re2j.Pattern;
@@ -49,20 +48,17 @@ public class GitleaksScanCheck implements PassiveScanCheck {
4948
private final PluginSettings settings;
5049
private final Logging logging;
5150
private final MontoyaApi api;
52-
private final IssuesTab issuesTab;
5351

5452
private record ScanState(
5553
List<GitleaksRule> rules,
5654
List<GitleaksAllowlist> allowlists,
5755
Trie keywordTrie) {
5856
}
5957

60-
public GitleaksScanCheck(MontoyaApi api, GitleaksConfiguration config, PluginSettings settings,
61-
IssuesTab issuesTab) {
58+
public GitleaksScanCheck(MontoyaApi api, GitleaksConfiguration config, PluginSettings settings) {
6259
this.api = api;
6360
this.logging = api.logging();
6461
this.settings = settings;
65-
this.issuesTab = issuesTab;
6662
updateConfig(config);
6763
}
6864

@@ -302,10 +298,6 @@ private AuditIssue createAuditIssue(GitleaksRule rule, String secret, String ful
302298
AuditIssueSeverity.HIGH,
303299
baseReq.withResponseMarkers(markers));
304300

305-
if (settings.isShowIssuesTab()) {
306-
issuesTab.addIssue(issue);
307-
}
308-
309301
return issue;
310302
}
311303

src/main/java/com/arqsz/burpgitleaks/ui/GitleaksContextMenuProvider.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.arqsz.burpgitleaks.verification.TemplateManager;
1717

1818
import burp.api.montoya.MontoyaApi;
19+
import burp.api.montoya.core.BurpSuiteEdition;
1920
import burp.api.montoya.http.message.HttpRequestResponse;
2021
import burp.api.montoya.scanner.AuditResult;
2122
import burp.api.montoya.scanner.audit.issues.AuditIssue;
@@ -31,12 +32,14 @@ public class GitleaksContextMenuProvider implements ContextMenuItemsProvider {
3132
private final ExecutorService executor;
3233
private final PluginSettings settings;
3334
private final VerificationMenuFactory menuFactory;
35+
private final IssuesTab issuesTab;
3436

3537
public GitleaksContextMenuProvider(MontoyaApi api, GitleaksScanCheck scanCheck,
36-
PluginSettings settings, TemplateManager templateManager) {
38+
PluginSettings settings, TemplateManager templateManager, IssuesTab issuesTab) {
3739
this.api = api;
3840
this.scanCheck = scanCheck;
3941
this.settings = settings;
42+
this.issuesTab = issuesTab;
4043
this.executor = Executors.newSingleThreadExecutor();
4144
this.menuFactory = new VerificationMenuFactory(api, templateManager);
4245
}
@@ -100,16 +103,27 @@ private void performManualScan(List<HttpRequestResponse> items) {
100103
}
101104

102105
for (AuditIssue newIssue : result.auditIssues()) {
103-
if (isAlreadyReported(newIssue)) {
106+
boolean addedToTab = false;
107+
if (settings.isShowIssuesTab()) {
108+
addedToTab = issuesTab.addIssue(newIssue);
109+
}
110+
111+
boolean alreadyInSiteMap = isAlreadyReported(newIssue);
112+
113+
if (!alreadyInSiteMap) {
114+
api.siteMap().add(newIssue);
115+
}
116+
117+
api.logging().logToOutput("Manual scan found issue: " + alreadyInSiteMap);
118+
119+
if (!alreadyInSiteMap || addedToTab) {
120+
issuesFound++;
121+
} else {
104122
duplicatesIgnored++;
105123
if (settings.isDebugEnabled()) {
106124
api.logging().logToOutput("Ignored duplicate: " + newIssue.name() + " @ " + newIssue.baseUrl());
107125
}
108-
continue;
109126
}
110-
111-
api.siteMap().add(newIssue);
112-
issuesFound++;
113127
}
114128
}
115129

@@ -152,6 +166,10 @@ private String buildResultToastMessage(int issuesFound, int duplicatesIgnored) {
152166
}
153167

154168
private boolean isAlreadyReported(AuditIssue newIssue) {
169+
if (api.burpSuite().version().edition() == BurpSuiteEdition.COMMUNITY_EDITION) {
170+
return true;
171+
}
172+
155173
List<AuditIssue> existingIssues = api.siteMap().issues(
156174
SiteMapFilter.prefixFilter(newIssue.baseUrl()));
157175

src/main/java/com/arqsz/burpgitleaks/ui/IssuesTab.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ public class IssuesTab extends JPanel {
5858
private final HttpResponseEditor responseViewer;
5959
private final JEditorPane advisoryPane;
6060

61-
private final TemplateManager templateManager;
6261
private final VerificationMenuFactory menuFactory;
6362

6463
private String tabTitle;
@@ -74,7 +73,6 @@ public IssuesTab(MontoyaApi api, String tabTitle, TemplateManager templateManage
7473
this.tabTitle = tabTitle;
7574
}
7675

77-
this.templateManager = templateManager;
7876
this.menuFactory = new VerificationMenuFactory(api, templateManager);
7977

8078
this.model = new IssuesTableModel();
@@ -228,13 +226,30 @@ public void popupMenuCanceled(PopupMenuEvent e) {
228226
});
229227
}
230228

231-
public void addIssue(AuditIssue issue) {
232-
SwingUtilities.invokeLater(() -> {
229+
public boolean addIssue(AuditIssue issue) {
230+
if (SwingUtilities.isEventDispatchThread()) {
233231
boolean added = model.add(issue);
234232
if (added) {
235233
updateTabTitle(model.getRowCount());
236234
}
237-
});
235+
return added;
236+
}
237+
238+
final boolean[] result = new boolean[1];
239+
240+
try {
241+
SwingUtilities.invokeAndWait(() -> {
242+
result[0] = model.add(issue);
243+
if (result[0]) {
244+
updateTabTitle(model.getRowCount());
245+
}
246+
});
247+
} catch (Exception e) {
248+
api.logging().logToError("Error adding issue to tab: " + e.getMessage());
249+
return false;
250+
}
251+
252+
return result[0];
238253
}
239254

240255
private void deleteSelectedIssues() {

0 commit comments

Comments
 (0)