搜尋
首頁後端開發PHP問題開發中php安全性考慮哪些

開發中php安全性考慮哪些

Sep 09, 2019 pm 06:00 PM
php安全性

開發中php安全性考慮哪些

開發中php安全性要考慮哪些?

1掌握整站的結構,避免洩漏網站敏感目錄

在寫程式碼之初,我也是像很多舊原始碼一樣,在根目錄下放上index.php、register.php、login.php,使用者點選註冊頁面,就跳到http://localhost/register.php。並沒有太多的結構的思想,像這樣的程式碼結構,最大的問題倒不是安全性問題,而是程式碼擴展與移植問題。

在寫程式碼的過程中,我們常要對程式碼進行修改,這時候如果程式碼沒有統一的一個入口點,我們可能要改很多地方。後來我讀了一點emlog的程式碼,發現網站真正的前端程式碼都在模板目錄裡,而根目錄下就只有入口點檔案和設定檔。這才頓悟,整個網站的架構進行了修改。

網站根目錄下放上一個入口點文件,讓它來對整個網站所有頁面進行管理,這個時候註冊頁面變成了http://localhost/?act=register ,任何頁面只是act的一個參數,得到這個參數後,再用一個switch來選擇要包含的檔案內容。在這個入口點檔案中,還可以包含一些常數的定義,例如網站的絕對路徑、網站的位址、資料庫使用者密碼。以後我們在腳本的編寫中,盡量使用絕對路徑而不要使用相對路徑(否則腳本如果改變位置,程式碼也要變),而這個絕對路徑就來自入口點檔案中的定義。

當然,在安全性上,一個入口點檔案也能隱藏後台位址。像這樣的位址http://localhost/?act=xxx不會暴露後台絕對路徑,甚至可以經常更改,不用改變太多程式碼。一個入口點檔案也可以驗證訪客的身份,例如一個網站後台,不是管理員就不允許查看任何頁面。在入口點文件中就可以驗證身份,如果沒有登錄,就輸出404頁。

有了入口點文件,我就把所有非入口點文件前面加上了這句話:

<?php 
if(!defined(&#39;WWW_ROOT&#39;))
 {
header("HTTP/1.1 404 Not Found");
 exit;
 } 
?>

WWW_ROOT是我在入口點中定義的一個常數,如果用戶是透過這個頁面的絕對路徑存取(http://localhost/register.php),我就輸出404錯誤;只有透過入口點存取(http://localhost/?act=register ),才能執行後面的程式碼。

2、使用預編譯語句,避免sql注入

注入是早前很大的一個問題,不過近些年因為大家比較重視這個問題,所以慢慢變得好了很多。

吳翰清在web白帽子裡說的很好,其實很多漏洞,像是sql注入或xss,都是將「資料」和「程式碼」沒有區分開。 「代碼」是程式設計師寫的內容,「數據」是使用者可以改變的內容。如果我們寫一個sql語句select * from admin where username='admin' password='xxxxx', admin和xxxxx就是數據,是使用者輸入的使用者名稱和密碼,但如果沒有任何處理,使用者輸入的就可能是“代碼”,例如'or ''=',這樣就造成了漏洞。 「代碼」是絕對不能讓使用者接觸的。

在php中,對於mysql資料庫有兩個模組,mysql和mysqli,mysqli的意思就是mysql improve。 mysql的改良版,這個模組中就含有「預編譯」這個概念。像上面那個sql語句,改一改:select * from admin where username='?' password='?',它就不是一個sql語句了,但是可以透過mysqli的預編譯功能先把他編譯成stmt對象,在後製用戶輸入帳號密碼後,用stmt->bind_param將用戶輸入的「資料」綁定到這兩個問號的位置。這樣,使用者輸入的內容就只能是“資料”,而不可能變成“代碼”。

這兩個問號限定了「資料」的位置,以及sql語句的結構。我們可以把我們所有的資料庫操作都封裝到一個類別中,所有sql語句的執行都會進行預編譯。這樣就完全避免了sql注入,這也是吳翰清最推薦的解決方案。

下面是使用mysqli的一些程式碼部分(所有的判斷函數運行成功或失敗的程式碼我都省略了,但不代表不重要):

<?php
//用户输入的数据
$name = &#39;admin&#39;;
$pass = &#39;123456&#39;;
//首先新建mysqli对象,构造函数参数中包含了数据库相关内容。
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
//设置sql语句默认编码
$this->mysqli->set_charset("utf8");
//创建一个使用通配符的sql语句
$sql = &#39;SELECT user_id FROM admin WHERE username=? AND password=?;&#39;;
//编译该语句,得到一个stmt对象.
$stmt = $conn->prepare($sql);
/********************之后的内容就能重复利用,不用再次编译*************************/
//用bind_param方法绑定数据
//大家可以看出来,因为我留了两个?,也就是要向其中绑定两个数据,所以第一个参数是绑定的数据的类型(s=string,i=integer),第二个以后的参数是要绑定的数据
$stmt->bind_param(&#39;ss&#39;, $name, $pass);
//调用bind_param方法绑定结果(如果只是检查该用户与密码是否存在,或只是一个DML语句的时候,不用绑定结果)
//这个结果就是我select到的字段,有几个就要绑定几个
$stmt->bind_result($user_id);
//执行该语句
$stmt->execute();
//得到结果
if($stmt->fetch()){
 echo &#39;登陆成功&#39;;
 //一定要注意释放结果资源,否则后面会出错
 $stmt->free_result();
 return $user_id; //返回刚才select到的内容
}else{echo &#39;登录失败&#39;;}
?>

3、預防XSS程式碼,如果不需要使用cookie就不使用

在我的網站中並沒有使用cookie,更因為我對權限限制的很死,所以對於xss來說危險性比較小。

對於xss的防禦,也是一個道理,處理好「程式碼」和「資料」的關係。當然,這裡的程式碼指的就是javascript程式碼或html程式碼。使用者能控制的內容,我們一定要使用htmlspecialchars等函數來處理使用者輸入的數據,並且在javascript中要謹慎把內容輸出到頁面中。

4、限制使用者權限,預防CSRF

现在脚本漏洞比较火的就是越权行为,很多重要操作使用GET方式执行,或使用POST方式执行而没有核实执行者是否知情。

CSRF很多同学可能比较陌生,其实举一个小例子就行了:

A、B都是某论坛用户,该论坛允许用户“赞”某篇文章,用户点“赞”其实是访问了这个页面:http://localhost/?act=support&articleid=12。这个时候,B如果把这个URL发送给A,A在不知情的情况下打开了它,等于说给articleid=12的文章赞了一次。

所以该论坛换了种方式,通过POST方式来赞某篇文章。

<form action="http://localhost/?act=support" method="POST">
 <input type="hidden" value="12" name="articleid">
 <input type="submit" value="赞">
</form>

可以看到一个隐藏的input框里含有该文章的ID,这样就不能通过一个URL让A点击了。但是B可以做一个“极具诱惑力”的页面,其中某个按钮就写成这样一个表单,来诱惑A点击。A一点击,依旧还是赞了这篇文章。

最后,该论坛只好把表单中增加了一个验证码。只有A输入验证码才能点赞。这样,彻底死了B的心。

但是,你见过哪个论坛点“赞”也要输入验证码?

所以吴翰清在白帽子里也推荐了最好的方式,就是在表单中加入一个随机字符串token(由php生成,并保存在SESSION中),如果用户提交的这个随机字符串和SESSION中保存的字符串一致,才能赞。

在B不知道A的随机字符串时,就不能越权操作了。

我在网站中也多次使用了TOKEN,不管是GET方式还是POST方式,通常就能抵御99%的CSRF估计了。

5、严格控制上传文件类型

上传漏洞是很致命的漏洞,只要存在任意文件上传漏洞,就能执行任意代码,拿到webshell。

我在上传这部分,写了一个php类,通过白名单验证,来控制用户上传恶意文件。在客户端,我通过javascript先验证了用户选择的文件的类型,但这只是善意地提醒用户,最终验证部分,还是在服务端。

白名单是必要的,你如果只允许上传图片,就设置成array('jpg','gif','png','bmp'),当用户上传来文件后,取它的文件名的后缀,用in_array验证是否在白名单中。

在上传文件数组中,会有一个MIME类型,告诉服务端上传的文件类型是什么,但是它是不可靠的,是可以被修改的。在很多存在上传漏洞的网站中,都是只验证了MIME类型,而没有取文件名的后缀验证,导致上传任意文件。

所以我们在类中完全可以忽略这个MIME类型,而只取文件名的后缀,如果在白名单中,才允许上传。

当然,服务器的解析漏洞也是很多上传漏洞的突破点,所以我们尽量把上传的文件重命名,以“日期时间+随机数+白名单中后缀”的方式对上传的文件进行重命名,避免因为解析漏洞而造成任意代码执行。

6、加密混淆javascript代码,提高攻击门槛

很多xss漏洞,都是黑客通过阅读javascript代码发现的,如果我们能把所有javascript代码混淆以及加密,让代码就算解密后也是混乱的(比如把所有变量名替换成其MD5 hash值),提高阅读的难度。

7、使用更高级的hash算法保存数据库中重要信息

这个硬盘容量大增的时期,很多人拥有很大的彩虹表,再加上类似于cmd5这样的网站的大行其道,单纯的md5已经等同于无物,所以我们迫切的需要更高级的hash算法,来保存我们数据库中的密码。

所以后来出现了加salt的md5,比如discuz的密码就是加了salt。其实salt就是一个密码的“附加值”,比如A的密码是123456,而我们设置的salt是abc,这样保存到数据库的可能就是md5('123456abc'),增加了破解的难度。

但是黑客只要得知了该用户的salt也能跑md5跑出来。因为现在的计算机的计算速度已经非常快了,一秒可以计算10亿次md5值,弱一点的密码分把钟就能跑出来。

所以后来密码学上改进了hash,引进了一个概念:密钥延伸。说简单点就是增加计算hash的难度(比如把密码用md5()函数循环计算1000次),故意减慢计算hash所用的时间,以前一秒可以计算10亿次,改进后1秒只能计算100万次,速度慢了1000倍,这样,所需的时间也就增加了1000倍。

那么对于我们,怎么使用一个安全的hash计算方法?大家可以翻阅emlog的源码,可以在include目录里面找到一个HashPaaword.php的文件,其实这就是个类,emlog用它来计算密码的hash。

這個類別有一個特點,每次計算出的hash值都不一樣,所以駭客不能透過彩虹表等方式破解密碼,只能用這個類別中一個checkpassword方法來傳回使用者輸入密碼的正確性。而函數又刻意增加了計算hash的時間,所以駭客很難破解他們拿到的hash值。

在最新的php5.5中,這個hash演算法成為了一個正式的函數,以後就能使用該函數來hash我們的密碼了

8、驗證碼安全性

驗證碼通常是由php腳本產生的隨機字串,透過GD庫的處理,製作成圖片。真正的驗證碼字串保存在SESSION中,然後把產生的圖片展示給使用者。使用者填寫了驗證碼提交後,在服務端上SESSION中的驗證碼進行比對。

由此想到了我之前犯過的一個錯誤。驗證碼比對完成之後,不管是正確還是錯誤,我都沒有清理SESSION。這樣產生了一個問題,一旦一個用戶第一次提交驗證碼成功,第二次以後不再訪問生成驗證碼的腳本,這時候SESSION中的驗證碼並沒有更新,也沒有刪除,導致驗證碼重複使用,起不到驗證的作用。

再說到了驗證碼被辨識的問題,wordpress包含emlog的程式我常常會藉鑑,但他們所使用的驗證碼我卻不敢恭維。很多垃圾評論都是驗證碼被機器辨識後產生的,所以我後來也使用了一個複雜一點的驗證碼,據說是w3c推薦使用的。

好了,我能想到的,也是在實際運用上用到的東西也就這麼多了。這也只是我自己寫程式碼中累積的一些對程式碼安全性的一個見解,如果大家還有更好的想法,可以和我交流。希望大家也能寫出更安全的程式碼。

以上內容僅供參考!

推薦影片教學:PHP影片教學

#

以上是開發中php安全性考慮哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:脚本之家。如有侵權,請聯絡admin@php.cn刪除
酸與基本數據庫:差異和何時使用。酸與基本數據庫:差異和何時使用。Mar 26, 2025 pm 04:19 PM

本文比較了酸和基本數據庫模型,詳細介紹了它們的特徵和適當的用例。酸優先確定數據完整性和一致性,適合財務和電子商務應用程序,而基礎則側重於可用性和

PHP安全文件上傳:防止與文件相關的漏洞。PHP安全文件上傳:防止與文件相關的漏洞。Mar 26, 2025 pm 04:18 PM

本文討論了確保PHP文件上傳的確保,以防止諸如代碼注入之類的漏洞。它專注於文件類型驗證,安全存儲和錯誤處理以增強應用程序安全性。

PHP輸入驗證:最佳實踐。PHP輸入驗證:最佳實踐。Mar 26, 2025 pm 04:17 PM

文章討論了PHP輸入驗證以增強安全性的最佳實踐,重點是使用內置功能,白名單方法和服務器端驗證等技術。

PHP API率限制:實施策略。PHP API率限制:實施策略。Mar 26, 2025 pm 04:16 PM

本文討論了在PHP中實施API速率限制的策略,包括諸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之類的庫。它還涵蓋監視,動態調整速率限制和手

php密碼哈希:password_hash和password_verify。php密碼哈希:password_hash和password_verify。Mar 26, 2025 pm 04:15 PM

本文討論了使用password_hash和pyspasswify在PHP中使用密碼的好處。主要論點是,這些功能通過自動鹽,強大的哈希算法和SECH來增強密碼保護

OWASP前10 php:描述並減輕常見漏洞。OWASP前10 php:描述並減輕常見漏洞。Mar 26, 2025 pm 04:13 PM

本文討論了OWASP在PHP和緩解策略中的十大漏洞。關鍵問題包括注射,驗證損壞和XSS,並提供用於監視和保護PHP應用程序的推薦工具。

PHP XSS預防:如何預防XSS。PHP XSS預防:如何預防XSS。Mar 26, 2025 pm 04:12 PM

本文討論了防止PHP中XSS攻擊的策略,專注於輸入消毒,輸出編碼以及使用安全增強的庫和框架。

PHP接口與抽像類:何時使用。PHP接口與抽像類:何時使用。Mar 26, 2025 pm 04:11 PM

本文討論了PHP中接口和抽像類的使用,重點是何時使用。界面定義了無實施的合同,適用於無關類和多重繼承。摘要類提供常見功能

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)