CVE-2026-84695 Overview
CVE-2026-84695 is a stored cross-site scripting (XSS) vulnerability in BookStack versions before 26.05.4. The flaw resides in the drawing upload endpoint, which accepts unvalidated base64 content and stores it without content inspection. Attackers holding editor permissions can upload SVG files containing embedded scripts. Those scripts execute in administrator browsers when the files are retrieved through the image gallery API, which serves content without content-type validation or Content Security Policy (CSP) headers. The weakness is tracked under CWE-79.
Critical Impact
Authenticated low-privilege users can execute arbitrary JavaScript in administrator sessions, enabling account takeover and full compromise of the BookStack knowledge base.
Affected Products
- BookStack versions prior to 26.05.4
- BookStack v26.05.3 (confirmed vulnerable via app/Uploads/ImageService.php)
- Self-hosted BookStack deployments exposing the drawing upload endpoint
Discovery Timeline
- 2026-09-02 - CVE-2026-84695 published to NVD
- 2026-09-02 - Last updated in NVD database
- v26.05.4 - BookStack releases patched version resolving the issue
Technical Details for CVE-2026-84695
Vulnerability Analysis
BookStack accepts drawing uploads through an endpoint that decodes base64-encoded payloads and writes the resulting bytes to storage. The endpoint does not inspect the decoded content to verify that it matches an expected image format. An editor-role user can supply an SVG document containing <script> elements or event-handler attributes. The file is stored intact and later served through the image gallery API.
Because the response omits a restrictive Content-Type header and no CSP is enforced on the delivery path, browsers render the SVG as active content in the BookStack origin. When an administrator opens the gallery or a page embedding the resource, the attacker's JavaScript runs in that administrator's authenticated context. This chains from editor privileges to full administrative control.
Root Cause
The root cause is missing content inspection in app/Uploads/ImageService.php combined with missing content-type enforcement on the image streaming path. Base64 decoding was treated as sufficient handling, and no MIME sniffing or SVG sanitization occurred before persistence or delivery.
Attack Vector
An attacker authenticated with editor permissions submits a crafted SVG payload to the drawing upload endpoint. The malicious file is stored and referenced through the standard image gallery URL. When a higher-privileged user accesses the resource, the embedded JavaScript executes, allowing session token theft, forced administrative actions, or persistent backdoor creation through further API calls.
// Patch excerpt: app/Uploads/ImageService.php
use BookStack\Entities\Queries\EntityQueries;
use BookStack\Exceptions\ImageUploadException;
+use BookStack\Exceptions\PrettyException;
+use BookStack\Http\DownloadResponseFactory;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
Source: GitHub Commit ac0348a79f3d
// Patch excerpt: app/Uploads/ImageStorageDisk.php - adds size() to support ranged streaming and content checks
return $this->filesystem->readStream($this->adjustPathForDisk($path));
}
+/**
+ * Get the size of the file at the given path.
+ */
+public function size(string $path): int
+{
+ return $this->filesystem->size($this->adjustPathForDisk($path));
+}
Source: GitHub Commit ac0348a79f3d. The fix introduces content checking and ranged streaming so that uploads are validated and served with correct handling.
Detection Methods for CVE-2026-84695
Indicators of Compromise
- Uploaded image files with .svg extensions or SVG magic bytes (<?xml / <svg) inside the BookStack uploads directory
- Stored image payloads containing <script>, onload=, onerror=, or javascript: strings
- HTTP POST requests to the drawing upload endpoint carrying base64-encoded content that decodes to non-raster data
- Administrator sessions issuing unexpected API calls (user creation, role changes) shortly after viewing image gallery URLs
Detection Strategies
- Scan the BookStack storage disk for SVG content containing scripting constructs and inline event handlers
- Review web server logs for POST traffic to drawing upload routes originating from editor-role accounts
- Correlate image gallery GET requests from admin sessions with subsequent privileged API operations
- Alert on responses from BookStack image endpoints returning image/svg+xml or missing a Content-Type header
Monitoring Recommendations
- Enable verbose access logging on BookStack, forwarding logs to a centralized analytics platform for query-based hunting
- Monitor for privilege changes, new admin accounts, and API token generation events that follow gallery access
- Track file writes into the uploads directory with file-integrity monitoring to catch anomalous SVG persistence
How to Mitigate CVE-2026-84695
Immediate Actions Required
- Upgrade BookStack to v26.05.4 or later without delay, following the BookStack Blog Release v26.05.4 notes
- Audit existing uploads for SVG files containing scripts and remove any suspicious content
- Rotate administrator credentials and API tokens if editor accounts show signs of abuse
- Restrict the editor role to trusted users until patching is complete
Patch Information
The fix is delivered in GitHub Release v26.05.4 and implemented in commit ac0348a79f3d. The patch adds content inspection in app/Uploads/ImageService.php and introduces a size() method plus ranged streaming in app/Uploads/ImageStorageDisk.php, enabling safer delivery through DownloadResponseFactory. See the VulnCheck Advisory for BookStack XSS for additional context.
Workarounds
- Deploy a reverse-proxy rule that forces Content-Type: text/plain or application/octet-stream on responses from the BookStack image gallery path until patched
- Apply a strict CSP header such as default-src 'self'; script-src 'self' at the proxy layer to block inline SVG script execution
- Temporarily remove the editor role from untrusted contributors and disable drawing uploads via a web application firewall (WAF) rule
- Enforce upload MIME validation at the WAF, rejecting requests whose decoded base64 body contains <svg or <script tokens
# Example nginx override to neutralize SVG rendering on the gallery path
location ~ ^/uploads/images/ {
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
add_header X-Content-Type-Options "nosniff" always;
if ($request_filename ~* \.svg$) {
add_header Content-Type "text/plain" always;
}
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

