国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - 實(shí)例分析10個PHP常見安全問題

實(shí)例分析10個PHP常見安全問題

2021-08-08 20:38PHP教程網(wǎng) PHP教程

在本篇文章里小編給各位分享了關(guān)于10個PHP常見安全問題以及相關(guān)實(shí)例代碼,需要的朋友們學(xué)習(xí)參考下。

相對于其他幾種語言來說, php 在 web 建站方面有更大的優(yōu)勢,即使是新手,也能很容易搭建一個網(wǎng)站出來。但這種優(yōu)勢也容易帶來一些負(fù)面影響,因?yàn)楹芏嗟?php 教程沒有涉及到安全方面的知識。

本文分為幾部分,每部分會涵蓋不同的安全威脅和應(yīng)對策略。但是,這并不是說你做到這幾點(diǎn)以后,就一定能避免你的網(wǎng)站出現(xiàn)任何問題。如果你想提高你的網(wǎng)站安全性的話,你應(yīng)該繼續(xù)通過閱讀書籍或者文章,來研究如何提高你的網(wǎng)站安全性

出于演示需要,代碼可能不是很完美。日常開發(fā)過程中,很多代碼都包含在了框架跟各種庫里面。作為一個后臺開發(fā),你不僅要熟練基本的 curd,更要知道如何保護(hù)你的數(shù)據(jù)。

1. sql 注入

我賭一包辣條,你肯定會看到這里。 sql 注入是對您網(wǎng)站最大的威脅之一,如果您的數(shù)據(jù)庫受到別人的 sql 注入的攻擊的話,別人可以轉(zhuǎn)出你的數(shù)據(jù)庫,也許還會產(chǎn)生更嚴(yán)重的后果。

網(wǎng)站要從數(shù)據(jù)庫中獲取動態(tài)數(shù)據(jù),就必須執(zhí)行 sql 語句,舉例如下:

?
1
2
3
4
5
<?php
 
$username = $_get['username'];
 
$query = "select * from users where username = '$username'";

攻擊者控制通過 get 和 post 發(fā)送的查詢(或者例如 ua 的一些其他查詢)。一般情況下,你希望查詢戶名為「 peter 」的用戶產(chǎn)生的 sql 語句如下:

?
1
select * from users where username = 'peter'

 

但是,攻擊者發(fā)送了特定的用戶名參數(shù),例如:' or '1'='1

這就會導(dǎo)致 sql 語句變成這樣:

?
1
select * from users where username = 'peter' or '1' = '1'

這樣,他就能在不需要密碼的情況下導(dǎo)出你的整個用戶表的數(shù)據(jù)了。

那么,我們?nèi)绾畏乐惯@類事故的發(fā)生呢?主流的解決方法有兩種。轉(zhuǎn)義用戶輸入的數(shù)據(jù)或者使用封裝好的語句。轉(zhuǎn)義的方法是封裝好一個函數(shù),用來對用戶提交的數(shù)據(jù)進(jìn)行過濾,去掉有害的標(biāo)簽。但是,我不太推薦使用這個方法,因?yàn)楸容^容易忘記在每個地方都做此處理。

下面,我來介紹如何使用 pdo 執(zhí)行封裝好的語句( mysqi 也一樣):

?
1
2
3
4
5
6
7
$username = $_get['username'];
 
$query = $pdo->prepare('select * from users where username = :username');
 
$query->execute(['username' => $username]);
 
$data = $query->fetch();

動態(tài)數(shù)據(jù)的每個部分都以:做前綴。然后將所有參數(shù)作為數(shù)組傳遞給執(zhí)行函數(shù),看起來就像 pdo 為你轉(zhuǎn)義了有害數(shù)據(jù)一樣。

幾乎所有的數(shù)據(jù)庫驅(qū)動程序都支持封裝好的語句,沒有理由不使用它們!養(yǎng)成使用他們的習(xí)慣,以后就不會忘記了。

2. xss

xss 又叫 css (cross site script) ,跨站腳本攻擊。它指的是惡意攻擊者往 web 頁面里插入惡意 html 代碼,當(dāng)用戶瀏覽該頁之時,嵌入其中 web 里面的 html 代碼會被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的。

下面以一個搜索頁面為例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
 
<?php
 
$searchquery = $_get['q'];
 
/* some search magic here */
 
?>
 
<h1>you searched for: <?php echo $searchquery; ?></h1>
 
<p>we found: absolutely nothing because this is a demo</p>
 
</body>

因?yàn)槲覀儼延脩舻膬?nèi)容直接打印出來,不經(jīng)過任何過濾,非法用戶可以拼接 url:

?
1
search.php?q=%3cscript%3ealert(1)%3b%3c%2fscript%3e

php 渲染出來的內(nèi)容如下,可以看到 javascript 代碼會被直接執(zhí)行:

?
1
2
3
4
5
6
7
<body>
 
<h1>you searched for: <script>alert(1);</script></h1>
 
<p>we found: absolutely nothing because this is a demo</p>
 
</body>

問:js 代碼被執(zhí)行有什么大不了的?

javascript 可以:

偷走你用戶瀏覽器里的 cookie;

通過瀏覽器的記住密碼功能獲取到你的站點(diǎn)登錄賬號和密碼;

盜取用戶的機(jī)密信息;

你的用戶在站點(diǎn)上能做到的事情,有了 js 權(quán)限執(zhí)行權(quán)限就都能做,也就是說 a 用戶可以模擬成為任何用戶;

在你的網(wǎng)頁中嵌入惡意代碼;

...

問:如何防范此問題呢?

好消息是比較先進(jìn)的瀏覽器現(xiàn)在已經(jīng)具備了一些基礎(chǔ)的 xss 防范功能,不過請不要依賴與此。

正確的做法是堅(jiān)決不要相信用戶的任何輸入,并過濾掉輸入中的所有特殊字符。這樣就能消滅絕大部分的 xss 攻擊:

?
1
2
3
<?php
 
$searchquery = htmlentities($searchquery, ent_quotes);

或者你可以使用模板引擎 twig ,一般的模板引擎都會默認(rèn)為輸出加上 htmlentities 防范。

如果你保持了用戶的輸入內(nèi)容,在輸出時也要特別注意,在以下的例子中,我們允許用戶填寫自己的博客鏈接:

?
1
2
3
4
5
<body>
 
 <a href="<?php echo $homepageurl; ?>" rel="external nofollow" >visit users homepage</a>
 
</body>

以上代碼可能第一眼看不出來有問題,但是假設(shè)用戶填入以下內(nèi)容:

?
1
#" onclick="alert(1)

會被渲染為:

?
1
2
3
4
5
<body>
 
 <a href="#" rel="external nofollow" onclick="alert(1)">visit users homepage</a>
 
</body>

永遠(yuǎn)永遠(yuǎn)不要相信用戶輸入的數(shù)據(jù),或者,永遠(yuǎn)都假設(shè)用戶的內(nèi)容是有攻擊性的,態(tài)度端正了,然后小心地處理好每一次的用戶輸入和輸出。

另外設(shè)置 cookie 時,如果無需 js 讀取的話,請必須設(shè)置為 "http only"。這個設(shè)置可以令 javascript 無法讀取 php 端種的 cookie。

3. xsrf/csrf

csrf 是跨站請求偽造的縮寫,它是攻擊者通過一些技術(shù)手段欺騙用戶去訪問曾經(jīng)認(rèn)證過的網(wǎng)站并運(yùn)行一些操作。

雖然此處展示的例子是 get 請求,但只是相較于 post 更容易理解,并非防護(hù)手段,兩者都不是私密的 cookies 或者多步表單。

假如你有一個允許用戶刪除賬戶的頁面,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
<?php
 
//delete-account.php
 
$confirm = $_get['confirm'];
 
if($confirm === 'yes') {
 
 //goodbye
 
}

攻擊者可以在他的站點(diǎn)上構(gòu)建一個觸發(fā)這個 url 的表單(同樣適用于 post 的表單),或者將 url 加載為圖片誘惑用戶點(diǎn)擊:

?
1
<img src="https://example.com/delete-account.php?confirm=yes" />

用戶一旦觸發(fā),就會執(zhí)行刪除賬戶的指令,眨眼你的賬戶就消失了。

防御這樣的攻擊比防御 xss 與 sql 注入更復(fù)雜一些。

最常用的防御方法是生成一個 csrf 令牌加密安全字符串,一般稱其為 token,并將 token 存儲于 cookie 或者 session 中。

每次你在網(wǎng)頁構(gòu)造表單時,將 token 令牌放在表單中的隱藏字段,表單請求服務(wù)器以后會根據(jù)用戶的 cookie 或者 session 里的 token 令牌比對,校驗(yàn)成功才給予通過。

由于攻擊者無法知道 token 令牌的內(nèi)容(每個表單的 token 令牌都是隨機(jī)的),因此無法冒充用戶。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php /* 你嵌入表單的頁面 */ ?>
 
<form action="/delete-account.php" method="post">
 
 <input type="hidden" name="csrf" value="<?php echo $_session['csrf']; ?>">
 
 <input type="hidden" name="confirm" value="yes" />
 
 <input type="submit" value="delete my account" />
 
</form>
 
##
 
<?php
 
//delete-account.php
 
$confirm = $_post['confirm'];
 
$csrf = $_post['csrf'];
 
$knowngoodtoken = $_session['csrf'];
 
if($csrf !== $knowngoodtoken) {
 
 die('invalid request');
 
}
 
if($confirm === 'yes') {
 
 //goodbye
 
}

請注意,這是個非常簡單的示例,你可以加入更多的代碼。如果你使用的是像 symfony 這樣的 php 框架,那么自帶了 csrf 令牌的功能。

4. lfi

lfi (本地文件包含) 是一個用戶未經(jīng)驗(yàn)證從磁盤讀取文件的漏洞。

我經(jīng)常遇到編程不規(guī)范的路由代碼示例,它們不驗(yàn)證過濾用戶的輸入。我們用以下文件為例,將它要渲染的模板文件用 get 請求加載。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
 
<?php
 
 $page = $_get['page'];
 
 if(!$page) {
 
  $page = 'main.php';
 
 }
 
 include($page);
 
?>
 
</body>

由于 include 可以加載任何文件,不僅僅是 php,攻擊者可以將系統(tǒng)上的任何文件作為包含目標(biāo)傳遞。

index.php?page=../../etc/passwd

這將導(dǎo)致 /etc/passwd 文件被讀取并展示在瀏覽器上。

要防御此類攻擊,你必須仔細(xì)考慮允許用戶輸入的類型,并刪除可能有害的字符,如輸入字符中的 “.” “/” “\”。

如果你真的想使用像這樣的路由系統(tǒng)(我不建議以任何方式),你可以自動附加 php 擴(kuò)展,刪除任何非 [a-za-z0-9-_] 的字符,并指定從專用的模板文件夾中加載,以免被包含任何非模板文件。

我在不同的開發(fā)文檔中,多次看到造成此類漏洞的 php 代碼。從一開始就要有清晰的設(shè)計思路,允許所需要包含的文件類型,并刪除掉多余的內(nèi)容。你還可以構(gòu)造要讀取文件的絕對路徑,并驗(yàn)證文件是否存在來作為保護(hù),而不是任何位置都給予讀取。

5. 不充分的密碼哈希

大部分的 web 應(yīng)用需要保存用戶的認(rèn)證信息。如果密碼哈希做的足夠好,在你的網(wǎng)站被攻破時,即可保護(hù)用戶的密碼不被非法讀取。

首先,最不應(yīng)該做的事情,就是把用戶密碼明文儲存起來。大部分的用戶會在多個網(wǎng)站上使用同一個密碼,這是不可改變的事實(shí)。當(dāng)你的網(wǎng)站被攻破,意味著用戶的其他網(wǎng)站的賬號也被攻破了。

其次,你不應(yīng)該使用簡單的哈希算法,事實(shí)上所有沒有專門為密碼哈希優(yōu)化的算法都不應(yīng)使用。哈希算法如 md5 或者 sha 設(shè)計初衷就是執(zhí)行起來非常快。這不是你需要的,密碼哈希的終極目標(biāo)就是讓黑客花費(fèi)無窮盡的時間和精力都無法破解出來密碼。

另外一個比較重要的點(diǎn)是你應(yīng)該為密碼哈希加鹽(salt),加鹽處理避免了兩個同樣的密碼會產(chǎn)生同樣哈希的問題。

以下使用 md5 來做例子,所以請千萬不要使用 md5 來哈希你的密碼, md5 是不安全的。

假如我們的用戶 user1 和 user315 都有相同的密碼 ilovecats123,這個密碼雖然看起來是強(qiáng)密碼,有字母有數(shù)字,但是在數(shù)據(jù)庫里,兩個用戶的密碼哈希數(shù)據(jù)將會是相同的:5e2b4d823db9d044ecd5e084b6d33ea5 。

如果一個如果黑客拿下了你的網(wǎng)站,獲取到了這些哈希數(shù)據(jù),他將不需要去暴力破解用戶 user315 的密碼。我們要盡量讓他花大精力來破解你的密碼,所以我們對數(shù)據(jù)進(jìn)行加鹽處理:

?
1
2
3
4
5
6
7
8
9
<?php
 
//warning: !!這是一個很不安全的密碼哈希例子,請不要使用!!
 
$password = 'cat123';
 
$salt = random_bytes(20);
 
$hash = md5($password . $salt);

最后在保存你的唯一密碼哈希數(shù)據(jù)時,請不要忘記連 $salt 也已經(jīng)保存,否則你將無法驗(yàn)證用戶。

在當(dāng)下,最好的密碼哈希選項(xiàng)是 bcrypt,這是專門為哈希密碼而設(shè)計的哈希算法,同時這套哈希算法里還允許你配置一些參數(shù)來加大破解的難度。

新版的 php 中也自帶了安全的密碼哈希函數(shù) password_hash ,此函數(shù)已經(jīng)包含了加鹽處理。對應(yīng)的密碼驗(yàn)證函數(shù)為 password_verify 用來檢測密碼是否正確。password_verify 還可有效防止 時序攻擊.

以下是使用的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
 
//user signup
 
$password = $_post['password'];
 
$hashedpassword = password_hash($password, password_default);
 
//login
 
$password = $_post['password'];
 
$hash = '1234'; //load this value from your db
 
if(password_verify($password, $hash)) {
 
 echo 'password is valid!';
 
} else {
 
 echo 'invalid password.';
 
}

需要澄清的一點(diǎn)是:密碼哈希并不是密碼加密。哈希(hash)是將目標(biāo)文本轉(zhuǎn)換成具有相同長度的、不可逆的雜湊字符串(或叫做消息摘要),而加密(encrypt)是將目標(biāo)文本轉(zhuǎn)換成具有不同長度的、可逆的密文。顯然他們之間最大的區(qū)別是可逆性,在儲存密碼時,我們要的就是哈希這種不可逆的屬性。

6. 中間人攻擊

mitm (中間人) 攻擊不是針對服務(wù)器直接攻擊,而是針對用戶進(jìn)行,攻擊者作為中間人欺騙服務(wù)器他是用戶,欺騙用戶他是服務(wù)器,從而來攔截用戶與網(wǎng)站的流量,并從中注入惡意內(nèi)容或者讀取私密信息,通常發(fā)生在公共 wifi 網(wǎng)絡(luò)中,也有可能發(fā)生在其他流量通過的地方,例如 isp 運(yùn)營商。

對此的唯一防御是使用 https,使用 https 可以將你的連接加密,并且無法讀取或者篡改流量。你可以從 let's encrypt 獲取免費(fèi)的 ssl 證書,或從其他供應(yīng)商處購買,這里不詳細(xì)介紹如何正確配置 web 服務(wù)器,因?yàn)檫@與應(yīng)用程序安全性無關(guān),且在很大程度上取決于你的設(shè)置。

你還可以采取一些措施使 https 更安全,在 web 服務(wù)器配置加上 strict-transport-security 標(biāo)示頭,此頭部信息告訴瀏覽器,你的網(wǎng)站始終通過 https 訪問,如果未通過 https 將返回錯誤報告提示瀏覽器不應(yīng)顯示該頁面。

然而,這里有個明顯的問題,如果瀏覽器之前從未訪問過你的網(wǎng)站,則無法知道你使用此標(biāo)示頭,這時候就需要用到 hstspreload。

可以在此注冊你的網(wǎng)站: https://hstspreload.org/

你在此處提交的所有網(wǎng)站都將被標(biāo)記為僅 https,并硬編碼到 google chrome、firefox、opera、safari、ie11 和 edge 的源代碼中。

你還可以在 dns 配置中添加 certification authority authorization (caa) record ,可以僅允許一個證書頒發(fā)機(jī)構(gòu)(例如: let's encrypt)發(fā)布你的域名證書,這進(jìn)一步提高了用戶的安全性。

7. 命令注入

這可能是服務(wù)器遇到的最嚴(yán)重的攻擊,命令注入的目標(biāo)是欺騙服務(wù)器執(zhí)行任意 shell 命令

你如果使用 shell_exec 或是 exec 函數(shù)。讓我們做一個小例子,允許用戶簡單的從服務(wù)器 ping 不同的主機(jī)。

?
1
2
3
4
5
<?php
 
$targetip = $_get['ip'];
 
$output = shell_exec("ping -c 5 $targetip");

輸出將包括對目標(biāo)主機(jī) ping 5 次。除非采用 sh 命令執(zhí)行 shell 腳本,否則攻擊者可以執(zhí)行想要的任何操作。

?
1
ping.php?ip=8.8.8.8;ls -l /etc

shell 將執(zhí)行 ping 和由攻擊者拼接的第二個命令,這顯然是非常危險的。

感謝 php 提供了一個函數(shù)來轉(zhuǎn)義 shell 參數(shù)。

escapeshellarg 轉(zhuǎn)義用戶的輸入并將其封裝成單引號。

?
1
2
3
4
5
<?php
 
$targetip = escapeshellarg($_get['ip']);
 
$output = shell_exec("ping -c 5 $targetip");

現(xiàn)在你的命令應(yīng)該是相當(dāng)安全的,就個人而言,我仍然避免使用 php 調(diào)用外部命令,但這完全取決于你自己的喜好。

另外,我建議進(jìn)一步驗(yàn)證用戶輸入是否符合你期望的形式。

8. xxe

xxe (xml 外部實(shí)體) 是一種應(yīng)用程序使用配置不正確的 xml 解析器解析外部 xml 時,導(dǎo)致的本地文件包含攻擊,甚至可以遠(yuǎn)程代碼執(zhí)行。

xml 有一個鮮為人知的特性,它允許文檔作者將遠(yuǎn)程和本地文件作為實(shí)體包含在其 xml 文件中。

?
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="iso-8859-1"?>
 
 <!doctype foo [
 
  <!element foo any >
 
  <!entity passwd system "file:///etc/passwd" >]>
 
  <foo>&passwd;</foo>

就像這樣, /etc/passwd 文件內(nèi)容被轉(zhuǎn)儲到 xml 文件中。

如果你使用 libxml 可以調(diào)用 libxml_disable_entity_loader 來保護(hù)自己免受此類攻擊。使用前請仔細(xì)檢查 xml 庫的默認(rèn)配置,以確保配置成功。

9. 在生產(chǎn)環(huán)境中不正確的錯誤報告暴露敏感數(shù)據(jù)

如果你不小心,可能會在生產(chǎn)環(huán)境中因?yàn)椴徽_的錯誤報告泄露了敏感信息,例如:文件夾結(jié)構(gòu)、數(shù)據(jù)庫結(jié)構(gòu)、連接信息與用戶信息。

實(shí)例分析10個PHP常見安全問題

你是不希望用戶看到這個的吧?

一般根據(jù)你使用的框架或者 cms ,配置方法會有不同的變化。通常框架具有允許你將站點(diǎn)更改為某種生產(chǎn)環(huán)境的設(shè)置。這樣會將所有用戶可見的錯誤消息重定向到日志文件中,并向用戶顯示非描述性的 500 錯誤,同時允許你根據(jù)錯誤代碼檢查。

但是你應(yīng)該根據(jù)你的 php 環(huán)境設(shè)置: error_reporting 與 display_errors.

10. 登錄限制

像登錄這樣的敏感表單應(yīng)該有一個嚴(yán)格的速率限制,以防止暴力攻擊。保存每個用戶在過去幾分鐘內(nèi)失敗的登錄嘗試次數(shù),如果該速率超過你定義的閾值,則拒絕進(jìn)一步登錄嘗試,直到冷卻期結(jié)束。還可通過電子郵件通知用戶登錄失敗,以便他們知道自己的賬戶被成為目標(biāo)。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲中字幕 | 在线不卡a资源高清 | 亚洲欧美观看 | 国产精品久久久久久久久费观看 | 欧美第8页 | 国产亚洲一区二区精品 | 亚洲精品一区二区三区精华液 | 国产成人综合一区 | 精品国产青草久久久久福利 | 国产91色| 欧美一区二区三区视频在线观看 | 亚洲一区精品在线 | 中文字幕一区在线观看视频 | 免费一级片视频 | 97人人干| 成人精品久久 | 国产一区二区三区成人 | www.天天操| 国产精品亚洲一区二区三区在线 | 一区二区三区四区精品 | 精品一区二区三区免费 | 久久国内 | 青青草欧美 | 久久久91精品国产一区二区三区 | 欧美一级免费 | 韩国成人精品a∨在线观看 欧美精品综合 | 国产精品国产三级国产aⅴ原创 | 精品久久久久久久久久久久久久 | 欧美在线观看免费观看视频 | 秋霞成人 | 久久精彩视频 | 精品小视频 | 九九九久久国产免费 | 国产日韩欧美视频 | 亚洲 欧美 日韩 在线 | 国产精品18久久久久久久久 | 色人在线| 欧美三级电影在线播放 | 激情欧美日韩一区二区 | 天天操一操 | 午夜私人影院 |