Threat database
56 threats
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Low | 3.7 | EPSS 0.3% | CVE-2026-53607apostrophe · Server-Side Request Forgery (SSRF) Low3.7EPSS 0.3%CVE Database V5CVE-2026-53607 ### Summary When `prettyUrls: true` is enabled on `@apostrophecms/file` (a documented SEO feature for serving uploaded files at clean URLs), the public pretty-URL handler builds the upstream URL using the raw `Host` HTTP request header: ```js proxyUrl = `${req.protocol}://${req.get('host')}${uglyUrl}` ``` That URL is then `fetch`'ed and the response body + headers are streamed straight back to the requester. Because `Host` is fully attacker-controlled, an **unauthenticated remote** attacker can pivot the apostrophe process to issue outbound HTTP requests against any host it can reach on the private network. The path component is constrained to `/uploads/attachments/<cuid>-<slug>.<ext>` (built from a local-DB lookup), which keeps the impact narrow: cross-instance data exfiltration is neutralised by cuid uniqueness, but blind-SSRF residuals remain (network-topology mapping via response-code / timing differences and verbose proxy/WAF 404 body disclosure). Verified on `apostrophe@4.30.0` (latest); no fixed release exists. - **Affected:** `apostrophe <= 4.30.0` when `@apostrophecms/file` is configured with `prettyUrls: true` and uploadfs is **local** (the default; S3/CDN deployments produce an absolute `uglyUrl` and are not affected). ### Details `modules/@apostrophecms/file/index.js` (excerpt; the public GET route registered when `prettyUrls: true`): ```js if (!self.options.prettyUrls) return; return { get: { async [`${self.options.prettyUrlDir}/*`](req, res) { const matches = (req.params[0] || '').match(/^([^.]+)\.\w+$/); if (!matches) return res.status(400).send('invalid'); const [ , slug ] = matches; if (slug.includes('..') || slug.includes('/')) { return res.status(403).send('forbidden'); } const file = await self.find(req, { slug: `${self.options.slugPrefix}${slug}` }).toObject(); if (!file) return res.status(404).send('not found'); const uglyUrl = self.apos.attachment.url(file.attachment, { prettyUrl: false }); const proxyUrl = uglyUrl.startsWith('/') ? `${req.protocol}://${req.get('host')}${uglyUrl}` // <-- sink : uglyUrl; return await streamProxy(req, proxyUrl, { error: self.apos.util.error }); } } }; ``` `lib/stream-proxy.js` (excerpt): ```js module.exports = async function(req, url, { error }) { const res = req.res; if (url.startsWith('/')) url = `${req.baseUrl}${url}`; let response; try { response = await fetch(url); } // <-- attacker-steered fetch catch (e) { return send502(e); } for (const header of ['content-type','etag','last-modified','content-disposition','cache-control']) { const v = response.headers.get(header); if (v != null) res.header(header, v); } res.status(response.status); response.body.pipeTo(new WritableStream({ write(c){ res.write(c) }, close(){ res.end() }, ... })); }; ``` `req.get('host')` returns the unvalidated `Host` HTTP header from the request. Express does not validate or restrict it, and apostrophe does not check the constructed `proxyUrl` against an allowlist. The upstream's body and content-type are forwarded verbatim — so any response the targeted host does return at the constrained path will reach the attacker. In practice the path constraint (`/uploads/attachments/<cuid>-<slug>.<ext>`) and cuid uniqueness mean meaningful body exfiltration only occurs against verbose-404 / banner- leaky proxies; against most internal services this degenerates to blind SSRF (response-code + timing side channels). Prerequisites are minimal: `prettyUrls: true` (a documented production SEO option) + at least one file uploaded with a known slug. Slugs are publicly enumerable in normal CMS use (file URLs appear in page content). **Distinct from the only published apostrophe SSRF advisory, GHSA-pr28-mf3q-qpg6** ("Authenticated SSRF in rich-text widget import via @apostrophecms/area validate-widget"), which is authenticated and lives in a completely different module/route. This finding is unauthenticated, in `@apostrophecms/file`, via the `Host` header. ### PoC Three services on an isolated Docker network: `mongo`, `internal` (returns a fake secret, **never exposed to the host**), `apos:3000` (the only port the host can reach). The host attacker proves it cannot reach `internal` directly, then exfiltrates `internal`'s response via one crafted request to `apos`. `app.js` (normal apostrophe site, documented option only): ```js require('apostrophe')({ shortName: 'apos-ssrf-poc', autoBuild: false, modules: { '@apostrophecms/express': { options: { session: { secret: 'x' }, port: 3000 } }, '@apostrophecms/db': { options: { uri: process.env.APOS_MONGODB_URI } }, '@apostrophecms/asset': { options: { autoBuild: false, publicBundle: false, watch: false, hmr: false } }, '@apostrophecms/file': { options: { prettyUrls: true, prettyUrlDir: '/files' } }, 'poc-seed': {} // seeds one file doc on boot (= what an admin does | CVE Database V5 | ||
| Medium | 5.4 | EPSS 0.2% | CVE-2026-53606sanitize-html · Cross-site Scripting Medium5.4EPSS 0.2%CVE Database V5CVE-2026-53606 ## Summary sanitize-html uses `allowedSchemesAppliedToAttributes` (default: `['href', 'src', 'cite']`) to gate the `naughtyHref()` function that blocks dangerous URI schemes like `javascript:` and `vbscript:`. The HTML specification defines 10+ attributes that accept URIs (`action`, `formaction`, `data`, `poster`, `background`, `ping`, `xlink:href`, `dynsrc`, `lowsrc`), but none of these are included in the default gate list. When a developer allows any of these attributes in their configuration, `javascript:` URIs pass through completely unmodified, enabling XSS. The library has zero awareness of these URI-bearing attributes — none appear anywhere in the 854-line source file (verified by grep). No warning mechanism exists, and the README provides no security guidance about expanding `allowedSchemesAppliedToAttributes` when allowing form or media attributes. ## Severity Exploitation requires non-default configuration: the developer must explicitly allow a non-default tag (e.g., `form`) AND a non-default attribute (e.g., `action`). Default configuration is NOT vulnerable. However, this is a common configuration pattern for CMS platforms, form builders, and rich content editors. ## Affected Versions All versions of sanitize-html from v1.18.0 (which introduced `allowedSchemesAppliedToAttributes`) through at least v2.17.2. The default list has been `['href', 'src', 'cite']` since introduction and has never been expanded. ## Root Cause **File**: `index.js:329` (sanitize-html 2.10.0, confirmed same in 2.17.x) ```javascript // Line 329 — The gate that controls scheme validation if (options.allowedSchemesAppliedToAttributes.indexOf(a) >= 0) { if (naughtyHref(name, value)) { delete frame.attribs[a]; return; } } ``` **Default list at line 829**: ```javascript allowedSchemesAppliedToAttributes: ['href', 'src', 'cite'], ``` The `naughtyHref()` function (lines 627-667) correctly blocks `javascript:`, `vbscript:`, and other dangerous schemes. However, it has exactly 2 call sites in the entire codebase (lines 330 and 395), both inside the `indexOf` gate. There is no ungated path. When attribute name is `action`, `formaction`, `data`, `poster`, `background`, etc.: - `indexOf('action')` returns `-1` - The `if` block is skipped entirely - `naughtyHref()` is never called - `javascript:alert(1)` passes through unmodified The `escapeHtml()` function at line 464 provides no defense — it only encodes `& < > "` characters, which are not present in `javascript:alert(1)`. **Data Flow**: ``` Attacker input: <form action="javascript:alert(document.cookie)"> 1. htmlparser2 parses → tag='form', attribs={action:'javascript:alert(document.cookie)'} 2. index.js:298 → allowedAttributes check: 'action' in developer config → PASS 3. index.js:329 → ['href','src','cite'].indexOf('action') → -1 → SKIP naughtyHref() 4. index.js:464 → escapeHtml('javascript:alert(document.cookie)') → unchanged 5. OUTPUT: <form action="javascript:alert(document.cookie)"> ``` ## Steps to Reproduce ```javascript const sanitize = require('sanitize-html'); // ===== VECTOR 1: form action (100% reliable, all modern browsers) ===== const v1 = sanitize( '<form action="javascript:alert(document.cookie)"><button>Submit</button></form>', { allowedTags: ['form', 'button'], allowedAttributes: { form: ['action'] } } ); console.log('V1 (action):', v1); // OUTPUT: <form action="javascript:alert(document.cookie)"><button>Submit</button></form> // XSS triggers when user submits the form // ===== VECTOR 2: button formaction (100% reliable) ===== const v2 = sanitize( '<button formaction="javascript:alert(1)">Click</button>', { allowedTags: ['button'], allowedAttributes: { button: ['formaction'] } } ); console.log('V2 (formaction):', v2); // OUTPUT: <button formaction="javascript:alert(1)">Click</button> // ===== VECTOR 3: object data ===== const v3 = sanitize( '<object data="javascript:alert(1)"></object>', { allowedTags: ['object'], allowedAttributes: { object: ['data'] } } ); console.log('V3 (data):', v3); // OUTPUT: <object data="javascript:alert(1)"></object> // ===== CONTROL: href IS scheme-checked (expected behavior) ===== const ctrl = sanitize( '<a href="javascript:alert(1)">click</a>', { allowedTags: ['a'], allowedAttributes: { a: ['href'] } } ); console.log('Control (href):', ctrl); // OUTPUT: <a>click</a> ← href correctly stripped by naughtyHref() ``` **Observed behavior**: `javascript:` preserved on `action`/`formaction`/`data` but correctly stripped on `href`. **Expected behavior**: `javascript:` should be stripped on ALL URI-bearing attributes, or at minimum, the library should warn developers when they allow URI-bearing attributes not covered by scheme validation. ## Impact An attacker can achieve XSS in applications that use sanitize-html with non-default configurations allowing URI-bearing attributes: - `<for | CVE Database V5 | ||
| Medium | 5.3 | EPSS 0.4% | CVE-2026-45014apostrophe · Cross-site Scripting Medium5.3EPSS 0.4%CVE Database V5CVE-2026-45014 ApostropheCMS is an open-source Node.js content management system. Versions up to and including 4.29.0 are vulnerable to stored cross-site scripting via unsanitized user display name in draft version tooltip. As of time of publication, no known patched versions are available. | CVE Database V5 | ||
| High | 8.1 | EPSS 0.4% | CVE-2026-45013apostrophe · Improper Input Validation High8.1EPSS 0.4%CVE Database V5CVE-2026-45013 ApostropheCMS versions up to and including 4.29.0 have an improper input validation vulnerability in the password reset flow. The reset URL is constructed using the HTTP Host header without proper validation when apos.baseUrl is not configured. This allows an unauthenticated attacker to craft a reset link pointing to an attacker-controlled domain and send it to a victim. If the victim clicks the link, the attacker receives the valid reset token, enabling full account takeover. No patch is currently available for this vulnerability. | CVE Database V5 | ||
| High | 7.6 | EPSS 0.3% | CVE-2026-45012apostrophe · Server-Side Request Forgery (SSRF) High7.6EPSS 0.3%CVE Database V5CVE-2026-45012 ApostropheCMS is an open-source Node.js content management system. Versions up to and including 4.29.0 contain an authenticated server-side request forgery (SSRF) in the rich-text widget import flow. An authenticated user who can submit/edit rich-text widget content can cause the server to fetch attacker-controlled URLs during widget validation. For image-compatible responses, the fetched content can be persisted and re-hosted by Apostrophe, allowing response exfiltration. As of time of publication, no known patched versions are available. | CVE Database V5 | ||
| High | 7.3 | EPSS 0.4% | CVE-2026-45011apostrophe · Cross-site Scripting High7.3EPSS 0.4%CVE Database V5CVE-2026-45011 ApostropheCMS is an open-source Node.js content management system. Version 4.29.0 has a stored cross-site scripting vulnerability in the image widget functionality. A user with the Editor role can configure an image widget link to use a javascript: URL payload. Because editors have permission to publish pages, the malicious widget can be published to the live site. When another user, including an administrator or public visitor, clicks the affected image/link, arbitrary JavaScript executes in the victim’s browser. As of time of publication, no known patched versions are available. | CVE Database V5 | ||
| Critical | 9.3 | EPSS 0.7% | CVE-2026-44990sanitize-html · Cross-site Scripting Critical9.3EPSS 0.7%CVE Database V5CVE-2026-44990 ApostropheCMS is an open-source Node.js content management system, and sanitize-html provides a simple HTML sanitizer with a clear API. Under the default configuration, versions of `sanitize-html` prior to 2.17.4 can turn attacker-controlled content inside a disallowed `xmp` element into live HTML or JavaScript. This is a sanitizer bypass in the default `disallowedTagsMode: 'discard'` path and can lead to stored XSS in applications that render sanitized output back to users. Version 2.17.4 patches the issue. | CVE Database V5 | ||
| Medium | 6.5 | EPSS 0.6% | CVE-2026-42853@apostrophecms/cli · OS Command Injection Medium6.5EPSS 0.6%CVE Database V5CVE-2026-42853 ApostropheCMS versions of the @apostrophecms/cli package up to and including 3.6.0 contain a command injection vulnerability in the 'apos create' command. This vulnerability arises because user input from the password prompt is directly embedded into a shell command without proper sanitization or escaping, allowing arbitrary command execution on the host system. No patched versions are currently available. | CVE Database V5 | ||
| Medium | 6.1 | EPSS 0.3% | CVE-2026-40186apostrophe · Cross-site Scripting Medium6.1EPSS 0.3%CVE Database V5CVE-2026-40186 ApostropheCMS is an open-source Node.js content management system. A regression introduced in commit 49d0bb7, included in versions 2.17.1 of the ApostropheCMS-maintained sanitize-html package bypasses allowedTags enforcement for text inside nonTextTagsArray elements (textarea and option). ApostropheCMS version 4.28.0 is affected through its dependency on the vulnerable sanitize-html version. The code at packages/sanitize-html/index.js:569-573 incorrectly assumes that htmlparser2 does not decode entities inside these elements and skips escaping, but htmlparser2 10.x does decode entities before passing text to the ontext callback. As a result, entity-encoded HTML is decoded by the parser and then written directly to the output as literal HTML characters, completely bypassing the allowedTags filter. An attacker can inject arbitrary tags including XSS payloads through any allowed option or textarea element using entity encoding. This affects non-default configurations where option or textarea are included in allowedTags, which is common in form builders and CMS platforms. This issue has been fixed in version 2.17.2 of sanitize-html and 4.29.0 of ApostropheCMS. | CVE Database V5 | ||
| Medium | 5.3 | EPSS 0.4% | Medium5.3EPSS 0.4%CVE Database V5CVE-2026-39857 ApostropheCMS versions 4.28.0 and earlier have an authorization bypass vulnerability in the REST API's choices and counts query parameters. This flaw allows unauthenticated attackers to retrieve distinct values of any schema field, including those protected by view permissions, bypassing intended field exposure restrictions. The vulnerability arises because MongoDB's distinct() operation does not respect the publicApiProjection filtering, resulting in sensitive data exposure. The issue affects both piece-type and page REST APIs and has been fixed in version 4.29.0. | CVE Database V5 | ||
| High | 8.7 | EPSS 0.4% | CVE-2026-35569apostrophe · Cross-site Scripting High8.7EPSS 0.4%CVE Database V5CVE-2026-35569 ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain a stored cross-site scripting vulnerability in SEO-related fields (SEO Title and Meta Description), where user-controlled input is rendered without proper output encoding into HTML contexts including <title> tags, <meta> attributes, and JSON-LD structured data. An attacker can inject a payload such as "></title><script>alert(1)</script> to break out of the intended HTML context and execute arbitrary JavaScript in the browser of any authenticated user who views the affected page. This can be leveraged to perform authenticated API requests, access sensitive data such as usernames, email addresses, and roles via internal APIs, and exfiltrate it to an attacker-controlled server. This issue has been fixed in version 4.29.0. | CVE Database V5 | ||
| Medium | 5.4 | EPSS 0.3% | CVE-2026-33889apostrophe · Cross-site Scripting Medium5.4EPSS 0.3%CVE Database V5CVE-2026-33889 ApostropheCMS versions 4.28.0 and earlier contain a stored cross-site scripting (XSS) vulnerability in the @apostrophecms/color-field module. This flaw allows an editor to inject malicious JavaScript by bypassing color value validation and inserting unsanitized input into style tags. The vulnerability can lead to session hijacking, cookie theft, and privilege escalation if an administrator views the affected content. The issue is fixed in version 4.29.0. | CVE Database V5 | ||
| Medium | 5.3 | EPSS 0.5% | CVE-2026-33888apostrophe · Incorrect Authorization Medium5.3EPSS 0.5%CVE Database V5CVE-2026-33888 ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the getRestQuery method of the @apostrophecms/piece-type module, where the method checks whether a MongoDB projection has already been set before applying the admin-configured publicApiProjection. An unauthenticated attacker can supply a project query parameter in the REST API request, which is processed by applyBuildersSafely before the permission check, pre-populating the projection state and causing the publicApiProjection to be skipped entirely. This allows disclosure of any field on publicly queryable documents that the administrator explicitly restricted from the public API, such as internal notes, draft content, or metadata. Exploitation is trivial, requiring only appending query parameters to a public URL with no authentication. This issue has been fixed in version 4.29.0. | CVE Database V5 | ||
| Low | 3.7 | EPSS 0.3% | CVE-2026-33877apostrophe · Observable Timing Discrepancy Low3.7EPSS 0.3%CVE Database V5CVE-2026-33877 ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain a timing side-channel vulnerability in the password reset endpoint (/api/v1/@apostrophecms/login/reset-request) that allows unauthenticated username and email enumeration. When a user is not found, the handler returns after a fixed 2-second artificial delay, but when a valid user is found, it performs a MongoDB update and SMTP email send with no equivalent delay normalization, producing measurably different response times. The endpoint also accepts both username and email via an $or query, and has no rate limiting as the existing checkLoginAttempts throttle only applies to the login flow. This enables automated enumeration of valid accounts for use in credential stuffing or targeted phishing. Only instances that have explicitly enabled the passwordReset option are affected, as it defaults to false. This issue has been fixed in version 4.29.0. | CVE Database V5 | ||
| Critical | 10.0 | EPSS 0.6% | CVE-2026-32731import-export · Path Traversal Critical10.0EPSS 0.6%CVE Database V5CVE-2026-32731 CVE-2026-32731 is a critical path traversal vulnerability in ApostropheCMS's import-export module prior to version 3.5.3. The vulnerability arises because the extract() function in gzip.js uses path.join() without sanitizing or resolving traversal sequences like '.. /', allowing crafted tar.gz files to write files outside the intended directory. Any user with Global Content Modify permission, typically content editors or site managers, can exploit this by uploading a malicious archive via the CMS import UI. This can lead to arbitrary file writes anywhere the Node. | CVE Database V5 | ||
| High | 8.1 | EPSS 0.5% | CVE-2026-32730apostrophe · Improper Authentication High8.1EPSS 0.5%CVE Database V5CVE-2026-32730 CVE-2026-32730 is a high-severity authentication bypass vulnerability in ApostropheCMS versions prior to 4.28.0. The flaw exists in the bearer token authentication middleware where an incorrect MongoDB query allows tokens that have passed password verification but not multi-factor authentication (MFA) to be accepted as fully authenticated. This bypasses MFA protections for any deployment using the login-totp module or custom post-password verification requirements. Exploitation requires no user interaction and can be performed remotely over the network. The vulnerability impacts confidentiality, integrity, and availability by allowing unauthorized access to protected resources. No known exploits are currently in the wild, but the issue is critical for organizations relying on ApostropheCMS with MFA enabled. Upgrading to version 4.28. | CVE Database V5 |
Showing 41–56 of 56 results