2015-11-08 31 views
0

目標

從XML「數據庫」中以簡單(並且我知道非常不安全)的方式驗證登錄數據。XML Database Array做奇怪的事情。嘗試使用XML和PHP驗證登錄

這裏的代碼是負責數據庫和檢索值的。選項一是我最初嘗試的,所以它仍然包含交叉引用用戶名和密碼的輸入數據與XML數據庫中的數據的代碼。 選項二是我嘗試不同方法的地方。似乎都沒有工作。 附上截圖。

方案一:

的login.php:

<?php 
if(!isset($_SESSION['user'])) { ?> 
<div>Please login to view your message log, and see whether anyone has left you a message.</div> 
<form action="php/authenticate.php" method="POST" > 
    <input type="text" name="Username" /> 
    <input type="password" name="Password" /> 
    <input type="submit" value="Login" /> 
</form> 
<?php }; 
$passwordValid = $_GET['error']; 
if($passwordValid == 1) { 
    echo "Falsches Password"; 
}; 
?> 

authenticate.php:

<?php 
session_start(); 

    // Load Credential Database 
    $xml = new DOMDocument(); 
    $xml->load('../logins.xml'); 
    $xpath = new DOMXPath($xml); 

    // Variable Declarations 
    $user = $_POST['Username']; 
    $password = $_POST['Password']; 

    // XPath Query for Correct Credential 
    $queryUsers = '//authentication/client/user[. = "' . $user . '"]'; 
    $userActual1 = $xpath->query($queryUsers); 
    $userActual = $userActual1->nodeValue; // Output: Anton 
    $passwordActual1 = $userActual1 . 'following-sibling::*[1]'; 
    $passwordActual = $xpath->query($passwordActual1); // Output: damn 

    // Authentication Checker 
    if($user == 'Arend' && $password == 'damn') { 
     $userLogin = true; 
     $_SESSION['user'] = $user; 
     header('Location: ../index.php'); 
    } else { 
     $userLogin = false; 
     header('Location: ../index.php?error=1'); 

    }; 

    if($userLogin == true) { 
     header('Location: ../index.php'); 
    }; 
?> 

XML 「logins.xml」:

<?xml version="1.0" encoding="UTF-8"?> 
<authentication> 
    <client> 
     <user>Arend</user> 
     <password>damn</password> 
    </client> 
    <client> 
     <user>Felipe</user> 
     <password>damned</password> 
    </client> 
    <client> 
     <user>Paula</user> 
     <password>damnest</password> 
    </client> 
</authentication> 

方案二:

XML代碼 「的test.xml」:

<?xml version="1.0" encoding="UTF-8"?> 
<authentication> 
    <user name="Arend"> 
    </user> 
     <password>damn</password> 
    <user name="Paula"> 
    </user> 
     <password>damnest</password> 
</authentication> 

PHP代碼:

<?php 
    $xml = simplexml_load_file('test.xml'); 
    $nodes = $xml->xpath('//authentication/user[@name="Arend"]'); 

    // Variable Declarations 
    $user = "Arend"; 
    $password = "damn"; 

    echo 'second test' . '<br>'; 
    print_r ($nodes); 
    echo '<br>'; 
    print_r ($nodes[0]['name']); 
    echo '<br>'; 
    echo $nodes[0]['name']; 
?> 

結果:

正如你所看到的,它抓住了XML數據和數組以及它在結構中的結構如何在屏幕截圖中查看。我能夠獲得用戶名,但是如果我嘗試指定密碼(echo $nodes[0]['password'];)作爲我想要的內容,則會出現以下第二張圖像:

+0

我只是要藉此機會指出,這實際上是在不安全實際上完全不顧您作爲系統設計者的責任。你永遠不應該保存純文本密碼。看看bcrypt,特別是如果你打算像這樣保存它們。 – MiDri

+0

同意MiDri。考慮到他的觀點,我不認爲你的XML是最好的格式。密碼節點應該是用戶的孩子,或者可能是屬性,例如, ' asdf'或'' – rjdown

+0

選項2肯定不明智(忽略整個logins.xml是壞的想法),因爲他們沒有共享的父母。密碼和用戶應該以某種方式分組。所以我想說選擇1是這樣做的唯一有價值的選擇。 – JPMC

回答

1

您承認這是不安全的,所以我不會獾或評論了。

至於使用logins.xml,就像你的第一個例子,我有一個適當的XPath和解決方案。不過,我使用了simpleXML,它使用了PHP。

//load credentials 
$xml = simplexml_load_file(__DIR__.'/logins.xml'); 
// Variable Declarations 
$user = $_POST['Username']; 
$password = $_POST['Password']; 
$search = $xml->xpath("//authentication/client[./user = '{$user}'][./password = '{$password}']"); 

if(count($search)) 
{ 
    //authenticated! 
} 
else 
{ 
    //DENIED 
} 

它確實匹配同時具有子<user>等於$user<password>等於$password一個<client>節點,而不是非此即彼,但兩者。

count($search)如果沒有,則返回0(false),然後其他任何內容都將轉換爲true,這意味着它們存在於您的數據集中。

  • 聲明,我用__DIR__因爲XML和PHP在同一個文件夾中的我,當我測試了我的XPath表達式。我想說永遠不要在web根目錄下有敏感的憑據,或者在某些地方沒有受到某種形式的HTAccess或其他限制的保護。

對於使用DOM文檔和DOMXPath,他們擁有的,而不是一個可數集的length參數。你反而會對這種檢查的if/else

$xmlpath= $xpath->query("//authentication/client[./user = '{$user}'][./password = '{$password}']"); 
if($xmlpath->length > 0) 
{ 
    //authenticate 
} 
else 
{ 
    //not 
} 

最後一個安全警告,使用直接$_POST變量,我想補充的意識,有這樣的事,作爲XPath注入,就像SQL注入。您的功能不用於顯示數據,所以它不會泄漏來自文檔的信息。但他們可以用它來進行查詢總是返回true,並讓他們登錄。

見的例子,包括登錄憑據XML像你這樣的!:https://www.owasp.org/index.php/XPATH_Injection

+0

第一個解決方案非常完美,謝謝,我正在閱讀關於注入的OWASP頁面(這不可避免地會導致更多關於注入的頁面),所以非常感謝大家,我會稍微嘗試第二個解決方案。 – Saborknight

2

不要存儲明文密碼,使用password_hash()來創建散列並且password_verify()來驗證它們。

隨着DOMXpath::evaluate()您可以直接在用戶獲取密碼:

$xml = <<<'XML' 
<?xml version="1.0" encoding="UTF-8"?> 
<authentication> 
    <client> 
     <user>Arend</user> 
     <password>$2y$10$WjYhm/JoG3Pn.nT7C91cweOCrshRSZOgYFoYvrG8Ry1SS/tohGfA.</password> 
    </client> 
    <client> 
     <user>Felipe</user> 
     <password>$2y$10$PlUKayvRmTy61sFMtAhlxePKGAkTL8LU84gvP1EjUn/3e0E2jHMgi</password> 
    </client> 
    <client> 
     <user>Paula</user> 
     <password>$2y$10$3XDNia4TqVJ5QlqH/zoX/e9.t7YJF5K1hNVZnnuoslI/hjvv0St1W</password> 
    </client> 
</authentication> 
XML; 

$document = new DOMDocument(); 
$document->loadXml($xml); 
$xpath = new DOMXpath($document); 

$passwordHash = $xpath->evaluate(
    'string(/authentication/client[user = "Arend"]/password)' 
); 

var_dump(password_verify('damn', $passwordHash)); 

輸出:

bool(true) 
+0

呵呵,那很方便!不知道「評估」!儘管你可以在查詢或simpleXML中使用該XPath,並將該元素轉換爲字符串以獲得相同的結果。無論哪種情況,我都想提醒人們注意,這可以防止'$ password'成爲注入向量,但是'$ name'仍然需要消毒。但從安全角度來看,您的解決方案仍然更好。 +1 – JPMC

+1

確實,消毒或引用值以避免Xpath注入:http://stackoverflow.com/a/27440520/2265374 – ThW

+0

這是一個很好的鏈接。我可能會更深入地看待醫療。你認爲我們中的任何一個人應該爲我們的答案增加清晰度?或者只是留下功能性的結果,並承認缺陷是什麼,而不必去解決它們的話題? – JPMC