2024 年日本 PHP 研討會

使用者提交的資料

許多 PHP 程式的最大弱點並非來自語言本身,而只是程式碼撰寫時沒有考慮到安全性。因此,您應該隨時考慮一段程式碼的含義,以確定如果提交了非預期的變數,可能會造成什麼樣的損害。

範例 #1 危險的變數用法

<?php
// 刪除使用者家目錄中的檔案... 或者可能是
// 別人的檔案?
unlink ($evil_var);

// 記錄他們的存取... 或者可能是 /etc/passwd 的項目?
fwrite ($fp, $evil_var);

// 執行一些瑣碎的指令... 或者 rm -rf *?
system ($evil_var);
exec ($evil_var);

?>

您應該仔細檢查您的程式碼,以確保從網頁瀏覽器提交的任何變數都經過妥善檢查,並自問以下問題:

  • 這個指令碼只會影響預期的檔案嗎?
  • 異常或不良的資料會被處理嗎?
  • 這個指令碼會被以非預期的方式使用嗎?
  • 這個指令碼會與其他指令碼結合使用而產生負面影響嗎?
  • 所有交易都會被充分記錄嗎?

在撰寫指令碼時充分考慮這些問題,而不是事後才處理,可以避免在需要提高安全性時不得不重寫程式碼的窘境。從一開始就抱持這種思維模式,雖然不能保證系統的絕對安全,但可以幫助改善系統的安全性。

您也可以考慮關閉 register_globals、magic_quotes 或其他便利性設定,這些設定可能會讓您混淆特定變數的有效性、來源或值。在 error_reporting(E_ALL) 模式下使用 PHP 也可以幫助您在使用變數之前就收到警告,提醒您檢查或初始化變數(這樣可以防止異常資料被操作)。

新增註釋

使用者貢獻的註釋 2 則註釋

Uli Kusterer
19 年前
我想在這裡再次強調文件中的一點,那就是哪些資訊實際上來自使用者。許多人認為 Cookie 是安全的,因為它是 PHP 寫入的。但事實上,它儲存在使用者的電腦上,由使用者的瀏覽器傳輸,因此很容易被竄改。

因此,在此再次提及以下內容會很有幫助:

URL 中的 CGI 參數、HTTP POST 資料和 Cookie 變數都被視為「使用者資料」,因此需要驗證。只有當它們來自不可信的來源(例如剛才提到的那些)時,才需要驗證工作階段資料和 SQL 資料庫內容。

這並不是新的資訊,但我原本預期會在此標題下看到這些資訊,至少作為簡短的摘要加上實際文件的連結。
Livingstone@stonyhills[dot]com
16 年前
確保您的表單是從您的頁面提交的!也可以透過在查詢字串中新增 &token 並使用 $_GET 將其與工作階段資料(或您喜歡的任何陣列)進行比對來應用於網址,前提是該字串是隨機產生並儲存的。如果您不希望使用 $_SESSION,您可以建立自己的陣列來儲存產生的字串,例如您可以建立 $tokens = array(),然後在您的 easysecure 類別中將所有內容儲存在該陣列中!

<?php

class easysecure {

var
$curr_user;
var
$curr_permission;
var
$curr_task;
var
$validpermission;
var
$error;


function &
setVar( $name, $value=null ) {
if (!
is_null( $value )) {
$this->$name = $value;
}
return
$this->$name;
}

function
maketoken($formname, $id){

$token = md5(uniqid(rand(), true));

$_SESSION[$formname.$id] = $token;

return
$token;
}

function
checktoken($token, $formname, $id){
//print_r($_SESSION);
//echo ($token);
//如果沒有有效的 token,則返回無效
if(!$token){
$this->setVar('validpermission', 0);
$this->setVar('error', '找不到 token,偵測到安全橋接');
return
false;
}

//如果有有效的 token,檢查它是否有效
$key = $_SESSION[$formname.$id];
if(
$key !== $token ){
$this->setVar('validpermission', 0);
$this->setVar('error', '無效的 token');
return
false;
}

if(
$this->validpermission !==1){
echo
'沒有執行此腳本的權限';
return
false;
}else{
return
true;
}
}

}

?>

<?php $userid = *** //設定您想要的 ID ?>
<form name="newform" action="index.php" method="post">
<input type="text" name="potentialeveilfield" value="" size 30 />
<input type="hidden" name="token" value="<?php echo maketoken(newform, $userid); //$userid 在這裡可以是使用者個人資料 ID ?>" />
<input type="submit" />
</form>

現在處理表單時... 檢查您的 token 值

<?php

// 你知道的,表單名稱
if( !checktoken($_POST['token'], 'newform', $userid))
{
// 驗證失敗
exit(); // 或任何適合你的終止和通知方法。
// 你也可以用自己的方式設計這個類別,以獲得更精確的失敗資訊(來自變數的錯誤訊息)
}

// 你現在可以繼續進行輸入資料清理(驗證)

?>
To Top