首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

仿 OSO 風格 PHP 論壇程式原始碼解析(三):readforum.php 核心邏輯與安全隱患審計

     編輯:PHP 綜合知識

本文剖析一套 2000 年代典型的「仿 OSO 風格」PHP 論壇原始碼第三部分 readforum.php,展示早期 PHP 直連 MySQL、註冊全域變量、SQL 拼接、HTML/JS 混寫的典型寫法,並逐一標註安全隱患與現代重構方向。

程式碼結構概覽

readforum.php
├── HTML 骨架(HEAD、CSS、Meta)
├── include("c:mydbheader.inc")  // 絕對路徑包含資料庫設定
├── 邏輯區()
│   ├── 連接 MySQL (mysql_connect + mysql_select_db)
│   ├── 參數處理 ($readflag, $theme_id, $username 等)
│   ├── 發文邏輯 (INSERT fr_t_forumtitle + fr_t_forumcontent)
│   ├── 閱讀計數/回覆計數更新 (UPDATE)
│   └── 查詢主題標題/計數 (SELECT)
└── 表現區(HTML + 內嵌 PHP 印出變數)

關鍵邏輯流程圖解

用戶請求 readforum.php?readflag=123
         ↓
$readflag > 0 ? $theme_id = $readflag : 新增主題流程
         ↓
新增主題:INSERT fr_t_forumtitle (id, state, readcount, replycount, title, createman, replytime)
         ↓
插入內容:INSERT fr_t_forumcontent (id, content, replyman, replyemail, replyhttp, replytime, replyface)
         ↓
更新統計:UPDATE fr_t_forumtitle SET readcount+1, replycount+1, replytime=NOW(), replyman=...
         ↓
查詢顯示:SELECT title, readcount, replycount FROM fr_t_forumtitle WHERE id=$theme_id
         ↓
輸出 HTML:主題標題、閱讀數、回覆數、發新貼/回覆/列表按鈕

安全隱患全景掃描

隱患類型代碼位置風險等級攻擊向量修正方案
SQL 注入全部 mysql_query($tempstr) 直接拼接 $forumtitle、$username、$forumcontent 等🔴 致命title=test', '0',0,-1,'hacked','attacker',NOW());--改用 PDO Prepared Statements:$stmt=$pdo->prepare('INSERT ... VALUES (?,?,?)'); $stmt->execute([$id,$title,$user]);
XSS (儲存型/反射型)print $ls_theme_title、echo $forumcontent 直接輸出未過濾🔴 致命發文內容含 <script>stealCookie()</script>輸出時 htmlspecialchars($str, ENT_QUOTES, 'UTF-8');入庫可選 HTMLPurifier 白名單過濾
註冊全域變量依賴直接使用 $username、$forumtitle 等未定義變量🟠 高register_globals=On 時任意變量覆蓋強制 register_globals=Off,統一從 $_GET/$_POST/$_REQUEST 取值並驗證
硬編碼資料庫憑證mysql_connect('localhost:3306','root','')🟠 高原始碼洩露即資料庫失陷配置檔置於 Web 根目錄外,使用環境變數或 .env 載入
絕對路徑包含include("c:mydbheader.inc")🟡 中遷移部署失敗、路徑遍歷風險改用相對路徑 __DIR__.'/config/db.php' 或 Composer 自動載入
已棄用擴展mysql_* 函數族 (PHP 7.0 移除)🔴 致命無法在 PHP 5.6+ 運行全面遷移至 PDO 或 mysqli
無 CSRF 保護發文表單無 Token🟡 中誘導用戶訪問惡構造頁面自動發文表單加入 <input type="hidden" name="csrf" value="">
無輸入長度/格式驗證標題、內容直接入庫🟡 中超長字串撐爆 VARCHAR、儲存型 XSS前後端雙重驗證:mb_strlen、strip_tags、正則白名單
錯誤資訊洩露die("寫方式打開檔案 $filename 失敗") 等🟢 低路徑、SQL 結構外洩生產環境 display_errors=Off,統一錯誤頁面,記錄詳細日誌

資料庫結構推測(依 SQL 反推)

CREATE TABLE fr_t_forumtitle (
  id INT PRIMARY KEY AUTO_INCREMENT,
  state TINYINT DEFAULT 0,
  readcount INT DEFAULT 0,
  replycount INT DEFAULT -1,  -- 首貼不算回覆
  title VARCHAR(255),
  createman VARCHAR(50),
  replytime DATETIME
);

CREATE TABLE fr_t_forumcontent (
  id INT,                     -- 關聯 fr_t_forumtitle.id
  content TEXT,
  replyman VARCHAR(50),
  replyemail VARCHAR(100),
  replyhttp VARCHAR(255),
  replytime DATETIME,
  replyface TINYINT           -- 表情/頭像代碼
);

現代重構路線圖

  1. 資料存取層:引入 PDO + 單例/依賴注入,封裝 ForumRepository。
  2. 輸入驗證:使用 respect/validation 或 Laravel Validator 定義規則集。
  3. 輸出編碼:模板引擎 (Blade/Twig/Latte) 自動 escape,或統一 e() 助手函數。
  4. CSRF:中介軟體自動驗證 _token。
  5. 認證授權:Session/JWT 識別用戶,替代裸露的 $username。
  6. 分頁/列表:列表頁改用 LIMIT/OFFSET 或游標分頁,避免全表掃描。
  7. 前端分離:API 回傳 JSON,前端 Vue/React 渲染,歷史 SEO 需求可用 SSR/SSG。
  8. 測試覆蓋:PHPUnit 單元測試 Repository、Service;Dusk/E2E 測試關鍵流程。

歷史價值與警示

這段代碼是 PHP 早期「人人都能寫論壇」時代的縮影:功能優先、安全缺位、耦合極高。它提醒我們:

  • 「能跑」不等於「可用」,安全性必須從第一行代碼開始設計。
  • 遺留系統改造成本遠高於初期正確架構,技術債務會複利增長。
  • 現代框架(Laravel/Symfony/CodeIgniter4)已將上述 90% 隱患在框架層解決,不要重複造輪子,也不要重複踩坑。

若您正在維護類似舊專案,建議採取「絞殺者模式」:在新框架中逐模塊重寫,以 API 代理舊系統,漸進式替換,而非大爆炸重寫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved