Skip to content

Commit

Permalink
## [v1.1.16] - 2024-02-02
Browse files Browse the repository at this point in the history
### Changed
- bugfix: fixed bug in tracking token68 in Authorization bearer header(which used in OAuth2.0)
### Added
- improve: Added feature of tracking "Rails" csrf-token in meta tag
  • Loading branch information
gdgd009xcd authored Feb 2, 2024
2 parents 6bdccb5 + cc5f5cf commit 1cd4738
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 163 deletions.
6 changes: 6 additions & 0 deletions addOns/automacrobuilder/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
All notable changes to this add-on will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [v1.1.16] - 2024-02-02
### Changed
- bugfix: fixed bug in tracking token68 in Authorization bearer header(which used in OAuth2.0)
### Added
- improve: Added feature of tracking "Rails" csrf-token in meta tag

## [v1.1.15] - 2024-01-24
### Changed
- bugfix: fixed bug in related to misuse of displaying icons in StyledDocument
Expand Down
2 changes: 1 addition & 1 deletion addOns/automacrobuilder/automacrobuilder.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import org.zaproxy.gradle.addon.AddOnStatus

version = "1.1.15"
version = "1.1.16"
description = "AutoMacroBuilder for ZAP"

tasks.withType<JavaCompile> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ public enum TokenTypeNames {
TEXTAREA,
JSON,
ACTION,
META,

};

private boolean urlencode; // Whether to encode URL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/** @author tms783 */
public class ParmGenParser implements DeepClone {

final private static org.apache.logging.log4j.Logger LOGGER4J =
org.apache.logging.log4j.LogManager.getLogger();
// get the factory
String htmltext;
Document doc;
Elements elems;
Map<ParmGenTokenKey, ParmGenTokenValue> map;
Map<ParmGenTokenKey, ParmGenTokenValue> defmap; // T_DEFAULT
// target tags: input|A|HREF|META
// private static String tagSelector = "input,a[href],form[action],textarea,meta";
private static String tagSelector = "[name],a[href],form[action]";

private void init() {
htmltext = null;
Expand All @@ -46,7 +50,7 @@ private void init() {
defmap = null;
}

// tokenらしき値を自動引継ぎ
// tracking token parser
public ParmGenParser(String htmltext) {
setup(htmltext);
}
Expand All @@ -59,60 +63,62 @@ private void setup(String htmltext) {
Elements elems = null;

try {
doc = Jsoup.parse(htmltext); // パース実行
doc = Jsoup.parse(htmltext);
// elems =
// doc.select("input[type=hidden],input[type=text],input[type=tel],input[type=url],
// input[type=email],
// input[type=search],input[type=number],input[type=email],a[href],form[action],textarea");//name属性を持つHIDDENタグ全部、A HREFタグ
elems = doc.select("input,a[href],form[action],textarea"); // input、A HREFタグ
// elemsprint(htmltext);
// input[type=search],input[type=number],input[type=email],a[href],form[action],textarea");//tag which has name attributes, href , form, textarea
elems = doc.select(tagSelector);

} catch (Exception e) {
// TODO Auto-generated catch block
EnvironmentVariables.plog.printException(e);
LOGGER4J.error(e.getMessage(), e);
doc = null;
elems = null;
}

this.doc = doc;
this.elems = elems;
//elemsprint();
}

void elemsprint(String _t) {
void elemsprint() {
for (Element vtag : elems) {
String n = vtag.attr("name");
String v = vtag.attr("value");
String h = vtag.attr("href");
if (vtag.tagName().toLowerCase().indexOf("input") != -1) { // <input
EnvironmentVariables.plog.AppendPrint(
String content = vtag.attr("content");
if (vtag.tagName().toLowerCase().equals("input")) { // <input
LOGGER4J.debug(
"<" + vtag.tagName() + " name=\"" + n + "\" value=\"" + v + "\">");
} else if (vtag.tagName().toLowerCase().indexOf("a") != -1) { // <A
EnvironmentVariables.plog.AppendPrint("<" + vtag.tagName() + " href=\"" + h + "\">");
} else if (vtag.tagName().toLowerCase().equals("a")) { // <A
LOGGER4J.debug("<" + vtag.tagName() + " href=\"" + h + "\">");

} else if (vtag.tagName().toLowerCase().equals("meta")) {
LOGGER4J.debug((ParmGenUtil.isTokenValue(content) ? "Token":"") + "<" + vtag.tagName() + " name=\"" + n + "\" content=\"" + content + "\">");
} else {
EnvironmentVariables.plog.AppendPrint("<" + vtag.tagName() + "\">");
LOGGER4J.debug("<" + vtag.tagName() + "\">");
}
}
}

public ArrayList<ParmGenToken> getParmGenTokens(
private ArrayList<ParmGenToken> getParmGenTokens(
Element vtag, HashMap<String, Integer> namepos) {
String[] nv = null;
ParmGenToken tk = null;
ArrayList<ParmGenToken> tklist = new ArrayList<ParmGenToken>();
if (vtag.tagName().toLowerCase().indexOf("input") != -1) { // <input
String n = vtag.attr("name");
String lowerTagName = vtag.tagName().toLowerCase();
String nameAttribute = vtag.attr("name");
if (lowerTagName.equals("input")) { // <input
String v = vtag.attr("value");
String t = vtag.attr("type");
// <inputタグのnameパラメータ
if (n == null) {
n = null;
} else if (n.isEmpty()) {
// name attribute in input tag.
String n = nameAttribute;
if (n.isEmpty()) {
n = null;
}
if (v == null) {
v = "";
}
if (n != null) {
// 重複nameの検査
// count if same name is exist
int npos = 0;
if (namepos.containsKey(n)) {
npos = namepos.get(n);
Expand All @@ -128,9 +134,28 @@ public ArrayList<ParmGenToken> getParmGenTokens(
tk = new ParmGenToken(ttype, "", n, v, false, npos);
tklist.add(tk);
}
} else if (vtag.tagName().toLowerCase().equals("a")) { // <A
} else if (lowerTagName.equals("meta")) { // <meta
String v = vtag.attr("content");
// name attribute in input tag.
String n = nameAttribute;
if (n.isEmpty()) {
n = null;
}
if (n != null) {
// count if same name is exist
int npos = 0;
if (namepos.containsKey(n)) {
npos = namepos.get(n);
npos++;
}
namepos.put(n, npos);
AppValue.TokenTypeNames ttype = AppValue.TokenTypeNames.META;
tk = new ParmGenToken(ttype, "", n, v, false, npos);
tklist.add(tk);
}
} else if (lowerTagName.equals("a")) { // <A
String h = vtag.attr("href");
// href属性から、GETパラメータを抽出。
// extract GET(query) parameters from href attribute.
// ?name=value&....
if (h != null) {
String[] nvpairs = h.split("[&?]|amp;");
Expand All @@ -143,7 +168,7 @@ public ArrayList<ParmGenToken> getParmGenTokens(
value = nvp[1];

if (name != null && name.length() > 0 && value != null) {
// 重複nameの検査
// count if same name is exist
int npos = 0;
if (namepos.containsKey(name)) {
npos = namepos.get(name);
Expand All @@ -163,9 +188,9 @@ public ArrayList<ParmGenToken> getParmGenTokens(
}
}
}
} else if (vtag.tagName().toLowerCase().indexOf("form") != -1) { // <A
} else if (lowerTagName.equals("form")) { // <form
String h = vtag.attr("action");
// href属性から、GETパラメータを抽出。
// extract GET(query) parameters from action attribute
// ?name=value&....
if (h != null) {
String[] nvpairs = h.split("[&?]|amp;");
Expand All @@ -178,7 +203,7 @@ public ArrayList<ParmGenToken> getParmGenTokens(
value = nvp[1];

if (name != null && name.length() > 0 && value != null) {
// 重複nameの検査
// count if same name is exist
int npos = 0;
if (namepos.containsKey(name)) {
npos = namepos.get(name);
Expand All @@ -198,21 +223,16 @@ public ArrayList<ParmGenToken> getParmGenTokens(
}
}
}
} else if (vtag.tagName().toLowerCase().indexOf("textarea") != -1) { // <textarea
String n = vtag.attr("name");
} else if (lowerTagName.equals("textarea")) { // <textarea
String n = nameAttribute;
String v = vtag.html();
String t = vtag.attr("type");
// <inputタグのnameパラメータ
if (n == null) {
n = null;
} else if (n.isEmpty()) {
// name attribute in textarea tag
if (n.isEmpty()) {
n = null;
}
if (v == null) {
v = "";
}
if (n != null) {
// 重複nameの検査
// count if same name is exist
int npos = 0;
if (namepos.containsKey(n)) {
npos = namepos.get(n);
Expand All @@ -227,9 +247,12 @@ public ArrayList<ParmGenToken> getParmGenTokens(
}
return tklist;
}
//
// 引き継ぎパラメータ一覧
//

/**
* get ParmGenToken list from response
*
* @return
*/
public ArrayList<ParmGenToken> getNameValues() {

HashMap<String, Integer> namepos = new HashMap<String, Integer>();
Expand All @@ -245,15 +268,19 @@ public ArrayList<ParmGenToken> getNameValues() {

} catch (Exception e) {
// TODO Auto-generated catch block
EnvironmentVariables.plog.printException(e);
LOGGER4J.error(e.getMessage(), e);
}

return lst;
}

//
// レスポンスパラメータ抽出
//
/**
* Gets the ParmGenToken that matches the specified parameters.
* @param name
* @param fcnt
* @param _tokentype
* @return
*/
public ParmGenToken fetchNameValue(String name, int fcnt, AppValue.TokenTypeNames _tokentype) {
if (name == null) return null; // name nullは不可。
ParmGenTokenKey tkey = null;
Expand Down Expand Up @@ -307,7 +334,7 @@ public ParmGenParser clone() {
nobj.defmap = HashMapDeepCopy.hashMapDeepCopyParmGenHashMapSuper(this.defmap);
return nobj;
} catch (CloneNotSupportedException ex) {
Logger.getLogger(ParmGenParser.class.getName()).log(Level.SEVERE, null, ex);
LOGGER4J.error(ex.getMessage(), ex);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ParmGenRequestToken {

public ParmGenRequestToken(ParmGenToken tkn) {
if (tkn != null) { // Is tkn convertable?
switch (tkn.getTokenKey().GetTokenType()) {
switch (tkn.getTokenKey().getTokenType()) {
case JSON:
key =
new ParmGenRequestTokenKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
package org.zaproxy.zap.extension.automacrobuilder;

import org.zaproxy.zap.extension.automacrobuilder.generated.MacroBuilderUI;

import java.util.HashMap;

/** @author youtube */
Expand Down Expand Up @@ -83,6 +85,7 @@ public ParmGenToken findResponseToken(String name, String value) {
ParmGenToken foundNameResToken = resTokenUrlDecodedNameHash.get(requestTokenNameDecoded);
ParmGenToken foundValueResToken = resTokenUrlDecodedValueHash.get(requestTokenValueDecoded);
ParmGenToken foundResToken = null;

if (foundNameAndValueResToken
!= null) { // exactly request parameter matched response parameter's name & value
foundResToken = foundNameAndValueResToken;
Expand All @@ -97,6 +100,8 @@ public ParmGenToken findResponseToken(String name, String value) {
&& foundNameResTokenValueDecoded.length()
== requestTokenValueDecoded.length()) {
foundResToken = foundNameResToken;
} else if(foundNameResToken.getTokenKey().getName().toLowerCase().equals(MacroBuilderUI.RAILS_CSRF_TOKEN)) {
foundResToken = foundNameResToken;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public String getName() {
return name;
}

public AppValue.TokenTypeNames GetTokenType() {
public AppValue.TokenTypeNames getTokenType() {
return tokentype;
}

Expand Down
Loading

0 comments on commit 1cd4738

Please sign in to comment.