Skip to content

Commit 56e8b84

Browse files
committed
Post/product content parameter changed in model edit method, added file checks to load only templates that are html files inside theme folder, previously other files could be loaded from theme folder, vulnerability reported by @0xHamy
1 parent f5d0a12 commit 56e8b84

File tree

2 files changed

+92
-28
lines changed

2 files changed

+92
-28
lines changed

admin/controller/editor/editor.php

+84-20
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ private function loadEditorData() {
116116
return $data;
117117
}
118118

119+
/*
120+
Load theme sections, components and inputs
121+
*/
122+
private function loadEditorAssets() {
123+
}
124+
119125
/*
120126
Load theme sections, components and inputs
121127
*/
@@ -169,14 +175,14 @@ function index() {
169175
$posts = [];
170176

171177
foreach ($results['post'] as $post) {
172-
$slug = $post['slug'];
178+
$slug = htmlspecialchars($post['slug']);
173179
$url = url('content/page/index',['slug' => $slug, 'post_id' => $post['post_id']]);
174180

175-
$posts[$slug] = [
176-
'name' => $slug,
181+
$posts["$slug-page"] = [
182+
'name' => "$slug-page",
177183
'file' => $post['template'] ? $post['template'] : 'content/page.html',
178184
'url' => $url . ($theme ? '?theme=' . $theme : ''),
179-
'title' => $post['name'],
185+
'title' => htmlspecialchars($post['name']),
180186
'post_id' => $post['post_id'],
181187
'folder' => '',
182188
'className' => 'page',
@@ -197,18 +203,75 @@ function index() {
197203
$className = 'url';
198204
$current_page = [];
199205

206+
//check if url and template is relative
207+
if (strpos($url, '//') !== false && strpos($template, '..') !== false) {
208+
$this->notFound();
209+
210+
exit();
211+
}
212+
213+
//check if the url has extension and is a html file and exists in the theme folder
214+
if (strpos($url, '.') !== false) {
215+
if (substr_compare($url, '.html', -5 ,5) === 0) {
216+
if (! file_exists(DIR_THEMES . $theme . DS . $url)) {
217+
$this->notFound();
218+
219+
exit();
220+
}
221+
} else {
222+
$this->notFound();
223+
224+
exit();
225+
}
226+
}
227+
228+
//check if template belongs to theme and is a html file
229+
if (substr_compare($template, '.html', -5 ,5) === 0) {
230+
if (! file_exists(DIR_THEMES . $theme . DS . $template)) {
231+
$this->notFound();
232+
233+
exit();
234+
}
235+
} else {
236+
$this->notFound();
237+
238+
exit();
239+
}
240+
200241
if ($route && isset($route['module'])) {
201242
switch ($route['module']) {
202243
case 'product/product/index':
203244
$className = 'product';
204-
$current_page['product_id'] = $route['product_id'];
245+
246+
if (isset($route['product_id'])) {
247+
$current_page['product_id'] = $route['product_id'];
248+
} else {
249+
if (isset($this->request->get['product_id'])) {
250+
$current_page['product_id'] = $this->request->get['product_id'];
251+
} else {
252+
if (isset($route['slug'])) {
253+
$current_page['slug'] = htmlspecialchars($route['slug']);
254+
}
255+
}
256+
}
205257

206258
break;
207259

208260
case 'content/post/index':
209261
case 'content/page/index':
210262
$className = 'page';
211-
$current_page['post_id'] = $route['post_id'];
263+
264+
if (isset($route['post_id'])) {
265+
$current_page['post_id'] = $route['post_id'];
266+
} else {
267+
if (isset($this->request->get['post_id'])) {
268+
$current_page['post_id'] = $this->request->get['post_id'];
269+
} else {
270+
if (isset($route['slug'])) {
271+
$current_page['slug'] = htmlspecialchars($route['slug']);
272+
}
273+
}
274+
}
212275

213276
break;
214277
}
@@ -561,14 +624,15 @@ function save() {
561624
'template' => $file,
562625
'type' => $type,
563626
'image' => 'posts/2.jpg', //'placeholder.svg'
564-
'post_content' => [[
565-
'slug' => $slug,
566-
'name' => $name,
567-
'content' => $content,
568-
'language_id' => $this->global['language_id'],
569-
]],
570627
] + $this->global,
571-
'site_id' => [$this->global['site_id']], ] + $this->global);
628+
'post_content' => [[
629+
'slug' => $slug,
630+
'name' => $name,
631+
'content' => $content,
632+
'language_id' => $this->global['language_id'],
633+
]],
634+
'site_id' => [$this->global['site_id']],
635+
] + $this->global);
572636

573637
if ($result['post']) {
574638
$post_id = $result['post'];
@@ -591,14 +655,14 @@ function save() {
591655
'status' => 1, //active
592656
'template' => $file,
593657
'price' => $price,
594-
'product_content' => [[
595-
'slug' => $slug,
596-
'name' => $name,
597-
'name' => $name,
598-
'content' => $content,
599-
'language_id' => $this->global['language_id'],
600-
]],
601658
] + $this->global,
659+
'product_content' => [[
660+
'slug' => $slug,
661+
'name' => $name,
662+
'name' => $name,
663+
'content' => $content,
664+
'language_id' => $this->global['language_id'],
665+
]],
602666
'site_id' => [$this->global['site_id']], ] + $this->global);
603667

604668
if ($result['product']) {

admin/template/editor/editor.tpl

+8-8
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ if(isset($this->themeBlocks) && is_array($this->themeBlocks))
4040
foreach ($this->themeBlocks as $id => $file) {?>
4141
4242
[data-v-theme-blocks]|src = $file
43-
[data-v-theme-blocks]|id = <?php echo "theme-$id";?>
43+
[data-v-theme-blocks]|id = <?php echo 'theme-' . htmlspecialchars($id);?>
4444
4545
[data-v-theme-blocks]|after = <?php
4646
}
@@ -55,7 +55,7 @@ if(isset($this->themeSections) && is_array($this->themeSections))
5555
foreach ($this->themeSections as $id => $file) {?>
5656
5757
[data-v-theme-sections]|src = $file
58-
[data-v-theme-sections]|id = <?php echo "theme-$id";?>
58+
[data-v-theme-sections]|id = <?php echo 'theme-' . htmlspecialchars($id);?>
5959
6060
[data-v-theme-sections]|after = <?php
6161
}
@@ -70,7 +70,7 @@ if(isset($this->themeJs) && is_array($this->themeJs))
7070
foreach ($this->themeJs as $id => $file) {?>
7171
7272
[data-v-theme-js]|src = $file
73-
[data-v-theme-js]|id = <?php echo "theme-$id";?>"
73+
[data-v-theme-js]|id = <?php echo 'theme-' . htmlspecialchars($id);?>
7474
7575
[data-v-theme-js]|after = <?php
7676
}
@@ -89,11 +89,11 @@ if (isset($this->$name)) {
8989
9090
if (isset($option['folder']) && ($optgroup != $option['folder'])) {
9191
$optgroup = $option['folder'];
92-
echo '<optgroup label="' . ucfirst($optgroup) . '">';
92+
echo '<optgroup label="' . ucfirst(htmlspecialchars($optgroup)) . '">';
9393
}
9494
?>
9595

96-
@templates-select-option|value = echo $option['file'];
96+
@templates-select-option|value = echo htmlspecialchars($option['file']);
9797
@templates-select-option = <?php echo htmlspecialchars(ucfirst($option['title']));?>
9898
@templates-select-option|addNewAttribute = <?php if ($option['file'] == 'blank.html') echo 'selected';?>
9999

@@ -121,14 +121,14 @@ form[data-vvveb-url]|action = $this->saveUrl
121121
foreach ($this->languagesList as $language) {
122122
//$content = $this->{{type}}['{{type}}_content'][$language['language_id']] ?? [];
123123
?>
124-
[data-v-languages] [data-v-language-id]|id = <?php echo 'lang-' . $language['code'] . '-' . $_lang_instance;?>
124+
[data-v-languages] [data-v-language-id]|id = <?php echo 'lang-' . htmlspecialchars($language['code']) . '-' . $_lang_instance;?>
125125
[data-v-languages] [data-v-language-id]|addClass = <?php if ($_i == 0) echo 'show active';?>
126126

127127
@language [data-v-language-name] = $language['name']
128128
@language [data-v-language-code]|name = $language['code']
129129
@language [data-v-language-img]|title = $language['name']
130-
@language [data-v-language-img]|src = <?php echo 'language/' . $language['code'] . '/' . $language['code'] . '.png';?>
131-
@language [data-v-language-link]|href = <?php echo '#lang-' . $language['code'] . '-' . $_lang_instance?>
130+
@language [data-v-language-img]|src = <?php echo 'language/' . htmlspecialchars($language['code']) . '/' . htmlspecialchars($language['code']) . '.png';?>
131+
@language [data-v-language-link]|href = <?php echo '#lang-' . htmlspecialchars($language['code']) . '-' . $_lang_instance?>
132132
@language [data-v-language-link]|addClass = <?php if ($_i == 0) echo 'active';?>
133133

134134
@language|after = <?php

0 commit comments

Comments
 (0)