這次帶給大家PHP應該怎麼使用file_put_contents函數,PHP中使用file_put_contents函數的注意事項有哪些,以下是實戰案例,一起來看一下。
# 最近在EIS上遇到一道檔案上傳的題,發現過濾了<,這樣基本很多姿勢都無效了,想了很久沒做出來這題,賽後才知道是利用數組來繞過, 這裡分析了下原理,話不多說了,來一起看看詳細的介紹吧。
來看file_put_contents函數第二個參數data的官網定義:
data 要写入的数据。类型可以是 string,array 或者是 stream 资源(如上面所说的那样)。 如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。 参数 data 可以是数组(但不能为多维数组),这就相当于 file_put_contents($filename, join('', $array))。
可以看到,data參數可以是陣列, 會自動做join('',$array)
轉換為字串的
當函數存取檔案時,請遵循以下規則:
如果設定了FILE_USE_INCLUDE_PATH,那麼將檢查*filename* 副本的內建路徑
# 但我們字串過濾函數一般是用preg_match函數來過濾的,如:
if(preg_match('/\</',$data)){ die('hack'); }
我們知道,許多處理字串的函數如果傳入數組會出錯返回NULL, 如strcmp,strlen,md5等, 但preg_match 函數出錯返回false, 這裡我們可以透過var_dump(preg_match('/</' ,$data));
來驗證, 這樣的話,preg_match 的正規過濾就失效了
因此,猜測檔案上傳的程式碼是這樣寫的
<?php if(isset($_POST['content']) && isset($_POST['ext'])){ $data = $_POST['content']; $ext = $_POST['ext']; //var_dump(preg_match('/\</',$data)); if(preg_match('/\</',$data)){ die('hack'); } $filename = time(); file_put_contents($filename.$ext, $data); } ?></p> <p style="text-align: left;"> 於是我麼可以傳入<code>content[]=<?php phpinfo();?>&ext=php </code>這樣來繞過</p> <p style="text-align: left;"> <span style="color:#ff0000;"><strong>修復方法</strong></span></p> <p style="text-align: left;"> 修復方法是使用fwrite 函數來代替危險的file_put_contents函數,fwrite函數只能傳入字串,如果是數組會出錯返回false</p> <pre class="brush:php;toolbar:false"><?php if(isset($_POST['content']) && isset($_POST['ext'])){ $data = $_POST['content']; $ext = $_POST['ext']; //var_dump(preg_match('/\</',$data)); if(preg_match('/\</',$data)){ die('hack'); } $filename = time(); // file_put_contents($filename.$ext, $data); $f = fopen($filename.$ext); var_dump(fwrite($f,$data)); } ?>
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是PHP中該怎麼使用file_put_contents函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!