Re: [請益] PHP接變數問題

看板PHP作者 (請勿忘記密碼)時間15年前 (2010/05/13 17:34), 編輯推噓2(204)
留言6則, 3人參與, 最新討論串5/5 (看更多)
※ 引述《tkdmaf (皮皮快跑)》之銘言: : ※ 引述《chan15 (ChaN)》之銘言: : : 接變數不外乎 : : $xxx = $_POST['xxx'] : : 如果變數有10幾個就要下10幾次 : : 請問各位朋友有比較便捷的寫法嗎? : 先前有人提及用foreach做$$key = $value : 也有提及$key的來源造成的變數異常的情況。 : 這會有安全性的問題(包含sql injetion之類的問題。) : 這麼一來就是得要對$key做處理還有將$value所傳入的字串做安全性的判斷。 : 比如說過濾不該存在的符號,將html字碼轉成普通字元……等等的方法。 : 改一改就長成這個樣子了。如果有更好的方法請指教: : 前一個欄位增加一個隱藏欄位表單。 : <input type="hidden" name="input_code" value="<?=md5("編碼值")?>" /> : $post = $_POST; //有人說不要將$_POST直接放入foreach處理,那就先用變數。 : 要做foreach前得先解編碼值: : if($post["input_code"] == md5("編碼值")){ : unset($post["input_code"]); //因為不需要把他也解進變數,就刪了他。 : foreach($post as $key => $value){ : $$key = desave($value); : } : }else{ : 看你要幹嘛! : } : function desave($value){ : 看你要怎麼處理安全性,將值放入$re_value,最後: : return $re_value; : } : 還有一種方式就是利用action取$get; : <form name="xxxxx" method="post" action="xxxx.php?input_code= : <?=md5("xxxxxx")?>"> : $post = $_POST; : if($_GET["input_code"] == md5("xxxxxx")){ : foreach($post as $key => $value){ : $$key = $desave($value); : } : }else{ : 看你要幹嘛! : } : 因為基本上md5是無法反解的。 : 所以除非對方能猜到你md5給的值不然就一定無法通過程式判斷。 : 這樣多少可稍微避免外來的侵害。 如果input_code的值不會改變的話,那麼這方式基本上沒有作用。 雖然我們無法得知php程式碼裡面的xxxxx其實是"ABCDE",但是這不重要,因為 沒必要知道。隨著表單送出去的是input_code=5ebedce9c92d556f4b06442a8668ddf1, 只要送出的input_code是這個(固定的)字串,在php裡面比對的時候就會通過, 因此只要檢視原始碼取得這個字串之後連同此字串送出其他內容,也都會通過。 這個方式要有作用,跟隨表單送出的input_code的值必須要會改變(而且無法預測)。 有兩種方式,一是隨著表單的其他欄位內容而改變,一是每次request都會變,也就是 兩次請求之間,即使其他欄位的值相同,input_code的值還是不同。 第一種方式適用於輸入的內容是可控制的,例如你開發了一個API讓特定合作廠商使用, 約定了input_code產生的方式,舉例而言是其他所有欄位的值依照特定順序互相連接, 然後再接上一個只有雙方知道的字串($salt),然後取md5。 $salt = "a very secret string"; $input_code = md5($a.$b.$c.$salt); 然後你這端接收到資料的時候,用同樣的方式將$a, $b, $c接上秘密字串取md5,然後 跟對方傳來的input_code進行比對,相同才通過檢查。如此,如果有人修改了$a, $b, $c 其中一個變數的值,但是$input_code沒有做相應的修改,檢查就不會通過。注意 $input_code的值是必須隨著$a, $b, $c的值的不同而跟著改變的。 但是這種方式不適用於一般讓使用者自行輸入內容的表單,因為不可能讓網友依照他 輸入的內容,自己產生然後輸入檢查碼。在這種狀況,應該在每個瀏覽區間(session), 甚至每個request,產生一個不同的檢查碼(此檢查碼的值跟使用者送出的資料內容無關), 將這檢查碼儲存在使用者看不到的地方(你可以放在$_SESSION裡面或者資料庫),然後 照原本的方式將檢查碼放在表單中讓使用者隨其他內容一起送出。在接收到資料時,把 送來的檢查碼拿去跟之前另行儲存的值相互比對。 但是話說回來,這做法其實不是用來防止「合法的使用者」送出「非法」的資料,而是 用來防止攻擊者「假裝是另一個合法使用者(受害者)」,在受害者不知情的狀況下, 以受害者的身份送出合法資料。這也就是前面有網友提到的CSRF攻擊。 如果攻擊者本身就是一個合法的使用者,而且他也是以自己的合法身份送出資料,那 這個方式並不能防止攻擊者在這個狀況下,送出非法的資料,而應該使用其他方式來 檢查資料的合法性。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.28.255.195

05/13 17:53, , 1F
推文就已經找出問題點了。你回應的太慢了喔!
05/13 17:53, 1F

05/13 17:57, , 2F
總之,欄位要驗證,資料要驗證。而不是光想要判斷資料來源
05/13 17:57, 2F

05/14 00:01, , 3F
不過我其實是看了這篇才知道前面在講什麼(逃)
05/14 00:01, 3F

05/14 00:02, , 4F
所以只要是合法的user還是可以透過script送資料吧!?
05/14 00:02, 4F

05/14 11:39, , 5F
應該是說 header 什麼都可以模仿.... XD
05/14 11:39, 5F

05/14 11:39, , 6F
前面有一篇推文討論得很詳細
05/14 11:39, 6F
文章代碼(AID): #1BwyU8zQ (PHP)
討論串 (同標題文章)
文章代碼(AID): #1BwyU8zQ (PHP)