Feb 10, 2026·4 min read·26 visits
If you used `unity-cli` versions < 1.8.2 with the `--verbose` flag, your Unity credentials (password, serial, token) were printed in plaintext to your console logs. Attackers with access to your CI/CD history or shell logs can harvest these secrets.
In the world of DevOps, visibility is everything. We want logs, metrics, and traces. But sometimes, tools give us a little *too much* visibility. The `unity-cli` tool, a popular wrapper for automating Unity Game Engine tasks, was found to be indiscriminately logging sensitive credentials—passwords, serials, and auth tokens—directly to standard output when the `--verbose` flag was engaged. This vulnerability turns your CI/CD logs into a treasure map for attackers looking to hijack your game development pipeline.
Automation is the lifeblood of modern game development. Nobody wants to manually click 'Build' in the Unity Editor twenty times a day. Enter @rage-against-the-pixel/unity-cli, a nifty TypeScript wrapper that makes headless Unity builds on CI/CD servers bearable.
Like any good CLI tool, it offers a --verbose flag. When things go wrong (and with Unity, they always go wrong), developers instinctively reach for this flag to see what's happening under the hood. It’s a standard debugging reflex.
However, in this specific instance, that reflex was dangerous. The developers behind unity-cli made a classic error: they confused 'debugging context' with 'data dumping'. By trying to be helpful and show the user exactly what arguments were being passed to the system, they inadvertently built a mechanism to broadcast the keys to the kingdom.
The vulnerability (CWE-532) boils down to a single line of code that prioritized convenience over hygiene. The application uses the popular commander library to parse command-line arguments. This library returns an options object containing every flag passed by the user.
The flaw resided in src/cli.ts. When the verbose flag was detected, the application decided to log the entire configuration state. Instead of selectively logging safe parameters (like buildTarget or projectPath), the code blindly passed the entire options object to JSON.stringify().
This is the digital equivalent of emptying your pockets onto the table to find your keys, but also dropping your credit card, social security card, and diary in the process. Because JSON.stringify() is impartial, it serialized everything: email, password, serial, and token included.
Let's look at the diff. It’s rare to see a vulnerability so concise yet so damaging. In the vulnerable versions, the logging logic was brutally simple:
// src/cli.ts (Vulnerable)
program.command('sign-package')
.action(async (options) => {
if (options.verbose) {
Logger.instance.logLevel = LogLevel.DEBUG;
}
// 💀 THE KILL SHOT:
// Direct serialization of the raw options object
Logger.instance.debug(JSON.stringify(options));
// ... logic continues ...
});The fix, introduced in commit 8d4d67b23d7c5fd8f00df3f0f10bec2961c95342, implements a sanitization layer. The developers added a scrubSensitiveData method that recursively walks the object and checks keys against a blacklist.
// src/logger.ts (Patched)
private readonly SENSITIVE_KEYS = [
'password', 'email', 'serial', 'token',
'config', 'organization', 'username'
];
private scrubSensitiveData(obj: any): any {
// ... recursion logic ...
if (this.SENSITIVE_KEYS.includes(key)) {
newObj[key] = '[REDACTED]';
}
// ...
}They also added maskCredential to hook into CI-specific masking features (like GitHub Actions ::add-mask::), ensuring that even if a value slips through elsewhere, the runner UI might still hide it.
Exploiting this doesn't require a disassembler or a heap spray. It requires a web browser and a scroll wheel. We call this 'Scroll Justacking'.
The Scenario:
unity-cli for building game artifacts.--verbose to diagnose why a build is failing in CI, or they have it enabled by default in a 'Debug' workflow.unity-cli activate-license --email "admin@studio.com" --password "S3cr3tUnityP@ss" --verbose{"email":"admin@studio.com","password":"S3cr3tUnityP@ss","verbose":true}Once an attacker has these credentials, they can log into the Unity ID portal, revoke licenses (causing a denial of service for the dev team), or potentially access cloud build artifacts depending on the scope of the account.
If you are using @rage-against-the-pixel/unity-cli, patching is mandatory. The fix was released in version 1.8.2.
npm install -g @rage-against-the-pixel/unity-cli@latest.[REDACTED] in your new logs, great. But your old logs are static text files stored on S3 or GitHub's servers. They still contain the plaintext passwords. You must delete these logs.--verbose, assume your Unity password and serial keys are public knowledge. Change them immediately.This serves as a grim reminder: Never trust the user input object. Always use an explicit allowlist when logging configuration objects. If you must log a 'context' object, pass it through a sanitization function first. And for the love of security, if your tool handles passwords, consider accepting them via environment variables (UNITY_PASSWORD) rather than CLI flags to avoid them showing up in process lists (ps aux) as well.
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@rage-against-the-pixel/unity-cli RageAgainstThePixel | < 1.8.2 | 1.8.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-532 |
| Attack Vector | Local / Context Dependent |
| CVSS | 5.9 (Medium) |
| Confidentiality Impact | High |
| Integrity Impact | None |
| Exploit Status | Trivial (Log Inspection) |
A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.
CVE-2026-61824 is a high-severity Cross-Site Scripting (XSS) vulnerability in kepano/defuddle before version 0.19.1. Custom site extractors for platforms such as X/Twitter, Substack, and YouTube constructed HTML representations via template string interpolation without output escaping. This allowed malicious pages to bypass standard parser sanitization routines and execute arbitrary JavaScript.
A high-severity vulnerability exists in KeystoneJS, a popular Node.js CMS and GraphQL framework, where the query resolution engine fails to validate signed negative integers within the pagination subsystem. Unauthenticated remote attackers can leverage this flaw to bypass the 'graphql.maxTake' safety boundary. By sending large negative values in the 'take' query parameter, the underlying Prisma ORM interprets the value as an instruction to fetch rows from the end of the collection, allowing malicious actors to bypass pagination limits, trigger database resource exhaustion, and execute application-level Denial of Service (DoS) attacks.
A critical path traversal vulnerability in Atlantis allows authenticated users or repository contributors to execute directory operations outside of the repository directory boundary via crafted workspace parameters in configuration files or API requests.
CVE-2026-76905 is a high-severity Denial of Service (DoS) vulnerability in the getkin/kin-openapi library, specifically inside the openapi3filter sub-package. When processing multipart/form-data request validation errors, a missing nil-pointer guard causes a Go runtime panic during error formatting. This panic terminates the active server process if no recovery handler is present, resulting in a total denial of service. The vulnerability affects versions from v0.10.0 to v0.140.0, and is resolved in v0.141.0.
A critical server-side template injection (SSTI) vulnerability exists in the Volt template engine of the Phalcon PHP framework. In versions 5.15.0 and earlier, raw AST token values for filter arguments in the 'join' filter are directly spliced into the generated PHP template code. This allows an attacker who can influence Volt templates to execute arbitrary PHP code during template rendering.