日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)

發(fā)布時(shí)間:2023/12/19 php 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 how to write a php framework,怎么一步步编写简单的PHP的Framework(十四) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天我說(shuō)一下怎么在框架中over掉這些安全問(wèn)題。

首先是SQL注入,這個(gè)如果你使用的是PDO,我覺(jué)得應(yīng)該沒(méi)什么問(wèn)題,如果你使用的還是mysql_*等API,那么你可以在框架中實(shí)現(xiàn)bindParameter或者在插入數(shù)據(jù)庫(kù)之前進(jìn)行字符串轉(zhuǎn)義。

前兩天把上一篇文章寫(xiě)完之后,Vian在后面留言說(shuō)到過(guò)SQL注入的一個(gè)解決方案,就是在在插入DB之前進(jìn)行'''.addslashes($id).''',它的意思就是首先進(jìn)行addslashes操作,之后再?gòu)?qiáng)制單引號(hào)包裹,這樣它就是一個(gè)不折不扣的字符串了,所以就注入不了,我覺(jué)得這個(gè)方法不錯(cuò),贊一個(gè)!!

由于SQL注入需要聯(lián)系到模型,XSS需要聯(lián)系到視圖,這兩塊兒我都沒(méi)有開(kāi)始講,所以我再后面再講怎么在框架中解決,當(dāng)然,如果我寫(xiě)到后面忘記了,你也可以提醒我一下。

上一次我講CSRF的時(shí)候,并沒(méi)有給出一個(gè)解決方案,今天我就給出這個(gè)解決方案。實(shí)際上解決的方法很簡(jiǎn)單,就是給它產(chǎn)生一個(gè)隨機(jī)數(shù),然后后端判定傳遞過(guò)來(lái)的數(shù)和正確的數(shù)是否吻合, 如果不吻合,就不執(zhí)行相應(yīng)的代碼了,這個(gè)隨機(jī)數(shù)我們稱為token。

為了簡(jiǎn)單,我們就將產(chǎn)生token和得到token的函數(shù)都寫(xiě)在控制器中,即Controller.php。

首先是生成隨機(jī)數(shù),最簡(jiǎn)單的方式是使用mt_rand()直接產(chǎn)生一個(gè)整數(shù),但在這兒我使用之前我在initphp這個(gè)框架中看到的解決csrf的方法,在這兒,也謝謝initphp作者的思路:

initphp的代碼是:

private function set_token() {

if (!$_COOKIE['init_token']) {

$str = substr(md5(time(). $this->get_useragent()), 5, 8);

setcookie("init_token", $str, NULL, '/');

$_COOKIE['init_token'] = $str;

}

} ? ? ? ?為了簡(jiǎn)單,我這兒就不使用userAgent了,initphp是將當(dāng)前時(shí)間戳和userAgent拼接成字符串之后再md5加密,取出第5到8位,我這邊的思路是將當(dāng)前時(shí)間戳進(jìn)行md5加密,然后從第0位開(kāi)始取,取得的字符串長(zhǎng)度是隨機(jī)產(chǎn)生的:

$token = substr(md5(time()),0,mt_rand(10,15)); ? ? ? 為了防止隨機(jī)數(shù)太大或太小,我設(shè)置mt_rand的取值范圍為10到15,也就是說(shuō)產(chǎn)生的token的位數(shù)為10到15位。

生成token之后其他的事情就好辦了,當(dāng)然,首先,也是設(shè)置token,我們沒(méi)有必要每次用戶請(qǐng)求的時(shí)候都產(chǎn)生一個(gè)隨機(jī)數(shù),所以我們將它存放在COOKIE中,框架載入的時(shí)候會(huì)判定是否有token,如果沒(méi)有則動(dòng)態(tài)生成一個(gè),當(dāng)然,生成的token會(huì)在一段時(shí)間之后過(guò)期失效,我這兒設(shè)置的時(shí)間為7天。

private function _setToken() {

if(empty($_COOKIE['_csrfToken'])) {

$token = substr(md5(time()),0,mt_rand(10,15));

$this->_token = $token;

setcookie('_csrfToken',$token,time() + 3600 * 24 * 7);

} else {

$this->_token = $_COOKIE['_csrfToken'];

}

}

由于生成token的過(guò)程是框架自動(dòng)完成的,所以沒(méi)有必要讓用戶看到此過(guò)程,所以將這個(gè)函數(shù)設(shè)為私有,然后在Controller類的構(gòu)造函數(shù)中調(diào)用即可。

剛才是生成token,那么怎么得到token呢,實(shí)際上得到token的方法就非常簡(jiǎn)單了,就是一個(gè)簡(jiǎn)單的getter:

protected function _getToken() {

return $this->_token;

} ? ? ? 現(xiàn)在我再演示一下在用戶編寫(xiě)的控制器的判定過(guò)程:

假設(shè)用戶請(qǐng)求的URL是:http://localhost/index.php?c=Index&a=test&token=rwerdfdsfsdfs

那么這個(gè)控制器的類的代碼如下:

class IndexController extends Controller {

public function test() {

$token = empty($_GET['token']) ? '' : $_GET['token'];

if($token === $this->_getToken()) {

//判定為正常

} else {

$this->_redirect(array(

//跳轉(zhuǎn)到某一個(gè)控制器的某一個(gè)Action

));

}

}

} ? ? ? ? 可能有人會(huì)問(wèn)URl上面的token值是怎么設(shè)置然后傳遞過(guò)來(lái)的呢?

我們可以想一下,假設(shè)上一個(gè)頁(yè)面是Index控制器的test2這個(gè)Action,那么我們可以在test2這個(gè)Action中首先使用$this->_getToken得到token值,然后在將數(shù)據(jù)傳遞到視圖,視圖中使用了之后,用戶點(diǎn)擊這個(gè)鏈接就可以將這個(gè)token值傳遞過(guò)來(lái)了。

我現(xiàn)在提一個(gè)問(wèn)題,假設(shè)用戶訪問(wèn)A頁(yè)面的時(shí)候得到token,這個(gè)token還有兩秒就過(guò)期了,這個(gè)用戶三秒之后點(diǎn)擊這個(gè)含有token的鏈接到達(dá)B頁(yè)面,B頁(yè)面由于COOKIE中的token已經(jīng)失效,所以重新產(chǎn)生一個(gè)token,然后再和傳遞的這個(gè)token比較,自然不匹配,然后就跳轉(zhuǎn)了,這還不是有問(wèn)題的呢,那么怎么解決呢?

由于還有一點(diǎn)時(shí)間,所以我提一下上傳文件漏洞吧,用戶上傳一個(gè)比如test.php頁(yè)面,如果用戶沒(méi)有做文件類型的判定,用戶上傳這個(gè)php文件之后,按照鏈接訪問(wèn)這個(gè)頁(yè)面,有可能這個(gè)頁(yè)面中有一些破壞性的代碼,整個(gè)網(wǎng)站就危險(xiǎn)了。

可能你已經(jīng)在程序中判定了,只允許后綴為jpg,png,gif這三種類型,那么我可以將這個(gè)jsp頁(yè)面后綴改成如jpg,上傳成功之后,如果網(wǎng)站存在某種漏洞能夠讓它修改文件后綴,那么你的網(wǎng)站又危險(xiǎn)了!!

還假設(shè)你的網(wǎng)站不允許修改文件后綴名,但是它在上傳的圖片后面加上一段JS腳本或者在上傳的文件名上面寫(xiě)一些腳本,這些都可能很危險(xiǎn)!!

所以,做好一個(gè)WEB應(yīng)用不是想象中那么容易的,剛才說(shuō)的是安全這一塊兒的內(nèi)容,實(shí)際上當(dāng)訪問(wèn)量大了之后,之前你覺(jué)得完全不是問(wèn)題的問(wèn)題可能就變成了一個(gè)大的問(wèn)題,除了這兩個(gè),還有其他N個(gè)問(wèn)題,所以,保持低調(diào),繼續(xù)學(xué)習(xí),繼續(xù)提高。。。。

上面一段話僅以自勉,其他人可以忽略。

大四了,還有一個(gè)月就要離開(kāi)天貓回學(xué)校做畢設(shè)了,我很想在畢業(yè)之前給我的網(wǎng)站做一個(gè)大幅度的修改,但是我現(xiàn)在不知道到底要做什么,不過(guò)肯定這個(gè)網(wǎng)站是針對(duì)程序員的,希望大家提一點(diǎn)意見(jiàn),我的個(gè)人網(wǎng)站http://www.qingyueit.com(比較挫,好久都沒(méi)有更新文章了,甚至連界面也是直接用了別人的主題)。

本次代碼點(diǎn)此下載

總結(jié)

以上是生活随笔為你收集整理的how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。