2015-04-02 55 views
-1

我必須通過一個jQuery插件的一些數據。我可以將它傳遞給一個使用GET請求獲取數據的URL,或者直接傳遞一個數組來消除一個服務器請求。有問題的數據是用戶提供的,在數據​​庫輸入時沒有消毒。用動態生成的JavaScript保護XSS

下面的腳本不顯示插件,但確實顯示了我可能會將數據傳遞給客戶端,以便它可以直接傳遞給插件。正如所看到的,動態生成的JS方法對於XSS是可疑的,但是,Ajax/JSON方法似乎不是。

對於這種情況,應該如何確保動態生成的JavaScript方法,並且Ajax/JSON方法存在風險?

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
     <title>XSS Testing</title> 
     <script src="getStuff.php?type=js" type="text/javascript"></script> 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script> 
     <script type="text/javascript"> 
      $(function(){ 
       console.log(stuff); 
       $.get("getStuff.php", function(data) { 
        console.log(data); 
       },'json'); 
      }); 
     </script> 
    </head> 

    <body> 
    </body> 
</html> 

getStuff.php

<?php 
$getFromDB=array(
    'Mary', 
    'x"];alert(\'xss2\');x=["x', 
    'John' 
); 
if(isset($_GET['type']) && $_GET['type']=='js') { 
    header('Content-Type: application/javascript;'); 
    $s='var stuff=['; 
    foreach($getFromDB as $row) { 
     $s.='"'.$row.'",'; 
    } 
    $s=substr($s, 0, -1).'];'; 
    echo($s); 
} 
else { 
    header('Content-Type: application/json;'); 
    echo(json_encode($getFromDB)); 
} 
?> 
+0

*「有問題的數據是用戶提供的,在數據​​庫輸入時沒有消毒。」*從外部世界進入系統的所有**數據需要在數據庫中記錄之前進行消毒/檢查,在任何合理的系統中。如果你不這樣做,你會在某個時候被有人登錄到你的系統的人咬住,但是有惡意的意圖。 – 2015-04-02 17:08:29

+0

@ T.J.Crowder真的嗎? http://stackoverflow.com/questions/11253532/html-xss-escape-on-input-vs-output http://lukeplant.me.uk/blog/posts/why-escape-on-input-is-a -bad-idea/ – user1032531 2015-04-02 17:30:11

+0

是的,這是措辭不佳,正如我們在別處商定的那樣。對不起'回合。我並不是說在輸入時輸入**,而是在輸入時檢查**,看它是否合理。當然,你在輸出中轉義,[如我在下面所述](http://stackoverflow.com/a/29418704/157247)。 – 2015-04-02 18:09:04

回答

0
如果您希望使用JSON的工作,爲什麼不首先確認那就是你正在使用什麼

$.get(...) 
.success(function(data) { 
    try { 
     JSON.parse(data) 
    } catch (e) { 
     console.error("this isn't actually JSON"); 
    } 
}) 

JSON不能包含的功能,也沒有函數調用,因此只要求瀏覽器,看它是否可以解析,應該足以讓他走「有東西在這裏,是不是真正的JSON數據」。

當然,您的PHP也是如此。 如果您需要特定的序列號,請勿建立字符串。在這種情況下,使用通常的PHP方式構建您的鍵/映射對象,然後使用內置的json_encode函數將其轉換爲合法的JSON序列化。

+0

感謝Mike,「特定序列化」是什麼意思?那麼用動態生成的JS方法來保護呢? – user1032531 2015-04-02 16:37:25

+0

像JSON,HTML,XML等任何「真正具有規範」的對象序列化。不要將它們構建爲字符串,將它們構建爲結構化對象,然後告訴它們序列化它們自己(如果可以的話),或者使用一個序列化API調用。即使繞過GET,也希望獲取該用戶數據,然後通過「JSON.parse」運行它,以便確定數據是否實際上是普通的JSON數據類型(對象,數組,字符串,數字 - 否函數,沒有函數調用) – 2015-04-02 16:40:42

+0

啊,你的意思是類似'exit('var stuff ='。json_encode($ getFromDB)。';');'?我測試了它,它不執行'alert'語句。這被認爲是安全的嗎? – user1032531 2015-04-02 16:48:08

0

這幾乎就像你設計你的例子容易受到黑客攻擊。你在「js」情況下沒有做任何事情來確保數據輸出正確的轉義,你只是在「json」情況下進行。

如果你要包括JavaScript文件是純粹的數據,這樣的:

<script src="getStuff.php?type=js"></script> 

然後getStuff.php需求,以確保它發回是正確轉義爲數據

<?php 
$getFromDB=array(
    'Mary', 
    'x"];alert(\'xss2\');x=["x', 
    'John' 
); 
if(isset($_GET['type']) && $_GET['type']=='js') { 
    header('Content-Type: application/javascript'); 
    echo('var data = '); 
    echo(json_encode($getFromDB)); 
    echo(';'); 
} 
else { 
    header('Content-Type: application/json'); 
    echo(json_encode($getFromDB)); 
} 
?> 

和繁榮:沒有警報。


旁註:你不應該有;Content-Type字符串的結束。我在上面刪除了它們。

+0

謝謝TJ。我同意這種方法的作品。直到看到Pomax的迴應,我才知道這件事。 – user1032531 2015-04-02 17:26:42