diff --git a/src/configurations/destinations/webhook/schema.json b/src/configurations/destinations/webhook/schema.json index 9fbeb476b..68b0d558b 100644 --- a/src/configurations/destinations/webhook/schema.json +++ b/src/configurations/destinations/webhook/schema.json @@ -517,7 +517,7 @@ }, "webhookUrl": { "type": "string", - "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$" + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$" }, "webhookMethod": { "type": "string", diff --git a/src/configurations/destinations/webhook/ui-config.json b/src/configurations/destinations/webhook/ui-config.json index 9a7448136..d9a8383a7 100644 --- a/src/configurations/destinations/webhook/ui-config.json +++ b/src/configurations/destinations/webhook/ui-config.json @@ -9,7 +9,7 @@ "value": "webhookUrl", "required": true, "placeholder": "http://www.abcd.com", - "regex": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$" + "regex": "^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$" }, { "type": "singleSelect", diff --git a/test/data/validation/destinations/webhook.json b/test/data/validation/destinations/webhook.json index 59f98338b..062b3e13a 100644 --- a/test/data/validation/destinations/webhook.json +++ b/test/data/validation/destinations/webhook.json @@ -39,7 +39,10 @@ } ] }, - "result": true + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] }, { "config": { @@ -62,7 +65,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -86,7 +89,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -110,7 +113,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -134,7 +137,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -158,7 +161,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -182,7 +185,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -239,7 +242,7 @@ }, "result": false, "err": [ - "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|(?!.*\\.ngrok\\.io)^(https?):\\/\\/(?!localhost|127\\.0\\.0\\.1|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}|0\\.0\\.0\\.0|\\[::1\\]|\\[fc[0-9a-fA-F]{2}:.*\\]|\\[fd[0-9a-fA-F]{2}:.*\\]|\\[::ffff:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\]).*([^\\s/$.?#].[^\\s]*)$\"" + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" ] }, { @@ -657,5 +660,316 @@ "ketchConsentPurposes.web must be array", "ketchConsentPurposes.unity.0 must be object" ] + }, + { + "testTitle": "localhost with port", + "config": { + "webhookUrl": "http://127.1.2.3:8080", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "ipv4 address with port", + "config": { + "webhookUrl": "http://192.168.1.100:8080", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Internal IP address", + "config": { + "webhookUrl": "http://0.0.0.0", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Private IP address", + "config": { + "webhookUrl": "http://192.168.0.1", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - IPv6 loopback", + "config": { + "webhookUrl": "http://[::1]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Domain with DNS rebinding", + "config": { + "webhookUrl": "http://spoofed.burpcollaborator.net", + "webhookMethod": "GET" + }, + "result": true + }, + { + "testTitle": "SSRF - URL encoding bypass attempt", + "config": { + "webhookUrl": "http://127.0.0.1%2f", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Decimal IP representation", + "config": { + "webhookUrl": "http://2130706433", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Octal IP representation", + "config": { + "webhookUrl": "http://0177.0000.0000.0001", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + + { + "testTitle": "SSRF - IPv6 mapped IPv4 address", + "config": { + "webhookUrl": "http://[::ffff:192.168.0.1]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Hexadecimal IP representation", + "config": { + "webhookUrl": "http://0xC0A80001", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Mixed encoding", + "config": { + "webhookUrl": "http://127.0.0.1%0d%0aHost:example.com", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Double encoding", + "config": { + "webhookUrl": "http://127.0.0.1%252f", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - IPv6 compressed", + "config": { + "webhookUrl": "http://[::127.0.0.1]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Enclosed alphanumerics", + "config": { + "webhookUrl": "http://⑫⑦.⓪.⓪.①", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Punycode domain", + "config": { + "webhookUrl": "http://xn--80ak6aa92e.com", + "webhookMethod": "GET" + }, + "result": true + }, + { + "testTitle": "SSRF - URL with credentials", + "config": { + "webhookUrl": "http://user:password@example.com", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Data URL scheme", + "config": { + "webhookUrl": "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Localhost with subdomain", + "config": { + "webhookUrl": "http://subdomain.localhost", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - localhost with dash", + "config": { + "webhookUrl": "http://local-host", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - localhost with numbers", + "config": { + "webhookUrl": "http://127.0.0.1.nip.io", + "webhookMethod": "GET" + }, + "result": true + }, + { + "testTitle": "SSRF - Dotless decimal IP", + "config": { + "webhookUrl": "http://2130706433", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Dotless hex IP", + "config": { + "webhookUrl": "http://0x7f000001", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - IPv6 localhost", + "config": { + "webhookUrl": "http://[::1]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - IPv6 localhost with zone identifier", + "config": { + "webhookUrl": "http://[::1%25en0]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Malformed IPv6", + "config": { + "webhookUrl": "http://0:0:0:0:0:ffff:127.0.0.1", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - IPv6 with IPv4 address", + "config": { + "webhookUrl": "http://[0:0:0:0:0:ffff:127.0.0.1]", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - Exotic protocols", + "config": { + "webhookUrl": "gopher://example.com/_TCP:80", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] + }, + { + "testTitle": "SSRF - URL fragment", + "config": { + "webhookUrl": "http://example.com#@evil.com/", + "webhookMethod": "GET" + }, + "result": false, + "err": [ + "webhookUrl must match pattern \"(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(https?:\\/\\/)(?![a-zA-Z0-9-]*\\.ngrok\\.io)(?!localhost|.*\\.localhost)([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,}(\\/.*)?$\"" + ] } ]