2012-03-10 98 views
0

我想要得到正則表達式告訴我路徑是否包含./../。這是爲了檢查用戶沒有超出他們的區域。如果輸入包含正斜槓前的一段時間,則不會被接受。正則表達式找到「../」或「./」

E.g.

/user/selected/path/ - Ok 
./user/selected/path/ - Failed 
../user/selected/path/ - Failed 

正斜槓將DIRECTORY_SEPERATOR被替換,以便適用於UNIX和Windows路徑。

+2

你爲什麼不[刪除的點段正常(http://tools.ietf.org/html/rfc3986#section-5.2.4)? – Gumbo 2012-03-10 17:44:34

+0

如果找到'。/'或'../',你想怎麼做?從路徑中刪除這些段?返回'false'或其他東西? – 2012-03-10 17:44:55

+0

@Gumbo因爲通常你會遇到......../......./........ /。/ ../ – arbme 2012-03-10 17:47:20

回答

0

使用此

if (preg_match('#\.(\.)?/#', $path, $match)) echo "Error"; 

如果您需要檢查../或./只在開始的時候,你必須使用此

if (preg_match('#^\.(\.)?/#', $path, $match)) echo "Error"; 
+0

請注意,第一個正則表達式會匹配'/ foo。/ bar',並且兩者都不會匹配裸「..」或「。」。另外,捕獲組是不必要的:'#\。\。?/#''。 – pilcrow 2012-03-10 19:11:36

0

我倒是

一)推薦strpos這個簡單的東西,而不是正則表達式的功能。

$usrPath = '../some/path/'; 
if (strpos($usrPath, '.' . DIRECTORY_SEPARATOR) !== false){ 
    die('oh no you don\'t'); 
} 

b)建議確保您的服務器設置和文件系統權限被設置爲防止獲得「超出了他們的區域」,而不是編程方法的用戶的任何機會。

+0

請注意,這種strpos的使用將匹配'foo。/ bar',並且不會匹配字面意義爲「..」或「。」的路徑。 – pilcrow 2012-03-10 19:24:29

+0

我認爲!==(不!=)意味着它應該匹配'。'和'..',除非我很密集。要檢查點是否開始字符串,可以這樣做:if(strpos($ usrPath,'。')=== 0){die('oh no you't't');}' – fred2 2012-03-10 20:12:07

+0

但是說實話, @佩卡說,我想說得更有說服力。沒有strpos/preg_match解決方案很聰明。 – fred2 2012-03-10 20:14:07

6

檢查「..」的存在是對問題不完美的解決方案。

如果要防止用戶跳出基本目錄,請檢查路徑結果(將考慮相對路徑)是否仍在根路徑下。

例子:

$root = "/my/user/basepath"; 
$requested_path = $_GET["input"]; // or whatever 

$real_path = realpath($root."/".$requested_path); 

if (strpos($real_path, $root) !== 0) 
die ("Illegal path"); 
0
$myString = "some/path"; 
if (preg_match('/(\.\.\/|\.\/)/', $myString)) { 
    echo "found ../ or ./ in path"; 
} 
+1

是否需要「// i」修飾符?你的語言環境中是否有大小寫點或斜線? :) – pilcrow 2012-03-10 19:25:02

+0

大聲笑,不,我想這不會做太多,是吧? – 2012-03-11 03:31:48