From fc9b57863da7cfaca2c9314447ffa58bb1f9bda4 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Tue, 22 Jul 2025 09:07:36 -0400 Subject: [PATCH 1/2] scanners.md Update Time Based entries and reserved ID for SQLite Signed-off-by: kingthorin --- docs/scanners.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/scanners.md b/docs/scanners.md index a434d9646d9..b70d9f80aec 100644 --- a/docs/scanners.md +++ b/docs/scanners.md @@ -152,15 +152,15 @@ Scan rules: 40016 Persistent XSS (Prime) 40017 Persistent XSS (Spider) 40018 SQL Injection -40019 SQL Injection MySQL (Timing Based) -40020 SQL Injection Hypersonic (Timing Based) -40021 SQL Injection Oracle (Timing Based) -40022 SQL Injection Postgresql (Timing Based) +40019 SQL Injection MySQL (Time Based) +40020 SQL Injection Hypersonic (Time Based) +40021 SQL Injection Oracle (Time Based) +40022 SQL Injection Postgresql (Time Based) 40023 Username Enumeration -40024 SQL Injection SQLite +40024 SQL Injection SQLite (Time Based) 40025 Proxy Disclosure 40026 Cross site scripting (DOM) -40027 SQL Injection MsSQL (Timing Based) +40027 SQL Injection MsSQL (Time Based) 40028 ELMAH Scanner 40029 trace.axd Scanner 40030 Backslash Powered Scanner @@ -221,9 +221,9 @@ Scan rules: 90034 Cloud Metadata Attack 90035 Server Side Template Injection 90036 Server Side Template Injection (Blind) -90037 Command Injection (Timing Based) -90038 SQL Injection SQLite (Timing Based) -90039 NoSQL Injection MongoDB (Timing Based) +90037 Command Injection (Time Based) +90038 SQL Injection SQLite (For future use, non-Time Based attacks) +90039 NoSQL Injection MongoDB (Time Based) 90040 DNS add-on SPF rule 100000 Client/Server HTTP Error Response Codes [Script] From d8c3934f77f65fab7e8de0df1794dba26dd847fb Mon Sep 17 00:00:00 2001 From: Simon Bennetts Date: Tue, 22 Jul 2025 14:38:39 +0100 Subject: [PATCH 2/2] SessionStructure - remove deprecated methods and add tests Remove methods that were deprecated in 2.10.0. Add unit tests which document the existing behavior for some of the name related methogs. These will be refactored in #9002 (which will be rebased on top of these changes) Signed-off-by: Simon Bennetts --- zap/gradle/japicmp.yaml | 7 +- .../zaproxy/zap/model/SessionStructure.java | 87 ------------ .../zap/model/SessionStructureUnitTest.java | 132 +++++++++++++++++- 3 files changed, 133 insertions(+), 93 deletions(-) diff --git a/zap/gradle/japicmp.yaml b/zap/gradle/japicmp.yaml index 693cfad2cea..a441996f8a2 100644 --- a/zap/gradle/japicmp.yaml +++ b/zap/gradle/japicmp.yaml @@ -7,4 +7,9 @@ fieldExcludes: [] classExcludes: - "org.parosproxy.paros.core.scanner.VariantAbstractRPCQuery$RPCParameter" - "org.parosproxy.paros.core.scanner.VariantJSONQuery$SimpleStringReader" -methodExcludes: [] +methodExcludes: + - "org.zaproxy.zap.model.SessionStructure#addPath(org.parosproxy.paros.model.Session,org.parosproxy.paros.model.HistoryReference,org.parosproxy.paros.network.HttpMessage)" + - "org.zaproxy.zap.model.SessionStructure#addPath(org.parosproxy.paros.model.Session,org.parosproxy.paros.model.HistoryReference,org.parosproxy.paros.network.HttpMessage,boolean)" + - "org.zaproxy.zap.model.SessionStructure#find(long,org.apache.commons.httpclient.URI,java.lang.String,java.lang.String)" + - "org.zaproxy.zap.model.SessionStructure#getNodeName(org.parosproxy.paros.network.HttpMessage)" + - "org.zaproxy.zap.model.SessionStructure#getRootNode()" \ No newline at end of file diff --git a/zap/src/main/java/org/zaproxy/zap/model/SessionStructure.java b/zap/src/main/java/org/zaproxy/zap/model/SessionStructure.java index fffb831fd92..6a2f21bbf83 100644 --- a/zap/src/main/java/org/zaproxy/zap/model/SessionStructure.java +++ b/zap/src/main/java/org/zaproxy/zap/model/SessionStructure.java @@ -53,20 +53,6 @@ public class SessionStructure { private static final Logger LOGGER = LogManager.getLogger(SessionStructure.class); - /** - * Adds the message to the Sites tree - * - * @param session the session - * @param ref the history reference - * @param msg the message - * @return the node added to the Sites Tree - * @deprecated Use {@link #addPath(Model, HistoryReference, HttpMessage)} - */ - @Deprecated - public static StructuralNode addPath(Session session, HistoryReference ref, HttpMessage msg) { - return addPath(session, ref, msg, false); - } - /** * Adds the message to the Sites tree * @@ -80,23 +66,6 @@ public static StructuralNode addPath(Model model, HistoryReference ref, HttpMess return addPath(model, ref, msg, false); } - /** - * Adds the message to the Sites tree - * - * @param session the session - * @param ref the history reference - * @param msg the message - * @param newOnly Only return a SiteNode if one was newly created - * @return the SiteNode that corresponds to the HttpMessage, or null if newOnly and the node - * already exists - * @deprecated Use {@link #addPath(Model, HistoryReference, HttpMessage, boolean)} - */ - @Deprecated - public static StructuralNode addPath( - Session session, HistoryReference ref, HttpMessage msg, boolean newOnly) { - return addPath(Model.getSingleton(), ref, msg, newOnly); - } - /** * Adds the message to the Sites tree * @@ -189,38 +158,6 @@ public static StructuralNode find(Model model, HttpMessage msg) return new StructuralTableNode(rs); } - /** - * Finds the node in the Site tree for the given request data - * - * @param sessionId the session id - * @param uri the URI - * @param method the method - * @param postData the POST data - * @return the site node or null if not found - * @throws DatabaseException - * @throws URIException - * @deprecated Use {@link #find(Model, URI, String, String)} - */ - @Deprecated - public static StructuralNode find(long sessionId, URI uri, String method, String postData) - throws DatabaseException, URIException { - Model model = Model.getSingleton(); - if (!Constant.isLowMemoryOptionSet()) { - SiteNode node = model.getSession().getSiteTree().findNode(uri, method, postData); - if (node == null) { - return null; - } - return new StructuralSiteNode(node); - } - - String nodeName = getNodeName(model, uri, method, postData, null); - RecordStructure rs = model.getDb().getTableStructure().find(sessionId, nodeName, method); - if (rs == null) { - return null; - } - return new StructuralTableNode(rs); - } - /** * Finds the node in the Site tree for the given request data * @@ -284,19 +221,6 @@ private static String getNodeName( return nodeUrl; } - /** - * Returns the node name for the given message - * - * @param msg the message - * @return the node name - * @throws URIException - * @deprecated Use {@link #getNodeName(Model, HttpMessage)} - */ - @Deprecated - public static String getNodeName(HttpMessage msg) throws URIException { - return getNodeName(Model.getSingleton(), msg); - } - /** * Returns the node name for the given message * @@ -697,17 +621,6 @@ private static String getScheme(URI uri) { return scheme.toLowerCase(Locale.ROOT); } - /** - * Returns the root node - * - * @return the root node - * @deprecated Use {@link #getRootNode(Model)} - */ - @Deprecated - public static StructuralNode getRootNode() { - return getRootNode(Model.getSingleton()); - } - /** * Returns the root node * diff --git a/zap/src/test/java/org/zaproxy/zap/model/SessionStructureUnitTest.java b/zap/src/test/java/org/zaproxy/zap/model/SessionStructureUnitTest.java index 3328f905e7e..a64cae3cf78 100644 --- a/zap/src/test/java/org/zaproxy/zap/model/SessionStructureUnitTest.java +++ b/zap/src/test/java/org/zaproxy/zap/model/SessionStructureUnitTest.java @@ -472,14 +472,136 @@ void shouldReturnOverridenPathTree() throws Exception { } } + @Nested + static class NodeNameTests { + + private Model model; + private Session session; + private VariantFactory factory; + + HttpMessage getParams; + HttpMessage postParamsFormData; + HttpMessage postParamsJsonData; + HttpMessage postParamsXmlData; + HttpMessage postMultipartData; + + @BeforeEach + void setup() throws Exception { + WithConfigsTest.setUpConstantMessages(); + model = mock(Model.class); + session = new Session(model); + factory = new VariantFactory(); + given(model.getSession()).willReturn(session); + given(model.getVariantFactory()).willReturn(factory); + getParams = + new HttpMessage(new URI("https://www.example.com/aaa/bbb?aa=bb&cc=dd", false)); + postParamsFormData = + getPostMsgWithFormParams( + "https://www.example.com/ccc", "aa=bb&cc=dd", "ee=ff&gg=ee"); + postParamsJsonData = + getPostMsg( + "https://www.example.com/ccc", + "aa=bb&cc=dd", + "{\"aaa\":\"bbb\", \"ccc\":\"ddd\", \"eee\":\"fff\"}", + "application/json"); + postParamsXmlData = + getPostMsg( + "https://www.example.com/ccc", + "aa=bb&cc=dd", + "BBBCCCDDD", + "text/xml"); + Control.initSingletonForTesting(model); + } + + @AfterEach + void cleanUp() { + Constant.messages = null; + } + + @Test + void shouldGetNodeName() throws URIException { + assertThat( + SessionStructure.getNodeName(model, getParams), + is(equalTo("https://www.example.com/aaa/bbb (aa,cc)"))); + assertThat( + SessionStructure.getNodeName(model, postParamsFormData), + is(equalTo("https://www.example.com/ccc (aa,cc)(ee,gg)"))); + // FIXME should have the JSON key names + assertThat( + SessionStructure.getNodeName(model, postParamsJsonData), + is(equalTo("https://www.example.com/ccc (aa,cc)"))); + // FIXME should have the XML key names + assertThat( + SessionStructure.getNodeName(model, postParamsXmlData), + is(equalTo("https://www.example.com/ccc (aa,cc)"))); + } + + @Test + void shouldGetLeafName1() throws URIException { + assertThat( + SessionStructure.getLeafName(model, "test", getParams), + is(equalTo("GET:test(aa,cc)"))); + assertThat( + SessionStructure.getLeafName(model, "test", postParamsFormData), + is(equalTo("POST:test(aa,cc)(ee,gg)"))); + // FIXME should have the JSON key names + assertThat( + SessionStructure.getLeafName(model, "test", postParamsJsonData), + is( + equalTo( + "POST:test(aa,cc)({\"aaa\":\"bbb\", \"ccc\":\"ddd\", \"eee\":\"fff\"})"))); + // FIXME should have the XML key names + assertThat( + SessionStructure.getLeafName(model, "test", postParamsXmlData), + is(equalTo("POST:test(aa,cc)(BBBCCCDD...)"))); + } + + @Test + void shouldGetLeafName2() throws Exception { + assertThat(getLeafName2(getParams), is(equalTo("GET:test(aa,cc)"))); + assertThat(getLeafName2(postParamsFormData), is(equalTo("POST:test(aa,cc)(ee,gg)"))); + // FIXME should have the JSON key names + assertThat( + getLeafName2(postParamsJsonData), + is( + equalTo( + "POST:test(aa,cc)({\"aaa\":\"bbb\", \"ccc\":\"ddd\", \"eee\":\"fff\"})"))); + // FIXME should have the XML key names + assertThat( + getLeafName2(postParamsXmlData), + is(equalTo("POST:test(aa,cc)(BBBCCCDD...)"))); + } + + String getLeafName2(HttpMessage msg) throws Exception { + return SessionStructure.getLeafName( + model, + "test", + msg.getRequestHeader().getURI(), + msg.getRequestHeader().getMethod(), + msg.getRequestBody().toString()); + } + } + private void createPostMsgWithFormParams(String uri, String queryParams, String formParams) throws URIException { - msg.getRequestHeader().setMethod(HttpRequestHeader.POST); + msg = getPostMsgWithFormParams(uri, queryParams, formParams); + } + + private static HttpMessage getPostMsgWithFormParams( + String uri, String queryParams, String formParams) throws URIException { + return getPostMsg(uri, queryParams, formParams, "application/x-www-form-urlencoded"); + } + + private static HttpMessage getPostMsg( + String uri, String queryParams, String formParams, String contentType) + throws URIException { + HttpMessage message = new HttpMessage(); + message.getRequestHeader().setMethod(HttpRequestHeader.POST); queryParams = queryParams == null ? "" : "?" + queryParams; - msg.getRequestHeader().setURI(new URI(uri + queryParams, true)); - msg.getRequestHeader() - .setHeader(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); - msg.setRequestBody(formParams); + message.getRequestHeader().setURI(new URI(uri + queryParams, true)); + message.getRequestHeader().setHeader(HttpHeader.CONTENT_TYPE, contentType); + message.setRequestBody(formParams); + return message; } public static final class PathTreeVariant implements Variant {