Merge 0faeefc5952dae6d5a706fe70beb180bdbacd035 into 4290ea753912378913b1f3f54e0fc5720afeda5d

This commit is contained in:
Harel Katz 2026-08-10 00:24:30 -07:00 committed by GitHub
commit 83b509d2b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 72 additions and 4 deletions

View File

@ -20,11 +20,17 @@ class DefangIPAddresses extends Operation {
this.name = "Defang IP Addresses";
this.module = "Default";
this.description = "Takes a IPv4 or IPv6 address and 'Defangs' it, meaning the IP becomes invalid, removing the risk of accidentally utilising it as an IP address.";
this.description = "Takes a IPv4 or IPv6 address and 'Defangs' it, meaning the IP becomes invalid, removing the risk of accidentally utilising it as an IP address.<br><br>When 'Last only' is enabled, only the final separator of each IP is replaced (e.g. <code>1.2.3.4</code> becomes <code>1.2.3[.]4</code>), keeping the address visually closer to its original form while still rendering it invalid.";
this.infoURL = "https://isc.sans.edu/forums/diary/Defang+all+the+things/22744/";
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.args = [
{
name: "Last only",
type: "boolean",
value: false
}
];
this.checks = [
{
pattern: "^\\s*(([0-9]{1,3}\\.){3}[0-9]{1,3}|([0-9a-f]{4}:){7}[0-9a-f]{4})\\s*$",
@ -44,12 +50,14 @@ class DefangIPAddresses extends Operation {
* @returns {string}
*/
run(input, args) {
const [lastOnly] = args;
input = input.replace(IPV4_REGEX, x => {
return x.replace(/\./g, "[.]");
return defangSeparators(x, ".", "[.]", lastOnly);
});
input = input.replace(IPV6_REGEX, x => {
return x.replace(/:/g, "[:]");
return defangSeparators(x, ":", "[:]", lastOnly);
});
return input;
@ -59,6 +67,26 @@ class DefangIPAddresses extends Operation {
export default DefangIPAddresses;
/**
* Replaces a separator character with a defanged token.
* If lastOnly is true, only the final occurrence is replaced.
*
* @param {string} match
* @param {string} sep
* @param {string} token
* @param {boolean} lastOnly
* @returns {string}
*/
function defangSeparators(match, sep, token, lastOnly) {
if (!lastOnly) {
return match.split(sep).join(token);
}
const idx = match.lastIndexOf(sep);
if (idx === -1) return match;
return match.slice(0, idx) + token + match.slice(idx + sep.length);
}
/**
* IPV4 regular expression
*/

View File

@ -39,5 +39,45 @@ TestRegister.addTests([
args: [],
},
],
}, {
name: "Defang IP: Last only — IPV4",
input: "192.168.1.1",
expectedOutput: "192.168.1[.]1",
recipeConfig: [
{
op: "Defang IP Addresses",
args: [true],
},
],
}, {
name: "Defang IP: Last only — IPV6",
input: "2001:0db8:85a3:0000:0000:8a2e:0370:7343",
expectedOutput: "2001:0db8:85a3:0000:0000:8a2e:0370[:]7343",
recipeConfig: [
{
op: "Defang IP Addresses",
args: [true],
},
],
}, {
name: "Defang IP: Last only — IPV6 shorthand",
input: "2001:db8:3c4d:15::1a2f:1a2b",
expectedOutput: "2001:db8:3c4d:15::1a2f[:]1a2b",
recipeConfig: [
{
op: "Defang IP Addresses",
args: [true],
},
],
}, {
name: "Defang IP: Last only — multiple IPs in text",
input: "From 10.0.0.1 to 192.168.1.254",
expectedOutput: "From 10.0.0[.]1 to 192.168.1[.]254",
recipeConfig: [
{
op: "Defang IP Addresses",
args: [true],
},
],
},
]);