Jun 5, 2026·6 min read·5 visits
Unbounded metadata tag processing in Bugsink allows unauthenticated users with a valid Project DSN to exhaust database write resources, resulting in a denial of service.
Bugsink, a Sentry-compatible self-hosted error tracker written in Python and Django, is vulnerable to a denial of service (DoS) in versions up to and including 2.2.1. The system's ingestion pipeline historically processed every metadata tag supplied with an incoming error event without bounding the maximum number of tags. Because database writes are serialized in Bugsink's typical single-writer architecture, a single event payload carrying an excessive number of tags can monopolize the database write lock, halting event processing for all other users.
Bugsink is an open-source, Sentry-compatible error tracking platform written in Python and Django. To minimize operational complexity, Bugsink is typically deployed in single-server configurations using a SQLite database backend. This architecture relies on a single-writer pattern where only one database transaction can write to the database file at any given moment.
In Sentry-compatible environments, client applications submit runtime errors accompanied by custom metadata key-value pairs referred to as tags. The vulnerability tracked under GHSA-5X67-J5XG-C5GJ is an uncontrolled resource consumption issue within Bugsink's error ingestion pipeline. Specifically, the system attempts to process and save every metadata tag present within an incoming event payload without imposing a maximum limit on the tag count.
An attacker who possesses a valid project Data Source Name (DSN) can exploit this lack of validation by sending a single, crafted error event containing an excessively large list of tags. This triggers a high volume of serialized database writes, holding the write lock for an extended period. Consequently, all other incoming error events from legitimate applications are blocked from being ingested, resulting in a localized denial of service for the platform.
The root cause of this vulnerability lies in the way Bugsink's digestion layer persists metadata tags. When a client application transmits an error event, the server extracts the tags dictionary and processes each entry. This processing is handled inside tags/models.py by a function named digest_tags, which iterates through the supplied tags and calls store_tags to write them to the database.
In SQLite-based configurations, database writes are strictly serialized. Storing a single key-value tag is not an isolated, low-overhead operation. For each metadata tag, Bugsink must query, verify, and potentially create records across four different database tables. These include the TagKey registry, the TagValue table, the EventTag mapping, and the IssueTag mapping.
Because of this relational design, processing a single tag translates into up to four distinct database row-write operations inside a single transaction. When an event contains thousands of tags, the ingestion thread initiates a massive write transaction that executes tens of thousands of database writes. This holds the database write lock, blocks all other database operations, and starves the application worker pool of available database connections.
The vulnerability was resolved in version 2.2.2 by implementing a strict cap on the number of tags stored per event. The fix was introduced across two separate commits.
In the first commit (8dca571b9e66c535ed4885465db820824e7c491a), a default configuration setting named MAX_EVENT_TAGS was added, initially set to 1000. The digest_tags function in tags/models.py was updated to truncate the incoming tags dictionary to this maximum limit prior to invoking the store_tags helper. This prevented an unbounded loop of database writes.
# File: tags/models.py
# The fixed logic slices the tags dictionary if it exceeds the max_tags setting
max_tags = get_settings().MAX_EVENT_TAGS
if len(tags) > max_tags:
logger.warning("event has %d tags; storing %d and dropping the rest", len(tags), max_tags)
tags = dict(list(tags.items())[:max_tags])In the second commit (1d0539fefcd1a796143d15d84053b1c0122ef8c7), the developers hardened this defense by lowering the default value of MAX_EVENT_TAGS from 1000 to 100. This change ensures that even under highly restricted hardware constraints or intense resource starvation, SQLite database writes remain within a predictable bound. Additionally, user-defined tags are prioritized over system-synthesized tags by ensuring truncation occurs after the primary user tags are extracted.
Exploitation of GHSA-5X67-J5XG-C5GJ requires network access to the Bugsink ingestion endpoint and a valid Project DSN. In many client-side applications (such as single-page web applications or mobile apps), the Sentry-compatible DSN is exposed within public asset bundles or network requests, making it easily discoverable.
With a valid DSN, an attacker can construct a standard JSON payload that mimics a Sentry crash report. Within the tags field of this JSON structure, the attacker generates an array or dictionary containing thousands of unique key-value pairs (e.g., "tag_0001": "value", "tag_0002": "value", etc.).
{
"event_id": "fc63bfc12c224079b4f0e7c700000001",
"timestamp": "2026-06-05T21:45:00.000Z",
"platform": "javascript",
"message": "Simulated Ingestion Delay Test",
"tags": {
"test_tag_1": "val",
"test_tag_2": "val",
"test_tag_10000": "val"
}
}When this payload is sent via an HTTP POST request to Bugsink's /api/{project_id}/store/ endpoint, the server processes the payload. If the server is running a version equal to or older than 2.2.1, it attempts to write approximately 40,000 database rows within a single transaction. This operation blocks other processes trying to obtain the SQLite write lock, causing them to time out or return server errors (HTTP 500 or 504).
The security impact of GHSA-5X67-J5XG-C5GJ is limited strictly to system availability. Because the vulnerability is exploited via the standard ingestion pipeline, it does not bypass authentication mechanisms to access sensitive administrative data, nor does it allow arbitrary code execution, file system writes, or data extraction.
The CVSS v3.1 score of 4.3 (Medium) reflects this limited impact. The metrics indicate that network access is required, the attack complexity is low, and low privileges are required (the valid Project DSN acts as a low-privilege credential). The impact is rated as Low for Availability and None for both Confidentiality and Integrity.
In production environments, the denial of service halts the ingestion of critical application errors. If an active incident occurs on the target application while the database is locked, administrators will fail to receive real-time traceback alerts and telemetry. This impairs the operational monitoring and incident response capabilities of organizations using Bugsink.
The recommended remediation path is to upgrade the Bugsink installation to version 2.2.2 or newer. The update implements the MAX_EVENT_TAGS cap natively, preserving performance and stability during processing.
For deployments where an immediate upgrade is not possible, administrators should configure the MAX_EVENT_TAGS environment variable to a conservative value, such as 50 or 100, if their deployment configuration exposes this parameter. Alternatively, rate-limiting rules can be implemented at the reverse proxy or Web Application Firewall (WAF) layer to limit the maximum size of incoming HTTP POST requests sent to the /api/*/store/ endpoints, as oversized payloads are often indicative of this exploitation vector.
Additionally, operations teams can monitor Bugsink logs for warning messages originating from the bugsink.ingest logger. When an event exceeds the configured limit, the system logs a message matching: event has {count} tags; storing 100 and dropping the rest. Detecting these log patterns provides a reliable indicator that an application is emitting excessive tags or that an ingestion attack is being attempted.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
bugsink Bugsink | <= 2.2.1 | 2.2.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network |
| CVSS v3.1 | 4.3 (Medium) |
| EPSS Score | Not Available |
| Impact | Denial of Service (Availability) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The software does not properly control the allocation and maintenance of a limited resource, enabling an attacker to influence the resource consumption rate and cause a system slowdown or denial of service.
A high-severity stored Cross-Site Scripting (XSS) vulnerability was identified in the TinyMCE rich text editor. The flaw exists in the handling of the 'protect' configuration option, where forged placeholder comments containing malicious payloads bypass the editor's sanitization routines and execute arbitrary JavaScript during serialization and content restoration.
An authorization bypass and client-side property tampering vulnerability (CVE-2026-47742) in the Shopper headless admin panel (built on Laravel and Livewire) allows low-privileged users to modify arbitrary product records (Insecure Direct Object Reference). This occurs due to unlocked public model properties and a complete lack of access control checks on mutating sub-form store methods.
Shopper is an open-source headless e-commerce administration panel built on Laravel, Livewire, and Filament. Prior to version 2.8.0, the admin tables for PaymentMethods, Currencies, and Carriers exposed inline toggles and per-record actions that could be modified by any authenticated user without verifying the corresponding administrative permissions on the backend.
An Insecure Direct Object Reference (IDOR) vulnerability in Bugsink (versions < 2.2.0) allows authenticated users with access to at least one project to view sensitive event details (including stack traces, local/environment variables, and execution breadcrumbs) belonging to other projects, by supplying a known event UUID directly to the issue event URL paths.
Bugsink prior to version 2.2.0 is vulnerable to Broken Object Level Authorization (BOLA). The issue list view authorizes access based on the project in the URL path but applies requested bulk actions to submitted issue UUIDs globally, without verifying project ownership.
A critical authorization bypass vulnerability in Bugsink prior to version 2.2.0 allows authenticated users to access and resolve sourcemaps and debug files belonging to other projects on the same instance.