摘要:用戶提交過來的數據都是不可信的,所以,在查庫或入庫前需要對提交過來的數據進行過濾或字符的轉換處理,以防止注入或攻擊等問題。
一、防止SQL注入用戶提交過來的數據都是不可信的,所以,在查庫或入庫前需要對提交過來的數據進行過濾或字符的轉換處理,以防止SQL注入或xss攻擊等問題。
什么是SQL注入攻擊?
所謂SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
尋找SQL注入的方法:
1.通過get請求
2.通過post請求
3.其他http請求,如cookie
常見的SQL注入問題:
數據庫查詢參數的類型轉換處理
1. 轉義字符處理不當Talk is cheap,Show me the code.
多說無益,代碼亮出來吧!
// 構造動態SQL語句 ? $sql = "select * from tbl where field = "$_GET["input"]""; ? // 執行SQL語句 ? $res = mysql_query($sql);
測試:
在下邊的網址后邊加一個單引號,就會報數據庫錯誤
http://testphp.vulnweb.com/ar...
// 構造動態SQL語句 $sql = "select * from tbl where field = $_GET["user_id"]"; // 執行SQL語句 $res = mysql_query($sql);
Mysql內置了一個命令,可以讀取文件
Union all select load_file("/etc/passwd")--
select * from tbl where userid = 1 union all select load_file("etc/passwd")--
該命令會獲取數據庫管理員的密碼。
處理方法:
需要將客戶端傳過來的數據進行類型強制轉換,而后再查詢
$user_id = (int)$_GET["user_id"]; "select * from tbl where userid = {$user_id}";3. 查詢語句組織不當
user.php?table=user&
4. 錯誤處理不當即將站點的錯誤信息暴漏給用戶,這樣非常危險。
// 構造動態查詢語句 $getid?=?"select?*?from?tbl?where?userid?>?1"; // 執行SQL語句 $res = mysql_query($getid) or die("5. 多個提交處理不當".mysql_error()."");
// 參數是否是一個字符串 if(is_string($_GET["param"])){}數據入庫時將轉換單引號、雙引號、反斜杠為實體
在入庫的時候如果不過濾 " ""這樣的東西,這樣會使數據庫報錯,或者注入等問題。
先將字符串用htmlspecialchars()轉換為實體后存儲到數據庫,然后從數據庫讀出來時htmlspecialchars_decode()轉為HTML標簽。
htmlspecialchars() 函數把一些預定義的字符轉換為 HTML 實體。
函數原型:htmlspecialchars(string,quotestyle,character-set)
預定義的字符是:
& (和號) 成為 & ” (雙引號) 成為 " ‘ (單引號) 成為 ' < (小于) 成為 < > (大于) 成為 >
htmlspecialchars_decode() 函數把一些預定義的 HTML 實體轉換為字符(和htmlspecialchars相反)。
函數原型:htmlspecialchars_decode(string,quotestyle)
二、防止xss攻擊什么是xss攻擊?
和上邊的sql注入不同的是,xss攻擊是合法的字符串,如經過htmlspecialchars()方法實體化后,可以保存在數據庫中,但是,當訪問含有該字符串的內容頁面時,就會出現問題,如字符串里邊還有JavaScript,frame代碼,原來的頁面就會被篡改。
比如你寫個留言本,有人去留言寫
XSS概念
XSS又稱CSS,全稱Cross SiteScript(跨站腳本攻擊), XSS攻擊類似于SQL注入攻擊,是Web程序中常見的漏洞,XSS屬于被動式且用于客戶端的攻擊方式,所以容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML代碼,當用戶瀏覽該網站時,這段HTML代碼會自動執行,從而達到攻擊的目的。如,盜取用戶Cookie信息、破壞頁面結構、重定向到其它網站等。
理論上,只要存在能提供輸入的表單并且沒做安全過濾或過濾不徹底,都有可能存在XSS漏洞。
下面是一些最簡單并且比較常見的惡意字符XSS輸入:
1.XSS 輸入通常包含 JavaScript 腳本,如彈出惡意警告框:
2.XSS 輸入也可能是 HTML 代碼段,譬如:
(1).網頁不停地刷新
(2).嵌入其它網站的鏈接
除了通過正常途徑輸入XSS攻擊字符外,還可以繞過JavaScript校驗,通過修改請求達到XSS攻擊的目的,如下圖:
了解到XSS攻擊的原理和危害后,其實要預防也不難,下面提供一個簡單的PHP防止XSS攻擊的函數:
除了通過正常途徑輸入XSS攻擊字符外,還可以繞過JavaScript校驗,通過修改請求達到XSS攻擊的目的。
了解到XSS攻擊的原理和危害后,其實要預防也不難,下面提供一個簡單的PHP防止XSS攻擊的函數:
"; clean_xss($str); //如果你把這個注釋掉,你就知道xss攻擊的厲害了 echo $str; ?>
避免被XSS:
1.給用戶開放的編輯器盡量過濾掉危險的代碼
如果是html編輯器,一般的做法是保留大部分代碼,過濾部分可能存在危險的代碼,如script, iframe等等
預處理語句對于防止 MySQL 注入是非常有用的。
預處理語句及綁定參數
預處理語句用于執行多個相同的 SQL 語句,并且執行效率更高。
預處理語句的工作原理如下:
預處理:創建 SQL 語句模板并發送到數據庫。預留的值使用參數 "?" 標記 。例如:
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
數據庫解析,編譯,對SQL語句模板執行查詢優化,并存儲結果不輸出。
執行:最后,將應用綁定的值傳遞給參數("?" 標記),數據庫執行語句。應用可以多次執行語句,如果參數的值不一樣。
相比于直接執行SQL語句,預處理語句有兩個主要優點:
預處理語句大大減少了分析時間,只做了一次查詢(雖然語句多次執行)。
綁定參數減少了服務器帶寬,你只需要發送查詢的參數,而不是整個語句。
預處理語句針對SQL注入是非常有用的,因為參數值發送后使用不同的協議,保證了數據的合法性。
PDO預處理機制
可以使用多種方式實現預處理:指的是在綁定數據進行執行的時候,可以有多種方式。
預處理語句中為變量
使用數組指定預處理變量
1、準備預處理語句(發送給服務器,讓服務器準備預處理語句) PDOStatement PDO::prepare:類似exec將一條SQL語句發送給Mysql服務器 //PDO::prepare 能夠自動的準備一個預處理語句,用戶需要準備的只是預處理所要執行的語句 //需求:往學生表里循環插入10條記錄 //PDO的預處理能夠自動的將對應的以:開始的變量給記錄下來,實際發送給服務器的是“?” $sql1 = "insert into pro_student values(null,:s_name,:s_num,:s_gender,:s_age,:c_id)"; 2、發送預處理語句 $stmt = $pdo->prepare($sql1); 3、給預處理綁定數據 $arr = array( ":s_name" => "房祖名", ":s_num" => "itcast0013", ":s_gender" => 0, ":s_age" => 28, ":c_id" => 2 ); 4、執行預處理:將要操作的數據發送給預處理語句,再執行預處理語句 PDOStatement::execute([$array]):數組用來傳遞對應的參數 $stmt->execute($arr); //執行預處理
PDO預處理原理
PDO的預防sql注入的機制也是類似于使用mysql_real_escape_string 進行轉義,PDO 有兩種轉義的機制,第一種是本地轉義,這種轉義的方式是使用單字節字符集(PHP < 5.3.6)來轉義的(單字節與多字節),來對輸入進行轉義,但是這種轉義方式有一些隱患。隱患主要是:在PHP版本小于5.3.6的時候,本地轉義只能轉換單字節的字符集,大于 5.3.6 的版本會根據 PDO 連接中指定的 charset 來轉義。
第二種方式是PDO,首先將 sql 語句模板發送給Mysql Server,隨后將綁定的字符變量再發送給Mysql server,這里的轉義是在Mysql Server做的,它是根據你在連接PDO的時候,在charset里指定的編碼格式來轉換的。這樣的轉義方式更健全,同時還可以在又多次重復查詢的業務場景下,通過復用模板,來提高程序的性能。如果要設置Mysql Server 來轉義的話,就要首先執行:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
原始鏈接方法:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->exec("set names utf8"); $title = "我們的愛情"; $content = "你是/誰啊,大幾都"老梁"做做&>women沒" . " 測試打印號"我是單引號"哈哈"; $user_id = 174742; $add_time = date("Y-m-d H:i:s"); $insert_sql = "insert into post_tbl (title, content, user_id, add_time) values (:x_title, :x_content, :x_user_id, :x_add_time)"; $stmt = $dbh->prepare($insert_sql); $stmt->execute(array("x_title"=>$title,":x_content"=> $content, ":x_user_id" => $user_id, ":x_add_time" => $add_time)); echo $dbh->lastinsertid();
可見這次PHP是將SQL模板和變量是分兩次發送給MySQL的,由MySQL完成變量的轉義處理,既然變量和SQL模板是分兩次發送的,那么就不存在SQL注入的問題了,但需要在DSN中指定charset屬性,如:
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8", "root");
示例:
/** * 插入用戶的Token */ function photo_save_token($user_id, $token) { // 參數判斷 $user_id = (int)$user_id; $token = trim($token); if(empty($token) || empty($user_id)) return false; $sql = "replace into token_db.app_token_tbl ( user_id, token, t_date, last_open_time) values ( :x_user_id, :x_token, :x_t_date, :x_last_open_time)"; sqlSetParam($sql,"x_user_id",$user_id); sqlSetParam($sql,"x_token",$token); sqlSetParam($sql,"x_t_date",date("Y-m-d H:i:s")); sqlSetParam($sql,"x_last_open_time", time()); return mysql_query($sql); }
總結: 當調用 prepare() 時,查詢語句已經發送給了數據庫服務器,此時只有占位符 ? 發送過去,沒有用戶提交的數據;當調用到 execute()時,用戶提交過來的值才會傳送給數據庫,他們是分開傳送的,兩者獨立的,SQL攻擊者沒有一點機會。
相關文章:
php-PDO預處理
PHP MySQL 預處理語句
pdo如何防止 sql注入
①、關于sql注入可以使用htmlspecialchars()或addslashes()方法,如果連接mysql,可以用mysql_real_escape_string(),還有在php.ini中配置magic_quotes_gpc開啟自動轉義的擴展。
PHP環境打開自動轉義,PHP.INI中查看
當magic_quotes_gpc=on 時將自動進行轉義(默認是on),可在程序中用get_magic_quotes_gpc()檢查他的狀態
程序為:
if (get_magic_quotes_gpc()==1){ $name=stripcslashes($_POST["name"]); }else{ $name=$_POST["name"]; }
②、關于xss攻擊可以寫一個去處script,frame等代碼的方法:
直接用這個函數editor_safe_replace代替htmlspecialchars,既保證安全又能用大部分html代碼
function editor_safe_replace($content) { $content = trim($content); $tags = array( """is", ""]*?>.*?"is", """is", ""]*?>.*?"is", ""]*?>.*? "is", ""]*?>"is", ""]*?>"is", ); // 1.先過濾掉含有xss攻擊的代碼 $content = preg_replace($tags, "", $content); // strip_tags過濾掉全部HTML標簽(script,iframe,head,a 等標簽)和上邊的正則方法類似 // $content = strip_tags($content); // 2.入庫時,防止sql注入,轉為HTML實體保存在數據庫,單雙引號都轉 $content = htmlspecialchars($content, ENT_QUOTES); // 3.替換反斜杠 $content = preg_replace("http://", "\", $content); // 4.替換斜杠 $content = preg_replace("http:///", "/", $content); return $content; }
所以,對于PHP的安全而言,一定要對用戶提交的數據進行過濾校驗處理,即先防止SQL注入,后再進行XSS過濾,這兩個都需要兩手一起抓,且兩手都要硬,否則,你的網站將會存在很大的安全風險。
相關文章:
PHP 安全三板斧:過濾、驗證和轉義之轉義篇 & Blade模板引擎避免XSS攻擊原理探究
8個很有用的PHP安全函數,你知道幾個?
HTML 字符實體對照表
PDO使用方法簡介
利用SQL注入漏洞登錄后臺
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21855.html
摘要:開發擴展是用語言實現的,流行的很大一個原因也是因為有大量開發者通過擴展實現大量通用的功能供廣大社區開發者使用。擴展化的優勢產品安全性和私密性好系統性能高擴展化的劣勢開發效率低的優勢之一就是開發效率高,需要選擇系統合適的模塊進行擴展化。 php是解釋性語言,不需要編譯。對于用php寫的產品,如果需要直接源碼安裝到客戶的運行環境中,則存在很大的安全隱患。客戶甚至可以把你的產品直接做二次部署...
摘要:從最大的同性社交平臺獲取數據好了,言歸正傳,回到題目。烏云密布的爬蟲百度網盤這件事,是我不想看到的,這類安全問題的一個共同特點用戶自身確實存在問題。 本文作者:夏之冰雪,i春秋簽約作家 《我在百度網盤上看到上萬條車主個人信息,企業、政府高官信息、各種數據庫和無窮無盡的盜版》,一時間,這篇文章就火了,火爆程度另百度猝不及防。 其實呢,這事真不能全怪百度,畢竟用戶分享出去了。之所以引起這么...
摘要:常見的就是,它是一個完整的目錄。的特點是簡單,使用一個中央版本庫。當初公司的日均均超過,所以采用的是方案雙機熱備集群優化架構圖上是兩主兩從。 前言 五年前,我在CNBLOG寫的一篇文章,《php+mysql下,對網站架構方面的一些認識(以我維護的站點為例)》,當然,整套架構不是做的,而是配合當初的運維部門,共同完成。那個時候我從入行PHP兩年,對所謂的架構也是懵懂。只覺得很深奧,很高大...
摘要:常見的就是,它是一個完整的目錄。的特點是簡單,使用一個中央版本庫。當初公司的日均均超過,所以采用的是方案雙機熱備集群優化架構圖上是兩主兩從。 前言 五年前,我在CNBLOG寫的一篇文章,《php+mysql下,對網站架構方面的一些認識(以我維護的站點為例)》,當然,整套架構不是做的,而是配合當初的運維部門,共同完成。那個時候我從入行PHP兩年,對所謂的架構也是懵懂。只覺得很深奧,很高大...
閱讀 3222·2021-09-09 11:39
閱讀 1228·2021-09-09 09:33
閱讀 1126·2019-08-30 15:43
閱讀 545·2019-08-29 14:08
閱讀 1732·2019-08-26 13:49
閱讀 2375·2019-08-26 10:09
閱讀 1544·2019-08-23 17:13
閱讀 2282·2019-08-23 12:57