2011-10-13 44 views
1

我正在尋找最安全的方式,不允許將我的Web表單(它使用PHP和MySQL)從非現場發佈到網站。我做了一些搜索,發現大多數人建議在表單中設置一個隱藏字段,並使用md5()散列值設置會話變量,並在表單提交時檢查它。但這似乎不是很安全,因爲md5()哈希值可以在隱藏值的表單源中看到。防止站外表單帖子?

這是我的想法,不允許關閉站點表單提交。數據庫調用的資源密集度更高,但看起來更安全,因爲代碼哈希不會發送到客戶端。

請看看它,看看你是否可以在這個安全措施戳任何漏洞,以防止非現場形式的職位。

// First time form loads 
if (!$_POST) { 

    session_start(); 

    $code_options = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9'); 
    for ($i=1; $i<=20; $i++) { 
     $code .= array_rand(array_flip($code_options), 1); 
    } 

    // Insert new record 
    $con = connect_to_db(); // connects to db 
    $sql = "INSERT INTO security_table (form_code) values('$code')"; 
    $result = run_query($sql, $con); // runs the query 

    $_SESSION['formcode'] = $code; 
    $_SESSION['formid'] = mysql_insert_id(); 

} 

// If form was posted to  
if ($_POST) { 

    session_start(); 

    $con = connect_to_db(); 
    $form_code = mysql_real_escape_string($_SESSION['formcode']); 
    $form_id = mysql_real_escape_string($_SESSION['formid']); 

    $sql = "SELECT form_code FROM security_table WHERE form_code = '$form_code' AND form_id = '$form_id '"; 
    $result = run_query($sql, $con); 

    if (mysql_num_rows($result) > 0) { 

     // Process the form 

     // If form processes successfully 
     $_SESSION['formcode'] = ""; 
     $_SESSION['formid'] = ""; 

    }else{ 

     // Error 

    } 

} 
+0

我試圖做到這一點沒有captcha – Mark

+1

什麼是讓腳本加載您的網頁兩次?你的php腳本會第一次爲它創建一個安全令牌,然後第二次接受這個會話... – bdares

+1

爲什麼所有的想法都是這樣的?爲什麼不把表單令牌放在會話中並檢查以確保它們匹配? –

回答

1

But that doesn't seem very secure because the md5() hash value can be seen in the source of the form in the hidden value.

沒關係。如果你對它進行了足夠的加密,令牌對任何人都是希臘的,因此不可能重新創建,除非你知道php腳本中的關鍵機制。既然你在每篇文章後重新生成令牌,看到它看起來不會對任何壞人有幫助。

你的表格安全保護方式基本上是「如果你有會話,你很好」。所以如果垃圾郵件機器訪問過你的頁面一次,安全層已經通過。爲什麼你有一個客戶端令牌的原因是,垃圾郵件發送者必須提供一些只能以實際形式獲得的內容。

例如,在stackoverflow上有很多關於安全表單的討論,例如看看Good Form Security - no CAPTCHA

2

而不是在您的應用程序中這樣做,您可以通過您的Web服務器配置控制對您的網站的訪問。如果您可以這樣做,那麼您可以很好地分離關注點 - 服務器處理請求,應用程序只處理邏輯。你使用Apache並且您已經閱讀到Apache的http.conf或本地的.htaccess /寫訪問

假設,你可以添加一條規則是這樣的:

<Limit GET POST> 
    order deny,allow 
    deny from all 
    allow from 199.166.210. 
    allow from .golden.net 
    allow from proxy.aol.com 
    allow from fish.wiretap.net 
</Limit> 

因此,否認每個人,除了爲您選擇允許的少數IP或網絡地址。

See the Apache docs爲基本細節。

+1

只有當您*可以*限制您的用戶IP時纔有效。 –