本文主要和大家探討一下`ThinkPHP`的安全注意事項(xiàng),可以作為`ThinkPHP`建議的安全規(guī)范實(shí)踐。(如果有新的內(nèi)容我也會(huì)及時(shí)補(bǔ)充)
>[danger]### 首先,沒有絕對(duì)的安全,只要你有足夠的安全意識(shí)才能盡可能的杜絕安全隱患。規(guī)范的使用框架,能讓你盡量避免一些看起來比較幼稚的安全問題。本文描述的安全注意事項(xiàng)主要是指生產(chǎn)環(huán)境下面的安全策略,本地開發(fā)的情況下有時(shí)候?yàn)榱苏{(diào)試的需要安全并不是第一考慮。
ThinkPHP在考慮開發(fā)體驗(yàn)的同時(shí),仍然十分重視框架的底層安全,雖然屢有安全漏洞被播報(bào),但官方都是第一時(shí)間進(jìn)行修復(fù)處理,而且大部分漏洞只要開發(fā)者有一定的安全意識(shí)都是可以避免的,今年也和國(guó)內(nèi)的幾個(gè)安全團(tuán)隊(duì)建立了合作關(guān)系,有助于提前發(fā)現(xiàn)和及時(shí)修正框架可能被利用的漏洞或者隱患。
## 規(guī)范部署
這一點(diǎn)很多開發(fā)者不是特別重視,安全是一個(gè)整體性的問題,任何一個(gè)環(huán)節(jié)出問題,帶來的后果都是一樣的嚴(yán)重,部署的安全策略是一個(gè)基礎(chǔ)安全問題。
很多開發(fā)者往往不按照官方的部署規(guī)范進(jìn)行部署,請(qǐng)務(wù)必把你的`WEB`根目錄指向`public`目錄而不是應(yīng)用根目錄,并且不要隨意更改入口文件的位置。`public`目錄下面不要放除了入口文件和資源文件以外的其它應(yīng)用文件。
## 關(guān)閉調(diào)試模式
在部署到生產(chǎn)環(huán)境的時(shí)候,確保你已經(jīng)關(guān)閉了調(diào)試模式,可以通過修改環(huán)境變量的方式關(guān)閉調(diào)試模式。
```
APP_DEBUG=false
```
>[danger] 無論是本地開發(fā)還是生產(chǎn)環(huán)境部署,都不建議直接通過修改配置文件的方式開啟/關(guān)閉調(diào)試模式,而應(yīng)該使用環(huán)境變量(本地開發(fā)可以通過定義`.env`文件)。
關(guān)閉調(diào)試模式后,系統(tǒng)的健康狀態(tài)和運(yùn)行監(jiān)控主要依靠日志或者你使用的監(jiān)控服務(wù)。所以,要養(yǎng)成定時(shí)檢查日志和運(yùn)行狀態(tài)的習(xí)慣。
## 請(qǐng)求變量過濾
永遠(yuǎn)不要相信用戶的輸入,這是一句至理名言。盡可能的過濾請(qǐng)求變量能有效防范大部分的漏洞和隱患。
框架建議的獲取請(qǐng)求變量的方法是`Request`類的`param`方法(如非必要不要再使用`get`或者`post`方法獲取,更不要使用原生的`$_GET`/`$_POST`等方法獲取)。
```
public function index(Request $request)
{
$name = $request->param('name');
// 在這里可以根據(jù)你的業(yè)務(wù)需求進(jìn)行更嚴(yán)謹(jǐn)?shù)倪^濾
// 例如 $name = $request->param('name','','htmlentities,strtolower');
// 或者使用驗(yàn)證器進(jìn)行專門的驗(yàn)證
}
```
對(duì)于有明確類型的請(qǐng)求變量,可以在使用`param`方法的時(shí)候使用**類型強(qiáng)制轉(zhuǎn)換**,例如:
```
public function index(Request $request)
{
// 強(qiáng)制轉(zhuǎn)換字符串?dāng)?shù)據(jù)
$name = $request->param('name/s');
// 強(qiáng)制轉(zhuǎn)換整型數(shù)據(jù)
$name = $request->param('id/d');
// 強(qiáng)制轉(zhuǎn)換浮點(diǎn)型數(shù)據(jù)
$name = $request->param('score/f');
}
```
或者直接使用方法參數(shù)獲取請(qǐng)求變量
```
public function index(string $name)
{
// 在這里可以根據(jù)你的業(yè)務(wù)需求進(jìn)行更嚴(yán)謹(jǐn)?shù)倪^濾
// 或者使用驗(yàn)證器進(jìn)行專門的驗(yàn)證
}
```
>[info] 如果你需要對(duì)所有數(shù)據(jù)進(jìn)行處理,可以設(shè)置全局的過濾方法。對(duì)不同的應(yīng)用需求設(shè)置`default_filter`過濾規(guī)則(默認(rèn)沒有任何過濾規(guī)則),常見的安全過濾函數(shù)包括`stripslashes`、`htmlentities`、`htmlspecialchars`和`strip_tags`等,請(qǐng)根據(jù)業(yè)務(wù)場(chǎng)景選擇最合適的過濾方法。
如果需要獲取多個(gè)數(shù)據(jù),建議使用`only`方法指定需要獲取的變量名稱,避免有些不懷好意的數(shù)據(jù)提交導(dǎo)致權(quán)限問題。
```
public function index(Request $request)
{
// 指定表單數(shù)據(jù)名稱
$data = $request->only(['name','title']);
}
```
當(dāng)你使用數(shù)據(jù)庫或者模型操作寫入數(shù)據(jù)的時(shí)候,也可以指定字段,避免非法和不希望的字段寫入數(shù)據(jù)庫。
```
// 模型
User::allowField(['name','title'])
->save($data);
// 數(shù)據(jù)庫
Db::name('user')
->field(['name','title'])
->insert($data);
```
模型還有一個(gè)[只讀字段](http://www.imay365.com/manual/thinkphp5_1/354049)的功能能避免你的數(shù)據(jù)受到外部的修改。
## 上傳檢測(cè)
網(wǎng)站的上傳功能也是一個(gè)非常容易被攻擊的入口,所以對(duì)上傳功能的安全檢查是尤其必要的。
系統(tǒng)的`think\File`類提供了文件上傳的安全支持,包括對(duì)文件后綴、文件類型、文件大小以及上傳圖片文件的合法性檢查,確保你已經(jīng)在上傳操作中啟用了這些合法性檢查,可以參考手冊(cè)的[上傳章節(jié)](http://www.imay365.com/manual/thinkphp5_1/354121)。
## SQL注入
ThinkPHP的查詢統(tǒng)一使用了`PDO`的`prepare`預(yù)查詢和參數(shù)綁定機(jī)制,能有效的避免SQL注入的發(fā)生。但不代表絕對(duì)安全,如果你缺乏良好的代碼規(guī)范,仍然有可能被利用。
>[danger] 一個(gè)最簡(jiǎn)單的原則就是不要讓用戶決定你的查詢條件(或者字段排序)和控制你的查詢數(shù)據(jù)。
對(duì)于一些字符串的查詢條件(包括原生查詢)或者特殊的查詢(包括`ORDER`部分),需要手動(dòng)進(jìn)行參數(shù)綁定。
```
// 錯(cuò)誤的
Db::query("select * from think_user where id=$id AND status=$statis");
// 正確的
Db::query("select * from think_user where id=? AND status=?", [ $id, $status]);
// 正確的
Db::execute("update think_user set name=:name where status=:status", [
'name' => 'thinkphp',
'status' => 1
]);
```
對(duì)于使用了`whereExp`和`whereRaw`方式的查詢,你也需要使用參數(shù)綁定。
```
Db::name('user')
->whereRaw('id > ? AND status = ?',[10, 1])
->select();
```
## 使用驗(yàn)證器
對(duì)于大量的表單需要驗(yàn)證的情況,建議使用[驗(yàn)證器](http://www.imay365.com/manual/thinkphp5_1/354102)功能統(tǒng)一進(jìn)行數(shù)據(jù)的合規(guī)驗(yàn)證。驗(yàn)證器的驗(yàn)證操作應(yīng)該在控制器或者路由階段使用`validate`方法進(jìn)行處理,模型的數(shù)據(jù)驗(yàn)證功能新版已經(jīng)取消不再建議使用,模型和數(shù)據(jù)庫操作的時(shí)候應(yīng)該傳入經(jīng)過安全處理過的數(shù)據(jù)。
## XSS攻擊
跨站腳本攻擊(cross-site scripting,簡(jiǎn)稱 `XSS`),XSS是一種在web應(yīng)用中的計(jì)算機(jī)安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。
在渲染輸出的頁面中,要對(duì)一些數(shù)據(jù)進(jìn)行安全處理,防止被惡意利用造成XSS攻擊,如果是5.1版本的話,所有的輸出都已經(jīng)經(jīng)過了`htmlentities` 轉(zhuǎn)義輸出,確保安全。如果是5.0版本的話,你可以自定義一個(gè)xss過濾函數(shù),在模板文件中對(duì)一些關(guān)鍵內(nèi)容變量進(jìn)行函數(shù)處理。
## CSRF
CSRF 跨站請(qǐng)求偽造是 Web 應(yīng)用中最常見的安全威脅之一,攻擊者偽造目標(biāo)用戶的HTTP請(qǐng)求,然后此請(qǐng)求發(fā)送到有CSRF漏洞的網(wǎng)站,網(wǎng)站執(zhí)行此請(qǐng)求后,引發(fā)跨站請(qǐng)求偽造攻擊。攻擊者利用隱蔽的HTTP連接,讓目標(biāo)用戶在不注意的情況下單擊這個(gè)鏈接,由于是用戶自己點(diǎn)擊的,而他又是合法用戶擁有合法權(quán)限,所以目標(biāo)用戶能夠在網(wǎng)站內(nèi)執(zhí)行特定的HTTP鏈接,從而達(dá)到攻擊者的目的。
開啟表單令牌驗(yàn)證,盡量開啟強(qiáng)制路由并嚴(yán)格規(guī)范每個(gè)URL請(qǐng)求,定義單獨(dú)的MISS路由規(guī)則。
遵循請(qǐng)求類型的使用規(guī)范并做好權(quán)限驗(yàn)證,刪除操作必須使用`DELETE`請(qǐng)求,數(shù)據(jù)更改操作必須使用` POST`、`PUT` 或者 `PATCH` 請(qǐng)求方法,`GET`請(qǐng)求不應(yīng)該更改任何數(shù)據(jù)。
## 會(huì)話劫持
會(huì)話劫持是指攻擊者利用各種手段來獲取目標(biāo)用戶的`session id`。一旦獲取到`session id`,那么攻擊者可以利用目標(biāo)用戶的身份來登錄網(wǎng)站,獲取目標(biāo)用戶的操作權(quán)限。
有效的防護(hù)策略包括:
在每次會(huì)話啟動(dòng)的時(shí)候,調(diào)用`regenerate`方法。
```
Session::start();
Session::regenerate(true);
```
更改`session`配置參數(shù),開啟安全選項(xiàng):
```
'use_trans_sid' => 0,
'httponly' => true,
'secure' => true,
```
## 升級(jí)到安全版本
官方會(huì)對(duì)一些安全隱患和潛在漏洞進(jìn)行修復(fù),并且發(fā)布一個(gè)更為安全的版本。請(qǐng)確認(rèn)你升級(jí)到更安全的版本,確保底層的安全和健壯性。
目前各個(gè)版本的建議版本如下:
大版本 | 安全建議版本
---|---
3.2| `3.2.4+`
5.0| `5.0.21+`
5.1|`5.1.25+`
關(guān)注官方的公眾號(hào)和[開發(fā)者周刊](http://www.imay365.com/thinkphp/weekly/content),注意最新的安全更新。
## 業(yè)務(wù)邏輯安全
這個(gè)屬于應(yīng)用層面的安全,很多漏洞源于某個(gè)業(yè)務(wù)邏輯自身的安全隱患,包括沒有做合理的數(shù)據(jù)驗(yàn)證和權(quán)限檢查,尤其是涉及資金及財(cái)務(wù)層面的,一定要做更多的安全檢查,并且開啟事務(wù)。一個(gè)好的建議是更多的對(duì)應(yīng)用進(jìn)行分層設(shè)計(jì),減少每層的復(fù)雜性,獨(dú)立的分層設(shè)計(jì)便于提高安全性。
## 服務(wù)器安全
最后一點(diǎn)是運(yùn)維階段需要特別注意的,及時(shí)更新服務(wù)器的安全補(bǔ)丁,確保沒有可利用的公開系統(tǒng)漏洞,包括你的數(shù)據(jù)庫系統(tǒng)安(尤其是數(shù)據(jù)備份工作)。
## 附錄
附上一些有價(jià)值的WEB安全相關(guān)內(nèi)容作為參考(陸續(xù)補(bǔ)充)
* [淺談PHP安全規(guī)范](http://www.freebuf.com/articles/web/184567.html)
* [前端安全系列(一):如何防止XSS攻擊?](https://my.oschina.net/meituantech/blog/2218539)
* [前端安全系列(二):如何防止CSRF攻擊?](https://my.oschina.net/meituantech/blog/2243958)
* [2018 PHP 應(yīng)用程序安全設(shè)計(jì)指北](https://zhuanlan.zhihu.com/p/33163426)
- 值得升級(jí)到5.1的18個(gè)理由
- 5.1.7版本新特性
- JSON字段類型在ORM中的使用
- 文件下載響應(yīng)對(duì)象
- 教你使用5.1的數(shù)組對(duì)象查詢
- 模型三大利器之一:搜索器
- 在ThinkPHP中使用Yaconf
- 掌握命令行的表格輸出
- 5.1.25查詢參數(shù)綁定的改進(jìn)
- ThinkPHP安全規(guī)范指引
- 巧用數(shù)據(jù)集的排序功能實(shí)現(xiàn)統(tǒng)計(jì)排序
- think-orm ——基于5.1的獨(dú)立ORM庫
- think-template——基于ThinkPHP的獨(dú)立模板引擎
- ThinkPHP5.1.26版本發(fā)布——修正版本,包含安全更新
- ThinkPHP5.0和3.2再發(fā)安全更新
- 官宣:ThinkPHP發(fā)布首個(gè)LTS版本
- 你真的了解Db類和模型的正確使用姿勢(shì)么?
- 如何更有效的記錄和管理日志
- 模型三大利器之二:修改器
- ThinkPHP5.1.28版本發(fā)布——修正上一版本問題,改進(jìn)關(guān)聯(lián)查詢
- 模型三大利器之三:獲取器
- API版本控制的幾種思路
- ThinkPHP5.2第一個(gè)Beta版本發(fā)布測(cè)試
- 讓你少犯錯(cuò)的數(shù)據(jù)查詢基本原則
- ThinkPHP發(fā)布5.1.29版本——常規(guī)更新
- 這15個(gè)好習(xí)慣讓你更容易升級(jí)到5.2
- 如何有效提高ThinkPHP的應(yīng)用性能
- 讓你提高開發(fā)效率的查詢技巧
- 模型關(guān)聯(lián)查詢不完全指南
- 5.2發(fā)布Beta2版本——統(tǒng)一和精簡(jiǎn)大量用法
- ThinkPHP發(fā)布5.1.30版本——支持微秒時(shí)間字段寫入
- ThinkPHP的數(shù)據(jù)緩存使用
- ThinkPHP5.2安裝及入口文件
- ThinkPHP榮獲2018 年度最受歡迎中國(guó)開源開發(fā)框架第1名
- 5.1路由使用心得技巧
- ThinkPHP5.*版本發(fā)布安全更新
- ThinkPHP項(xiàng)目及代碼規(guī)范指北
- 5.2版本的設(shè)計(jì)規(guī)范指導(dǎo)
- ThinkPHP5.1.32版本發(fā)布——圣誕快樂
- 利用Trait特性給模型增加樂觀鎖功能
- 5.2數(shù)據(jù)庫和模型的變化(摘要)
- ThinkPHP模板引擎實(shí)現(xiàn)和常見問題
- ThinkPHP5.0.24版本發(fā)布——安全更新
- 不忘初心,方得始終——ThinkPHP十三周年報(bào)告
- ThinkPHP5+相關(guān)資源匯總
- 異步社區(qū)ThinkPHP周年慶專享優(yōu)惠活動(dòng)
- 5.2路由的調(diào)整和改進(jìn)
- ThinkPHP發(fā)布5.1.33版本——包含安全更新
- ThinkPHP擴(kuò)展開發(fā)指南
- ThinkPHP發(fā)布5.2Beta3版本
- ThinkPHP發(fā)布5.1.34版本——喜迎新年
- ThinkPHP發(fā)布5.2RC1版本
- ThinkPHP發(fā)布5.1.35版本——常規(guī)更新
- 5.2配置類的調(diào)整
- 5.2時(shí)間查詢的改進(jìn)和優(yōu)化
- 5.2RC版本升級(jí)不完全指導(dǎo)(僅供學(xué)習(xí)參考)
- ThinkPHP5.2版本正式變更為6.0版本
- ThinkPHP百度云云虛擬主機(jī)專享免費(fèi)活動(dòng)
- 事件系統(tǒng)以及查詢事件、模型事件的使用
- ThinkPHP6.0RC2版本發(fā)布——架構(gòu)升級(jí)、精簡(jiǎn)核心
- ThinkPHP5.1.36LTS版本發(fā)布——常規(guī)更新
- 新版Session和Cookie設(shè)計(jì)變化
- ThinkPHP5.1.37版本發(fā)布——常規(guī)更新
- ThinkPHP6.0RC3版本發(fā)布——細(xì)節(jié)完善,體驗(yàn)優(yōu)化
- 6.0中間件使用詳解
- Composer各大廠商鏡像地址
- ThinkPHP6.0發(fā)布計(jì)劃公告
- 「ThinkPHP開發(fā)者周刊」招募志愿者
- ThinkPHP6.0日志變化
- ThinkPHP5.1.38版本發(fā)布——常規(guī)更新
- ThinkPHP6.0RC4版本發(fā)布——ORM獨(dú)立,日志多通道支持
- ThinkORM2.0開發(fā)指南上線
- ThinkPHP6.0RC5版本發(fā)布——多應(yīng)用模式獨(dú)立,中間件機(jī)制調(diào)整
- ThinkPHP6.0版本發(fā)布——程序員節(jié)福利
- ThinkPHP5.1.39LTS版本發(fā)布——常規(guī)更新
- ThinkPHP6.0.1版本發(fā)布——圣誕快樂!
- 回顧2019,展望2020!
- ThinkPHPV6.0.2版本發(fā)布——2020新春快樂!
- 周年福利系列:Swoole合作優(yōu)惠
- 億速云成為ThinkPHPV6.0獨(dú)家贊助發(fā)布商??
- 新冠疫情工具和限免資源專題(保持更新中)
- 周年福利系列:創(chuàng)宇信用認(rèn)證合作優(yōu)惠
- 周年福利系列:碼云企業(yè)版限時(shí)10%優(yōu)惠
- 周年福利系列:想天短說抵現(xiàn)優(yōu)惠
- think-swoole直播:從零開始掌握swoole開發(fā)
- 周年福利系列:B2C開源電商ShopXO授權(quán)8折優(yōu)惠
- 周年福利系列:LayuiAdmin 永久授權(quán)限時(shí)優(yōu)惠
- ThinkPHP資源導(dǎo)航站上線——構(gòu)建生態(tài) 服務(wù)未來
- ThinkPHP官方技術(shù)支持服務(wù)和應(yīng)用服務(wù)市場(chǎng)上線公測(cè)
- ThinkPHP市場(chǎng)精選——推廣基本要素
- ThinkPHP市場(chǎng)精選——客服聊天專題
- ThinkPHPV6.0.3版本發(fā)布——端午安康
- ThinkPHP開發(fā)者扶持計(jì)劃
- 6.0.3版本關(guān)鍵更新及升級(jí)事項(xiàng)
- 「ThinkPHP開發(fā)者周刊」改版重啟
- ThinkPHP市場(chǎng)精選——企業(yè)建站專題
- ThinkPHP 提供統(tǒng)一API接口服務(wù)
- ThinkPHP市場(chǎng)精選——直播電商專題
- ThinkAPI服務(wù)SDK發(fā)布
- 官方服務(wù)市場(chǎng)啟用獨(dú)立子域名
- ThinkPHP市場(chǎng)精選——刷臉支付專題
- ThinkAPI推出會(huì)員服務(wù)計(jì)劃
- ThinkPHPV6.0.4版本發(fā)布——中秋國(guó)慶雙節(jié)快樂
- ThinkPHPV5.1.40版本發(fā)布——常規(guī)更新
- 1024程序員節(jié)福利走一波
- ThinkPHP V6.0.5版本發(fā)布——兼容Composer2.0
- 知識(shí)圖譜應(yīng)用場(chǎng)景——源論技術(shù)沙龍
- ThinkPHP5.*版本改進(jìn)Composer2.0的兼容
- 官方市場(chǎng)雙十一精選推薦
- 技術(shù)人做產(chǎn)品有機(jī)會(huì)么(文末送課程)
- 本周秒殺——古德云售后獲客營(yíng)銷系統(tǒng)
- ThinkAPI服務(wù)更新——支持接口分組和PHP版本依賴調(diào)整
- PHP8新特性盤點(diǎn)
- PHP8新特性系列:構(gòu)造器屬性提升使用及注意事項(xiàng)
- ThinkPHP2021新年寄語
- ThinkPHP V6.0.6&V5.1.41版本發(fā)布——兼容PHP8.0
- PHP如何更優(yōu)雅地調(diào)用API接口
- ThinkPHP V6.0.7發(fā)布——修正版本
- ThinkAPI服務(wù)更新——IP白名單
- 最新版ThinkORM對(duì)于時(shí)間字段的調(diào)整
- ThinkAPI短信接口正式上線
- ThinkPHP V6.0.8版本發(fā)布——多環(huán)境變量配置支持
- 頂想云寫作服務(wù)開啟第一次公測(cè)
- ThinkSSL上線——官方SSL/TLS證書服務(wù)
- MDBootstrap國(guó)內(nèi)用戶福利——ThinkPHP官方市場(chǎng)首發(fā)
- ThinkPHP V6.0.9版本發(fā)布——常規(guī)更新
- ThinkORM功能盤點(diǎn)——虛擬模型
- 全面支持主流GIT版本庫——云寫作服務(wù)第二次公測(cè)
- 云寫作服務(wù)私有化部署方案之:版本庫私有化
- 看云雙十一活動(dòng)
- ThinkPHP V6.0.10LTS發(fā)布——兼容PHP8.1
- ThinkPHP V6.0.12發(fā)布——命令行兼容8.1
- 頂想云知識(shí)管理上線公測(cè)——構(gòu)建企業(yè)文檔中心和知識(shí)庫
- 頂想云上線——助力生態(tài)數(shù)字化建設(shè)
- 618活動(dòng)進(jìn)行中——官方市場(chǎng)迎來一波更新
- 頂想云知識(shí)管理正式上線——看云文檔啟動(dòng)遷移服務(wù)
- ThinkPHP V6.0.13發(fā)布——常規(guī)更新
- 頂想云網(wǎng)站助理服務(wù)上線——構(gòu)建產(chǎn)品支持服務(wù)
- ThinkPHP發(fā)布6.1.0&6.0.14版本——安全更新
- ThinkPHP新版社區(qū)上線試運(yùn)營(yíng)
- ThinkAPI上架人臉核身接口——助力網(wǎng)站實(shí)名認(rèn)證
- 辭舊迎新——舊版社區(qū)停止注冊(cè)及發(fā)帖
- ThinkPHP6.1.2版本發(fā)布——兼容PHP8.2
