Skip to content
Renesoft
About Products Services Robotics Cybersecurity Careers Contact
EN SV

Security Advisories

CVE-2026-63656

flyimg — Unauthenticated OS command injection (RCE)

Critical 9.3 CWE-77 CWE-78 PHP · Composer, Docker

The CVE identifier is assigned; the CVE record is not yet published.

9.3/10CriticalCVSS 4.0 base score
LowMediumHighCritical
04.07.09.010
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Summary

flyimg is a self-hosted, on-the-fly image resizer. It assembles an ImageMagick command line as a string and runs it through a shell, and one option reaches that command line without shell escaping.

Technical analysis

Every value on the command line is passed through shell escaping except the webp-method option, which is appended verbatim and then executed by /bin/sh. That option is set from an unauthenticated URL segment, and the default configuration ships with no URL signing and no domain allow-list, so the whole request is attacker-controlled.

The value is taken raw from the URL. The option parser splits each URL segment on _ and stores the right-hand side with no validation: webpm_$(id) becomes webp-method = $(id). There is no numeric cast and no allow-list, even though the option is meant to be an integer 0–6. src/Core/Entity/OptionsBag.php:48-50

Quality and the output path are escaped — webp-method is appended verbatim. On the very lines that build the webp arguments, quality and the output path are wrapped in escapeshellarg(), but $webpMethod is concatenated directly. Command::addArgument() appends the string raw and __toString() joins it into one command. src/Core/Processor/ImageProcessor.php:233-238 · src/Core/Entity/Command.php:31-47

The command string is run through a shell. Processor.php passes the assembled string to proc_open(). Given a string (not an argv array), proc_open() executes it via /bin/sh -c on Linux — so any shell metacharacter in webp-method is interpreted, not treated as literal argument text. src/Core/Processor/Processor.php:66

ImageProcessor.php — the webp argument build
// quality and the output path go through escapeshellarg()…
$parameter = "-quality " . escapeshellarg($quality) .
    " -define webp:thread-level=" . $webpThreads .
    " -define webp:method=" . $webpMethod .    // <-- appended RAW, no escapeshellarg()
    " -define webp:lossless=" . $lossLess .
    " " . escapeshellarg($outputImage->getOutputTmpPath());

Proof of concept

Renesoft confirmed this against the real package in an isolated environment, with no live systems. The attack path, then the recorded test output:

  1. Send a single unauthenticated GET with the payload in the webp-method segment — GET /upload/o_webp,webpm_$(id)/https://attacker.example/1x1.png. o_webp forces webp output regardless of the Accept header, and the default restricted_domains: false lets flyimg fetch any source image URL the request names.
  2. flyimg parses webpm_$(id) into webp-method = $(id) — and builds the ImageMagick command containing … -define webp:method=$(id) …, with the attacker's value unescaped.
  3. proc_open() runs the string through /bin/sh -c — the shell expands $(id) and executes it on the server. None of the injection characters are the parser's own _ / , delimiters, so they pass through cleanly.
poc — real flyimg Command + proc_open · loopback, no live systems
$ php poc/poc.php

ATTACK   webp-method = "4 & echo INJECTED… > FLYIMG_PWNED.txt"
  -> injected command executed (marker created): YES
CONTROL  webp-method = "4"  (benign)
  -> marker created: no

exit 0 · VERDICT: CONFIRMED

Impact

An unauthenticated attacker runs arbitrary operating-system commands as the flyimg service process with a single request, out of the box on the official Docker image. What follows from that depends on the deployment's permissions and network controls.

Affected versions

Affected
0.1.2 – 1.12.2
Fixed
1.12.3
CVSS
9.3 (4.0)
Weakness
CWE-77 · CWE-78
Ecosystem
PHP · Composer, Docker
Disclosed
2026-07-30

Remediation

Fixed in 1.12.3, which escapes the value like the others. Deployments should upgrade and, as defence in depth, set a URL signing key.

Timeline

  • 2026-06-28Discovered, proven, and reported privately through GitHub private vulnerability reporting.
  • 2026-07-30Fixed in 1.12.3; advisory published and CVE-2026-63656 assigned.

References

  • GHSA-rmgv-gcwh-2pqh
  • Packagist: flyimg/flyimg
  • Source

← All advisories

Renesoft

Conviction, compiled.

© 2026 Renesoft ABReg. no. 559593-4489Malmö, SwedenCareersCybersecurityPrivacy policy
v7.4.2 · cbb0edd