Skip to content

Commit 3159ed2

Browse files
authored
Merge pull request #6253 from thc202/authhelper/diags-storage
authhelper: record/report local/session storage
2 parents 2219dcd + 1ea2ec5 commit 3159ed2

File tree

8 files changed

+160
-1
lines changed

8 files changed

+160
-1
lines changed

addOns/authhelper/src/main/java/org/zaproxy/addon/authhelper/AuthenticationDiagnostics.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.time.Instant;
2323
import java.util.List;
24+
import java.util.Map;
2425
import javax.jdo.PersistenceManager;
2526
import javax.jdo.Transaction;
2627
import org.apache.logging.log4j.LogManager;
@@ -39,6 +40,7 @@
3940
import org.parosproxy.paros.network.HttpMessage;
4041
import org.parosproxy.paros.network.HttpSender;
4142
import org.zaproxy.addon.authhelper.internal.db.Diagnostic;
43+
import org.zaproxy.addon.authhelper.internal.db.DiagnosticBrowserStorageItem;
4244
import org.zaproxy.addon.authhelper.internal.db.DiagnosticMessage;
4345
import org.zaproxy.addon.authhelper.internal.db.DiagnosticScreenshot;
4446
import org.zaproxy.addon.authhelper.internal.db.DiagnosticStep;
@@ -199,9 +201,37 @@ public void recordStep(WebDriver wd, String description, WebElement element) {
199201
}
200202
}
201203

204+
if (wd instanceof JavascriptExecutor je) {
205+
for (var type : DiagnosticBrowserStorageItem.Type.values()) {
206+
processStorage(je, type);
207+
}
208+
}
209+
202210
createStep();
203211
}
204212

213+
private <T> void processStorage(JavascriptExecutor je, DiagnosticBrowserStorageItem.Type type) {
214+
@SuppressWarnings("unchecked")
215+
List<Map<String, String>> storage =
216+
(List<Map<String, String>>) je.executeScript(type.getScript());
217+
if (storage == null || storage.isEmpty()) {
218+
return;
219+
}
220+
221+
storage.stream()
222+
.map(
223+
e -> {
224+
DiagnosticBrowserStorageItem item = new DiagnosticBrowserStorageItem();
225+
item.setCreateTimestamp(Instant.now());
226+
item.setStep(currentStep);
227+
item.setType(type);
228+
item.setKey(e.get("key"));
229+
item.setValue(e.get("value"));
230+
return item;
231+
})
232+
.forEach(currentStep.getBrowserStorageItems()::add);
233+
}
234+
205235
private DiagnosticWebElement createDiagnosticWebElement(
206236
WebDriver wd, List<WebElement> forms, WebElement element) {
207237
if (element == null) {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Zed Attack Proxy (ZAP) and its related class files.
3+
*
4+
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
5+
*
6+
* Copyright 2025 The ZAP Development Team
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
package org.zaproxy.addon.authhelper.internal.db;
21+
22+
import java.time.Instant;
23+
import javax.jdo.annotations.Cacheable;
24+
import javax.jdo.annotations.Column;
25+
import javax.jdo.annotations.IdGeneratorStrategy;
26+
import javax.jdo.annotations.PersistenceCapable;
27+
import javax.jdo.annotations.Persistent;
28+
import javax.jdo.annotations.PrimaryKey;
29+
import lombok.Data;
30+
import lombok.NoArgsConstructor;
31+
32+
@Data
33+
@NoArgsConstructor
34+
@Cacheable("false")
35+
@PersistenceCapable(table = "AUTHHELPER_DIAGNOSTIC_BROWSER_STORAGE_ITEM", detachable = "true")
36+
public class DiagnosticBrowserStorageItem {
37+
38+
private static final String STORAGE_SCRIPT =
39+
"""
40+
const data = [];
41+
for (let i = 0; i < STORAGE.length; i++) {
42+
data.push({"key": STORAGE.key(i), "value": STORAGE.getItem(STORAGE.key(i))});
43+
}
44+
return data;
45+
""";
46+
47+
public enum Type {
48+
LOCAL(STORAGE_SCRIPT.replace("STORAGE", "window.localStorage")),
49+
SESSION(STORAGE_SCRIPT.replace("STORAGE", "sessionStorage"));
50+
51+
private String script;
52+
53+
Type(String script) {
54+
this.script = script;
55+
}
56+
57+
public String getScript() {
58+
return script;
59+
}
60+
}
61+
62+
private Instant createTimestamp;
63+
64+
@PrimaryKey
65+
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
66+
private int id;
67+
68+
@Column(name = "STEPID")
69+
private DiagnosticStep step;
70+
71+
@Column(jdbcType = "INTEGER")
72+
private Type type;
73+
74+
@Column(length = 4096)
75+
private String key;
76+
77+
@Column(length = 65536)
78+
private String value;
79+
}

addOns/authhelper/src/main/java/org/zaproxy/addon/authhelper/internal/db/DiagnosticStep.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.time.Instant;
2323
import java.util.ArrayList;
2424
import java.util.List;
25+
import java.util.stream.Stream;
2526
import javax.jdo.annotations.Cacheable;
2627
import javax.jdo.annotations.Column;
2728
import javax.jdo.annotations.Element;
@@ -71,7 +72,24 @@ public class DiagnosticStep {
7172
@Order(column = "NUMBER")
7273
private List<DiagnosticWebElement> webElements = new ArrayList<>();
7374

75+
@Order(column = "NUMBER")
76+
@Persistent(mappedBy = "step")
77+
private List<DiagnosticBrowserStorageItem> browserStorageItems = new ArrayList<>();
78+
7479
public DiagnosticStep(String description) {
7580
this.description = description;
7681
}
82+
83+
public Stream<DiagnosticBrowserStorageItem> getBrowserLocalStorage() {
84+
return getBrowerStorage(DiagnosticBrowserStorageItem.Type.LOCAL);
85+
}
86+
87+
public Stream<DiagnosticBrowserStorageItem> getBrowserSessionStorage() {
88+
return getBrowerStorage(DiagnosticBrowserStorageItem.Type.SESSION);
89+
}
90+
91+
private Stream<DiagnosticBrowserStorageItem> getBrowerStorage(
92+
DiagnosticBrowserStorageItem.Type type) {
93+
return browserStorageItems.stream().filter(e -> e.getType() == type);
94+
}
7795
}

addOns/authhelper/src/main/resources/META-INF/persistence.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<persistence-unit name="authhelper">
88
<class>org.zaproxy.addon.authhelper.internal.db.Diagnostic</class>
9+
<class>org.zaproxy.addon.authhelper.internal.db.DiagnosticBrowserStorageItem</class>
910
<class>org.zaproxy.addon.authhelper.internal.db.DiagnosticMessage</class>
1011
<class>org.zaproxy.addon.authhelper.internal.db.DiagnosticScreenshot</class>
1112
<class>org.zaproxy.addon.authhelper.internal.db.DiagnosticStep</class>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
CREATE CACHED TABLE IF NOT EXISTS "AUTHHELPER_DIAGNOSTIC_BROWSER_STORAGE_ITEM" (
3+
"CREATETIMESTAMP" TIMESTAMP NULL,
4+
"ID" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
5+
"STEPID" BIGINT NOT NULL,
6+
"TYPE" INTEGER NOT NULL,
7+
"NUMBER" BIGINT NOT NULL,
8+
"KEY" VARCHAR(4096) NOT NULL,
9+
"VALUE" VARCHAR(65536) NULL,
10+
);
11+
12+
CREATE INDEX "AUTHHELPER_DIAGNOSTIC_BROWSER_STORAGE_ITEM_STEPID_IDX" ON "AUTHHELPER_DIAGNOSTIC_BROWSER_STORAGE_ITEM" ("STEPID");
13+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
report.template.invalid = There were no contexts or sites identified with relevant authentication data configured.
22
report.template.section.afenv = Automation Framework Environment
33
report.template.section.diagnostics = Diagnostics
4+
report.template.section.diagnosticslocalstorage = Local Storage for Diagnostics
45
report.template.section.diagnosticsmessages = HTTP Messages for Diagnostics
56
report.template.section.diagnosticsscreenshots = Screenshots for Diagnostics
7+
report.template.section.diagnosticssessionstorage = Session Storage for Diagnostics
68
report.template.section.diagnosticswebelements = Web Elements for Diagnostics
79
report.template.section.statistics = Statistics
810
report.template.section.summary = Summary

addOns/authhelper/src/main/zapHomeFiles/reports/auth-report-json/report.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,21 @@
6363
}[/th:block]
6464
][/th:block][#th:block th:if="${reportData.isIncludeSection('diagnosticsscreenshots') && step.screenshot}" th:with="screenshot=${step.screenshot}"]
6565
,"screenshot": [[${screenshot.data}]]
66-
[/th:block][#th:block th:if="${reportData.isIncludeSection('diagnosticsmessages')}" th:with="messages=${step.messages}"]
66+
[/th:block][#th:block th:if="${reportData.isIncludeSection('diagnosticslocalstorage')}" th:with="storage=${step.getBrowserLocalStorage()}"]
67+
,"localStorage": [[#th:block th:each="entry, state: ${storage}"][#th:block th:if="${! state.first}"],[/th:block]
68+
{
69+
"created": [[${entry.createTimestamp}]],
70+
"key": [[${entry.key}]],
71+
"value": [[${entry.value}]]
72+
}[/th:block]
73+
][/th:block][#th:block th:if="${reportData.isIncludeSection('diagnosticssessionstorage')}" th:with="storage=${step.getBrowserSessionStorage()}"]
74+
,"sessionStorage": [[#th:block th:each="entry, state: ${storage}"][#th:block th:if="${! state.first}"],[/th:block]
75+
{
76+
"created": [[${entry.createTimestamp}]],
77+
"key": [[${entry.key}]],
78+
"value": [[${entry.value}]]
79+
}[/th:block]
80+
][/th:block][#th:block th:if="${reportData.isIncludeSection('diagnosticsmessages')}" th:with="messages=${step.messages}"]
6781
,"messages": [[#th:block th:each="entry, state: ${messages}" th:with="message=${helper.getHttpMessage(entry.messageId)}"][#th:block th:if="${! state.first}"],[/th:block]
6882
{[#th:block th:if="${message}"]
6983
"created": [[${entry.createTimestamp}]],

addOns/authhelper/src/main/zapHomeFiles/reports/auth-report-json/template.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ sections:
1010
- diagnosticsmessages
1111
- diagnosticsscreenshots
1212
- diagnosticswebelements
13+
- diagnosticslocalstorage
14+
- diagnosticssessionstorage

0 commit comments

Comments
 (0)