2011-06-14 192 views
4

如何檢測我的php腳本是否被另一個域名調用,而另一個域名是否正在非法使用我的腳本?有沒有辦法來防止呢?如何防止跨域的Ajax請求?

UPDATE

我發現SO this的問題,但它仍然沒有安全,就可以欺騙。

+0

使用訪問令牌可能是您最好的選擇。推薦人不可靠,易於僞造。 – 2011-06-14 18:02:55

+0

哦,但我不知道如何實現訪問令牌。您能否通過答案來展示一些信息? – 2011-06-14 18:05:27

+2

設置服務的某種授權用戶的cookie。在每次調用ajax處理腳本時檢查這個cookie。或者在您的腳本中嵌入令牌,以便將其作爲參數從您自己的合法代碼發送到每個AJAX調用中。基本上有SOMETHING伴隨請求從一個帶寬竊賊中識別合法用戶。如果他們變得聰明並複製令牌,那麼只能通過登錄機制或其他每個用戶的身份識別系統提供令牌。 – 2011-06-14 18:08:13

回答

3

沒有任何絕對萬無一失的方法來防止這種情況,因爲任何標題信息都可能被欺騙。基於會話的令牌是另一種可能的解決方案,但在這種情況下,您的JavaScript可公開訪問,所以任何想花費一點時間的人都可以確定令牌系統的工作方式並找出解決方法。

方法的組合將給你最廣泛的保護。您可以查找標題,使用和.htaccess文件,並使用令牌。這種全面的方法使得濫用Web服務器變得更加困難 - 大多數濫用來自於人們試圖找到一個容易被利用的漏洞。要記住的重要一點是,你不能自滿,因爲你已經部署了「最好」的保護,或者因爲你有太多的保護層,看起來不可能破解。如果有人真的需要它,並有時間,他們會找到一個方法。這些類型的預防措施實際上只是阻止懶惰,好奇和無聊的惡意行爲。目標攻擊是一個完全獨立的安全類別,通常更多地集中在服務器級別的安全問題上。

樣本htaccess。這不會是什麼你把你的根,而是在,你有腳本,不應該從地址欄稱爲子文件夾:

RewriteEngine on 
RewriteCond %{HTTP_REFERER} !^$ 
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?_YOUR_DOMAIN_NAME_HERE.com [NC] 
RewriteRule \.(php)$ - [NC,F,L] 

看看這篇文章的信息有關使用令牌系統:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet

1

您可以手動拒絕其Origin標頭與您的域名不匹配的每個請求。但是,並非所有瀏覽器都會發送Origin標題。在這些情況下,您可以回退到Referer [sic]標頭,解析並找出域名,並如上所述進行比較。

一些JavaScript框架還爲AJAX請求設置了一個X-Requested-With標頭。

這應該會拒絕很大一部分用戶(我估計> 95%)。請注意,由於Same-Origin Policy,向您的域發送AJAX請求的人唯一得到的就是時間信息。

+0

檢查更新。順便說一句,在你的答案中,如果所有瀏覽器都不發送Origin頭文件,那麼還有什麼可以做的? – 2011-06-14 18:04:00

+0

'發送AJAX請求到你的域名的人唯一得到的就是時間信息。「你是什麼意思? – 2011-06-14 18:07:06

+0

@編碼怪胎更新了詳細的解釋和'X-Requested-With'。但是,我不知道爲什麼有人會發送隨機的AJAX請求。 – phihag 2011-06-14 18:07:16

-2

這不是一個可以解決的問題。如果你創建一個網站,按照定義,它是公開可用的。
如果你想要你的數據是私人的,你需要要求某種登錄。

創建一個系統是不可能的,這個系統對用戶開放,但對於沒有登錄/惱人的驗證碼的腳本來說是不可能的。

-3

我知道這是一箇舊帖子,但目前一個「萬無一失」的方法來避免這一點,它的地獄般簡單... 首先在頁面,Ajax調用會進行:

在AJAX腳本

var formData = new FormData(); 
formData.append("token","<?php echo $token;?>"); 
     $.ajax({ 
      url: 'yourfile.php', 
      type: 'POST', 
      xhr: function() { 
       var myXhr = $.ajaxSettings.xhr(); 
       return myXhr; 
      }, 
      success:function(data) { 
       alert(data); 
      }, 
      data: formData, 
      cache: false, 
      contentType: false, 
      processData: false 
     }); 

終於在PHP頁面將被稱爲

<?php 
$token = sha1(rand(1000,9999)); 
$_SESSION['token'] = $token; 
?> 

然後:

<?php 
$token = $_POST['token']; 
if($token === $_SESSION['token'] && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') 
{ 
    //Perform your stuff here... 
} 
?>  
+1

這裏的問題是rand()並不是真正的隨機。這是一個基於時間的僞隨機數。雖然這仍然是首選方法,但絕不是「萬無一失」。 – 2015-05-07 21:31:20

+0

,但它沒有影響,因爲字符串存儲在一個會話,所以只關聯到這臺計算機;)謝謝反正通知 – user3491125 2015-06-03 15:03:17

+0

我認爲[會話欺騙]的答案(http://stackoverflow.com/questions/17413480/session -spoofing-php)在某些方面可以幫助解決這個問題,但不確定這是否是OP尋找的理想解決方案。 – aug 2016-01-12 00:15:58

0

有點像user3491125提出的,你可以在調用的頁面中設置一個$ _SESSION,並在頁面Ajax中檢查它是否被設置爲$ _SESSION ['user']。