初次接觸 Ecshop、Discuz! 時,免費開源且功能豐富令人驚嘆。但深入二次開發、審計核心代碼後發現:這些系統存在根本性架構缺陷,無法支撐高併發、高安全要求的生產環境。本文針對兩大核心問題——SQL 拼接普遍化與輸入轉義缺失——進行深度剖析。
Ecshop 核心模型 cls_mysql 封裝的是 mysql_* 系列函數(已棄用),所有查詢均採用字串拼接:
// Ecshop 典型查詢
$w_openid = $db->getOne("SELECT `wxid` FROM `wxch_user` WHERE `wxid` = '$openid'");
// 典型寫入
$wxch_user_sql = "INSERT INTO `$thistable` (`user_name`,`password`,`field3`,`field4`)
VALUES ('$variable1','$variable2','value3','value4')";
$db->query($wxch_user_sql);
後果:
mysql_connect,不支援 mysqli 的多語句、事務控制、SSL 等新特性。// mysqli 預處理
$mysqli = new mysqli("host", "user", "pass", "db");
$stmt = $mysqli->prepare("INSERT INTO `user` (`name`, `pwd`) VALUES (?, ?)");
$stmt->bind_param("ss", $safe_name, $safe_pwd);
$stmt->execute();
// PDO
$pdo->prepare("INSERT INTO `user` (`name`, `pwd`) VALUES (:name, :pwd)")
->execute([':name'=>$safe_name, ':pwd'=>$safe_pwd]);
代碼庫中極少見 mysql_real_escape_string() 或 addslashes():
// 危險代碼:直接拼接 $_POST
$unsafe = $_POST["user-input"];
$sql = "INSERT INTO `t` (`col`) VALUES ('$unsafe')"; // 注入點
正確姿勢(若必須用舊 API):
$unsafe = $_POST["user-input"];
$safe = mysql_real_escape_string($unsafe); // 必須在連接建立後調用
$sql = "INSERT INTO `t` (`col`) VALUES ('$safe')";
實測:裸露 Ecshop/Discuz! 論壇上線 24h 內即被掃描機器人發現並注入垃圾帖、廣告帳號。修補成本極高,需全站掃描所有 $_GET/$_POST/$_REQUEST 入口。
{php}... 標籤可直接執行 PHP,模板注入風險極高。require_once 到處硬編碼,擴展性極差。開發這些產品的公司(如上海商創、騰訊)技術實力雄厚,但高質量代碼、安全審計、架構重構都集中在商業授權版/雲服務版。開源版本更多是「引流產品」「教學樣本」,社區維護力度有限,已知漏洞修復周期長。
laravel-shop、fecshop)開源不等於「免費且可直接商用」。代碼審計是上線前的必修課,Ecshop/Discuz! 的教訓值得每個 PHP 開發者深思。