2010-09-10 46 views
3

我正在使用get方法執行一些操作,如批准,markasspam,刪除,用於評論系統。我知道這是非常不安全的,但我無法幫助它。因爲使用$ _GET方法的原因是使用PHP_SELF在頁面本身內執行操作,FYI使用複選框使用post方法執行操作。

現在使它位安全,我想隨機數或生成散列或東西,然後進行比較,得到的ID和執行操作

我當前的代碼是有點像這樣。

<?php 
if($approve == 1) 
{ 
    ?> 
    <a href="<?php echo $_SERVER['PHP_SELF']."?approve=".$id; ?>">Unapprove</a> 
    <?php 
} else 
{ 
    ?> 
    <a href="<?php echo $_SERVER['PHP_SELF']."?unapprove=".$id; ?>">Approve</a> 
    <?php 
} 
?> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?spam=".$id; ?>">Spam</a> 
| <a class="edit-comments" href="edit-comments.php?id=<?php echo $id; ?>">Edit</a> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?delete=".$id; ?>">Delete</a> 

,我使用此代碼執行的操作..

if(isset($_GET['approve'])) { 
    $id = intval($_GET['approve']); 
    $query = "UPDATE comments SET approve = '0' WHERE id = '$id'"; 
    $result = mysql_query($query); 
} 

if(isset($_GET['unapprove'])) { 
    $id = intval($_GET['unapprove']); 
    $query = "UPDATE comments SET approve = '1' WHERE id = '$id'"; 
    $result = mysql_query($query); 
} 

if(isset($_GET['delete'])) { 
    $id = intval($_GET['delete']); 
    $query = "DELETE FROM comments WHERE id = '$id'"; 
    $result = mysql_query($query); 
} 

if(isset($_GET['spam'])) { 
    $id = intval($_GET['spam']); 
    $query = "UPDATE comments SET spam = '1' WHERE id = '$id'"; 
    $result = mysql_query($query); 
} 

而不是使用批准或拒絕或刪除或垃圾郵件,我想隨機或哈希說的話,並希望它儘可能長時間然後執行操作。

我該怎麼做?你對此有什麼看法?

編輯:請注意,只有 身份驗證的用戶即管理員將 能夠執行此操作。即使 雖然它通過身份驗證 系統我想添加更多的安全 即使是管理員。以避免實驗 或意外

該代碼不是確切的它只是讓你明白我想實現的樣本。

+4

請不要告訴我這是生產代碼。 – NullUserException 2010-09-10 05:43:45

+0

請說明一下,爲什麼不能使用POST在頁面內執行操作? – 2010-09-10 05:45:34

+0

@NullUserException不幸的是,你看我是一個初學者學習的東西。是的,我不能在這個項目中使用。我將不勝感激,並歡迎任何形式的反饋意見或建議:) – 2010-09-10 05:45:41

回答

5

無論您使用GET還是POST參數,在這裏並不重要 - 腳本需要什麼第一個是某種認證。 (做到這一點後,你可以進入安全細節哪裏得到略大於POST不太安全 - 詳見註釋)。

我說你有兩個選擇:

  • 保護整個腳本使用.htaccess - 腳本本身無需更改

  • 介紹PHP側用戶身份驗證並僅在已登錄的用戶發出請求時才執行操作。需要對腳本進行根本性更改,但最爲靈活。

回覆您的編輯:

事實證明你的腳本已受到保護。在這種情況下,我假設你對URL中增加的ID號碼,在瀏覽器中緩存等等感到不舒服。通常的解決方案是在創建時爲每個註釋生成一個隨機密鑰(除了增量ID)。該密鑰存儲在一個單獨的列中(不要忘記添加一個索引),並且可以與之匹配。

更進一步的做法是爲每個動作創建臨時哈希值,這是對多種外部攻擊的最終保護。

回覆您的有關使用一次性編輯散列:

我從來沒有實現在一個管理界面一次性哈希又那麼我有沒有這樣的經驗,但我想,一個非常簡單的實現會將動作哈希存儲在一個單獨的表中,其列hash,recordaction。只要您的工具列出了一些記錄並輸出「刪除/批准/取消批准」鏈接,它就會在散列表中爲每條評論生成三條記錄:一條用於刪除,一條用於批准,一條用於未批准。然後,「刪除/批准/取消批准」鏈接將取代記錄標識和命令,獲取正確的散列作爲唯一參數。

添加未使用的哈希超時功能(加刪除實際上使用的任何哈希),你就大功告成了。

+0

@皮卡僅供參考此操作僅由經過驗證的用戶執行。我想避免事故和實驗,這就是爲什麼我想使它更安全,是的,我將使用.htaccess,但現在我需要知道在這個腳本中有任何方法來產生哈希和比較使用$ _GET和執行操作。 – 2010-09-10 05:49:37

+0

@Ibrahim什麼阻止未經身份驗證的用戶輸入URL'page.php?delete = 1'? – NullUserException 2010-09-10 05:52:41

+0

當我們在管理界面上討論XSS攻擊時,POST更安全。 – 2010-09-10 05:52:47

1

你可以做到這樣,該$_GET是不是在你的代碼不安全的事情。不安全來自於你沒有檢查用戶是否是例如被授權刪除評論。

在你當前的代碼,任何人都可以在任何時候和,因爲他們經常要刪除任何東西。

如果您有保證if語句postet通過,如果enter good reason here,那麼也沒關係,你不執行的封裝代碼。

但你應該嘗試驗證,該參數的內容都是整數,而不是僅僅int_val'ing他們直接使用它們的數據庫。

您的編輯

你應該檢查你的參數確實是一個int。 intval("test")也將返回一個整數,大多是0

你可能會考慮爲正則表達式,以驗證只包含了一串數字:preg_match('/[0-9]+/', $_GET['id']);

如果是這樣,你可以執行的操作。

+0

對不起,我忘了提及我給了用戶認證只有管理員才能夠執行操作。 – 2010-09-10 05:50:35

+0

「'$ _GET'不是您的代碼中不安全的東西」-1 – quantumSoup 2010-09-10 06:19:27

+0

@quantumSoup此問題已經演變。當時有人問,有問題的腳本似乎完全無保護地訪問所有管理功能,在這種情況下,使用GET還是POST都無關緊要。在問題的背景完全改變時下調答案有點不公平 - 一個簡單的評論就足夠了。 – 2010-09-10 06:24:45

0

你不應該使用GET執行更改服務器數據的任何操作。決不。你只用它來獲取數據。

如果您不能使用操作按鈕的形式(因爲他們之外的另一種形式),你應該考慮這樣的設計:

  • 您可以使用AJAX來執行POST請求到服務器
  • 在javascript中 - 使用GET鏈接的禁用環境,如user.php?action = delete,它在單獨的頁面上顯示非常簡單的表單。表單中的標題詢問:「您確定要刪除用戶X嗎?」它有兩個按鈕:1)「是」 - 將POST請求提交給操作腳本,2)「否」 - 將用戶發回到他已經訪問過的頁面
+0

是否有任何JQuery插件? – 2010-09-10 06:01:19

+0

它在沒有任何插件的JQuery中。閱讀$ .post()或$ .ajax()中的文檔 – 2010-09-10 06:05:46