
CakePHP 5.4.2 - उच्च - रिमोट - SQLi - WindowExpression रेंज/फ्रेम ऑफसेट SQL में जोड़े गए
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-window-sqli
Class: SQLi Reach: Remote
CakePHP 5.4.2 (887b641) - Cake Software Foundation
CVE-2026-79752 ने FunctionsBuilder के cast / extract / dateAdd को ensureSimpleString() के साथ बंद कर दिया। WindowExpression::range() और frame() उस फिक्स में नहीं थे। rows() और groups() ?int लेते हैं। range() अभी भी एक स्ट्रिंग लेता है। buildOffsetSql ऑफ़सेट, फ़्रेम प्रकार, और PRECEDING / FOLLOWING को OVER में जोड़ता है। बाइंडर का उपयोग तब तक नहीं होता जब तक ऑफ़सेट पहले से ExpressionInterface न हो।
एक ऐप जो रिक्वेस्ट डेटा को func()->count('*')->over()->range($start, $end) में फ़ॉरवर्ड करता है, कॉलर की स्ट्रिंग को RANGE BETWEEN में बिना बाइंड और बिना कोट के डाल देता है।
| ID | अभी तक कोई CVE नहीं |
| Class | SQLi |
| Reach | Remote (ऐप जो रिक्वेस्ट डेटा को range() / frame() में फ़ॉरवर्ड करता है) |
| CWE | CWE-89 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Product | CakePHP (cakephp/database) |
| Affected | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | ऐप जो क्वेरी/फ़ॉर्म डेटा को ->over()->range($start, $end) / frame() में फ़ॉरवर्ड करता है |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1 |
एक उपयोगकर्ता जो ऐप द्वारा फ़ॉरवर्ड किए जाने वाले विंडो बाउंड को सेट कर सकता है (एनालिटिक्स "पिछले N दिन", एक रिपोर्ट बिल्डर) OVER क्लॉज़ को अतिरिक्त SQL में बदल देता है।
| Privilege | Method / sink | Kind | Lab-proven or inferred |
|---|---|---|---|
OVER (RANGE BETWEEN ...) में SQL फ़्रैगमेंट जोड़ना | GET /?mode=range&start= को AggregateExpression::range($start, $end) / WindowExpression::frame() में | संकलित SQL की अखंडता | Lab-proven। संकलित SQL है RANGE BETWEEN 1) /* CAKEPHP-WINDOW-SQLI-WITNESS */ -- PRECEDING एक खाली बाइंडर के साथ |
| ऐप के DB उपयोगकर्ता के रूप में पंक्तियाँ पढ़ना या संशोधित करना | वही क्वेरी, निष्पादित | DB की अखंडता / recon | स्प्लिस से अनुमानित। यह लैब केवल-संकलन है |
| उसी तरह फ़्रेम प्रकार या दिशा बदलना | frame($type, $offset, $direction, ...) उन स्ट्रिंग्स को भी जोड़ता है | संकलित SQL की अखंडता | sql() / buildOffsetSql() से अनुमानित। लैब ने range() का उपयोग किया |
rows() / groups() को उसी तरह तोड़ना | टाइप्ड ?int | बंद | Lab-proven बंद। rows(3) है ROWS BETWEEN 3 PRECEDING, न कोट किया गया, न बाइंड किया गया |
इस पिन पर बंद: FunctionsBuilder cast / extract / dateAdd / jsonValue (CVE-2026-79752 / CVE-2026-77635); Query::limit / offset (टाइप्ड int)। डिफ़ॉल्ट cakephp/app क्वेरी-स्ट्रिंग डेटा के साथ range() को कॉल नहीं करता। बचा हुआ हिस्सा प्रलेखित विंडो API है। स्केलेटन ऐप पर अनऑथेंटिकेटेड RCE नहीं। शेल नहीं।
उसी पिन के अवशेष: collate SQLi, attachment CRLF, cache unserialize।
2026 FunctionsBuilder SQLi GHSAs के बाद मैंने cakephp/cakephp 5.4.2 को पिन किया। उस टैग पर दस शिकार। CSRF / FormProtection, View LFI, BodyParser XXE, mass assignment, helper XSS, और trustProxy के बिना clientIp() इस बार में खाली लौटे। WindowExpressionTest::testRange अभी भी यह दावा करता है:
$w = (new WindowExpression())->range("'1 day'", "'10 days'");
buildOffsetSql कभी स्ट्रिंग ऑफ़सेट को बाइंड नहीं करता:
protected function buildOffsetSql(
ValueBinder $binder,
ExpressionInterface|string|int|null $offset,
string $direction,
): string {
if ($offset === 0) {
return 'CURRENT ROW';
}
if ($offset instanceof ExpressionInterface) {
$offset = $offset->sql($binder);
}
return sprintf('%s %s', $offset ?? 'UNBOUNDED', $direction);
}
$binder का उपयोग तब तक नहीं होता जब तक ऑफ़सेट पहले से ExpressionInterface न हो।
पहले से दर्ज गलत मोड़: rows() को छेद मानना (यह टाइप्ड int है); यह दावा करना कि स्टॉक cakephp/app इसे सार्वजनिक फ़ॉर्म पर उजागर करता है; SQLite में इंजेक्टेड SQL को oracle के रूप में निष्पादित करना (POC-READY केवल-संकलन है); एक रिवर्स शेल। नाटक।
python3 cakephp-window-sqli-Abraxas-Labs.py
या
cd lab
./run.sh
लक्ष्य केवल http://127.0.0.1:19440। छोटा PHP ऐप, cakephp/database 5.4.2, SQLite :memory:। GET /?mode=range&start= को स्ट्रिंग के रूप में range() में पास किया जाता है। GET /?mode=rows&n=3 int नियंत्रण है।
SUCCESS cakephp-window-sqli pin=5.4.2 range-raw=yes rows-numeric=yes bound=no quoted=no CAKEPHP-WINDOW-SQLI-WITNESS
IOC संकलित SQL:
SELECT (COUNT(*) OVER (RANGE BETWEEN 1) /* CAKEPHP-WINDOW-SQLI-WITNESS */ -- PRECEDING AND CURRENT ROW)) AS n FROM sqlite_master
नियंत्रण:
SELECT (COUNT(*) OVER (ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)) AS n FROM sqlite_master
संख्यात्मक ऑफ़सेट बाइंड करें। फ़्रेम प्रकार (RANGE / ROWS / GROUPS) और दिशा (PRECEDING / FOLLOWING) को allowlist करें। इंटरवल स्ट्रिंग्स के लिए, उन्हें कोट करें या ExpressionInterface की आवश्यकता रखें। एक टेस्ट जोड़ें कि गैर-int range() ऑफ़सेट एक प्लेसहोल्डर या कोटेड लिटरल बने, कच्चा SQL नहीं।
887b641de9f7aba06071f98f17edcbc573cbcf63)WindowExpression.php · AggregateExpression.phpGNU Affero GPL v3.0। देखें LICENSE। केवल लूपबैक लैब। कोई वारंटी नहीं।