Lookup for vulnerable packages by Package URL.

GET /api/packages/1072392?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "url": "http://public2.vulnerablecode.io/api/packages/1072392?format=api",
    "purl": "pkg:maven/io.micronaut/micronaut-inject@1.0.0.RC3",
    "type": "maven",
    "namespace": "io.micronaut",
    "name": "micronaut-inject",
    "version": "1.0.0.RC3",
    "qualifiers": {},
    "subpath": "",
    "is_vulnerable": true,
    "next_non_vulnerable_version": "4.10.22",
    "latest_non_vulnerable_version": "4.10.22",
    "affected_by_vulnerabilities": [
        {
            "url": "http://public2.vulnerablecode.io/api/vulnerabilities/92246?format=api",
            "vulnerability_id": "VCID-c342-bm72-cbcr",
            "summary": "Micronaut has Unbounded `bundleCache` in `ResourceBundleMessageSource` that Allows Memory Exhaustion via `Accept-Language` Header\n## Summary\n\n`ResourceBundleMessageSource` maintains two caches: `messageCache` (bounded at 100 entries via `ConcurrentLinkedHashMap`) and `bundleCache` (unbounded `ConcurrentHashMap`). The `bundleCache` is keyed by `(Locale, baseName)` where the locale originates from the HTTP `Accept-Language` header. In applications that explicitly register a `ResourceBundleMessageSource` bean and serve HTML error responses, an unauthenticated attacker can exhaust heap memory by sending requests with large numbers of unique `Accept-Language` values, each causing a new entry in the unbounded `bundleCache`. Unlike GHSA-2hcp-gjrf-7fhc and the sibling `messageCache` (both bounded), `bundleCache` was not updated to use a bounded cache implementation.\n\n## Details\n\nThe `bundleCache` is initialized in `inject/src/main/java/io/micronaut/context/i18n/ResourceBundleMessageSource.java` at line 150:\n\n```java\n// ResourceBundleMessageSource.java:139-152\nprotected Map<MessageKey, Optional<String>> buildMessageCache() {\n    return new ConcurrentLinkedHashMap.Builder<MessageKey, Optional<String>>()\n            .maximumWeightedCapacity(100)    // ← BOUNDED ✓\n            .build();\n}\n\nprotected Map<MessageKey, Optional<ResourceBundle>> buildBundleCache() {\n    return new ConcurrentHashMap<>(18);      // ← UNBOUNDED ✗\n}\n```\n\nThe `resolveBundle()` method at line 169 inserts into `bundleCache` with no eviction policy:\n\n```java\n// ResourceBundleMessageSource.java:169-185\nprivate Optional<ResourceBundle> resolveBundle(Locale locale) {\n    MessageKey key = new MessageKey(locale, baseName);\n    final Optional<ResourceBundle> resourceBundle = bundleCache.get(key);\n    if (resourceBundle != null) {\n        return resourceBundle;\n    } else {\n        Optional<ResourceBundle> opt;\n        try {\n            opt = Optional.of(ResourceBundle.getBundle(baseName, locale, getClassLoader()));\n        } catch (MissingResourceException e) {\n            opt = Optional.empty();\n        }\n        bundleCache.put(key, opt);    // NO SIZE CHECK — unbounded growth\n        return opt;\n    }\n}\n```\n\nThe attack path requires:\n1. The application registers a `ResourceBundleMessageSource` bean (non-default, requires explicit user configuration).\n2. The attacker sends requests that trigger HTML error responses — i.e., requests with `Accept: text/html` to any URL that returns an error (e.g., 404 for any non-existent path).\n3. Each request uses a unique `Accept-Language` value (e.g., `zz-AA`, `zz-AB`, …).\n4. `DefaultHtmlErrorResponseBodyProvider.error()` calls `messageSource.getMessage(code, locale)` → `CompositeMessageSource` delegates to `ResourceBundleMessageSource` → `resolveBundle(locale)` inserts one entry per unique locale into `bundleCache`.\n\nFor locales that don't match any bundle file, `ResourceBundle.getBundle()` throws `MissingResourceException` and `Optional.empty()` is stored — a low-cost sentinel. For locales that DO match a bundle, a full `ResourceBundle` object is retained in memory. In either case, the map itself and the `MessageKey` objects grow without bound.\n\nNote: the `messageCache` is bounded at 100 entries but does not prevent `bundleCache` growth, as `resolveBundle()` is called directly (bypassing `messageCache`) whenever a `messageCache` miss occurs.\n\n## PoC\n\nAgainst a Micronaut application with a `ResourceBundleMessageSource` bean registered (e.g., `@Bean ResourceBundleMessageSource messages() { return new ResourceBundleMessageSource(\"messages\"); }`):\n\n```bash\n# Flood bundleCache with unique locales via HTML error path\nfor i in $(seq 1 100000); do\n  curl -s -o /dev/null \\\n    -H \"Accept: text/html\" \\\n    -H \"Accept-Language: zz-$(printf '%04d' $i)\" \\\n    \"http://localhost:8080/nonexistent-path-$(printf '%06d' $i)\" &\n  [ $((i % 200)) -eq 0 ] && wait\ndone\nwait\n```\n\nEach unique `zz-XXXX` tag creates one new `bundleCache` entry. The `MessageKey` (Locale + baseName) and map overhead cost approximately 100-200 bytes per entry. At 100,000 entries, heap consumption from the cache alone reaches roughly 20 MB — significant in resource-constrained deployments. If a locale matches a bundle file, retained `ResourceBundle` objects cost substantially more per entry.\n\n## Impact\n\n- Only affects applications that explicitly register a `ResourceBundleMessageSource` bean (not the default configuration).\n- Requires the ability to send HTTP requests with `Accept: text/html` headers and control over the `Accept-Language` value.\n- Memory grows approximately 100-200 bytes per novel locale (for non-matching locales) up to several KB per locale if bundles are found. Sustained attack over time causes gradual heap exhaustion.\n- Partial availability impact (A:L) under sustained attack in long-running services.\n\n## Recommended Fix\n\nApply the same bounded-cache pattern used for the sibling `messageCache`:\n\n```java\n// In ResourceBundleMessageSource.java — replace buildBundleCache()\nprotected Map<MessageKey, Optional<ResourceBundle>> buildBundleCache() {\n    return new ConcurrentLinkedHashMap.Builder<MessageKey, Optional<ResourceBundle>>()\n            .maximumWeightedCapacity(50)    // small — one entry per (locale, baseName)\n            .build();\n}\n```\n\nThe number of distinct resource bundle files is bounded at compile time; a limit of 50 entries is more than sufficient for any realistic i18n configuration while fully preventing unbounded growth.",
            "references": [
                {
                    "reference_url": "https://api.first.org/data/v1/epss?cve=CVE-2026-44242",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.00048",
                            "scoring_system": "epss",
                            "scoring_elements": "0.15287",
                            "published_at": "2026-06-06T12:55:00Z"
                        },
                        {
                            "value": "0.00048",
                            "scoring_system": "epss",
                            "scoring_elements": "0.15188",
                            "published_at": "2026-06-09T12:55:00Z"
                        },
                        {
                            "value": "0.00048",
                            "scoring_system": "epss",
                            "scoring_elements": "0.15164",
                            "published_at": "2026-06-08T12:55:00Z"
                        },
                        {
                            "value": "0.00048",
                            "scoring_system": "epss",
                            "scoring_elements": "0.15247",
                            "published_at": "2026-06-07T12:55:00Z"
                        },
                        {
                            "value": "0.00048",
                            "scoring_system": "epss",
                            "scoring_elements": "0.15297",
                            "published_at": "2026-06-05T12:55:00Z"
                        }
                    ],
                    "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-44242"
                },
                {
                    "reference_url": "https://github.com/micronaut-projects/micronaut-core",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "3.7",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/micronaut-projects/micronaut-core"
                },
                {
                    "reference_url": "https://github.com/micronaut-projects/micronaut-core/releases/tag/v4.10.22",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "3.7",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/micronaut-projects/micronaut-core/releases/tag/v4.10.22"
                },
                {
                    "reference_url": "https://github.com/micronaut-projects/micronaut-core/security/advisories/GHSA-3rfq-4wpf-qqw3",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "3.7",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-05-13T14:54:21Z/"
                        }
                    ],
                    "url": "https://github.com/micronaut-projects/micronaut-core/security/advisories/GHSA-3rfq-4wpf-qqw3"
                },
                {
                    "reference_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44242",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "3.7",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44242"
                },
                {
                    "reference_url": "https://github.com/advisories/GHSA-3rfq-4wpf-qqw3",
                    "reference_id": "GHSA-3rfq-4wpf-qqw3",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "LOW",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/advisories/GHSA-3rfq-4wpf-qqw3"
                }
            ],
            "fixed_packages": [
                {
                    "url": "http://public2.vulnerablecode.io/api/packages/114913?format=api",
                    "purl": "pkg:maven/io.micronaut/micronaut-inject@4.10.22",
                    "is_vulnerable": false,
                    "affected_by_vulnerabilities": [],
                    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:maven/io.micronaut/micronaut-inject@4.10.22"
                }
            ],
            "aliases": [
                "CVE-2026-44242",
                "GHSA-3rfq-4wpf-qqw3"
            ],
            "risk_score": 1.6,
            "exploitability": "0.5",
            "weighted_severity": "3.3",
            "resource_url": "http://public2.vulnerablecode.io/vulnerabilities/VCID-c342-bm72-cbcr"
        }
    ],
    "fixing_vulnerabilities": [],
    "risk_score": "1.6",
    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:maven/io.micronaut/micronaut-inject@1.0.0.RC3"
}