Skip to content

Commit 01b4174

Browse files
authored
Merge pull request #508 from kingthorin/cyberchef-example
Add Encode/Decode CyberChef example
2 parents ca2b294 + 5155aee commit 01b4174

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
- Variant script 'AddUrlParams.js'
1010
- Extender script 'ScanMonitor.js'
1111
- Active script 'OpenModelContextProtocolServer.js' - Attempts to detect Model Context Protocol (MCP) servers lacking authentication.
12+
- Encode/Decode script 'CyberChefExample.js' - A script which communicates with CyberChef-server Docker image for processing.
1213

1314
### Changed
1415
- Update minimum ZAP version to 2.16.0 and compile with Java 17.

encode-decode/CyberChefExample.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// CyberChef - Extract URLs (via /bake)
2+
// https://www.zaproxy.org/blog/2026-02-17-encoder-cyberchef-via-scripts/
3+
4+
const EncodeDecodeResult = Java.type(
5+
"org.zaproxy.addon.encoder.processors.EncodeDecodeResult"
6+
);
7+
const HttpRequestHeader = Java.type(
8+
"org.parosproxy.paros.network.HttpRequestHeader"
9+
);
10+
const HttpMessage = Java.type("org.parosproxy.paros.network.HttpMessage");
11+
const HttpSender = Java.type("org.parosproxy.paros.network.HttpSender");
12+
13+
const cyberchefUrl = "http://localhost:3000/bake";
14+
15+
const header = new HttpRequestHeader("POST " + cyberchefUrl + " HTTP/1.1");
16+
header.setHeader("Content-Type", "application/json");
17+
header.setHeader("Accept", "application/json");
18+
19+
const msg = new HttpMessage(header);
20+
21+
const sender = new HttpSender(HttpSender.MANUAL_REQUEST_INITIATOR);
22+
23+
function process(helper, value) {
24+
try {
25+
// This is the recipe/operation(s) we're going to ask CyberChef to handle
26+
// In this case if the input value is empty send a single space, otherwise CyberChef complains
27+
var payload = JSON.stringify({
28+
input: !value || value === "" ? " " : value,
29+
recipe: [{ op: "Extract URLs" }],
30+
});
31+
32+
msg.setRequestBody(payload);
33+
msg.getRequestHeader().setContentLength(msg.getRequestBody().length());
34+
35+
sender.sendAndReceive(msg);
36+
37+
var responseStr = msg.getResponseBody().toString();
38+
39+
// CyberChef /bake returns { "value": "...", "type": "string" }
40+
if (msg.getResponseHeader().isJson()) {
41+
var json = JSON.parse(responseStr);
42+
// If the return value is empty tell the user there's no URLs, otherwise provide them
43+
// Falling back to the raw response if it isn't JSON
44+
var output = json.value === "" ? "No URLs" : json.value || responseStr;
45+
return helper.newResult(output);
46+
}
47+
48+
return helper.newResult(responseStr);
49+
} catch (e) {
50+
return helper.newError("Error contacting CyberChef: " + e.toString());
51+
}
52+
}

0 commit comments

Comments
 (0)