XML数据库数组做着奇怪的事情.尝试使用XML和PHP验证登录名


XML Database Array doing weird things. Trying to authenticate login using XML and PHP

目标

从XML"数据库"中获取数据,作为验证登录数据的一种简单(我知道,这是非常不安全的)方法。

这里的代码负责数据库和检索值。选项一是我最初尝试的,因此它仍然包含将用户名和密码的输入数据与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'];)作为我想要的东西,它会出现下面的第二个图像:

不要存储纯文本密码,请使用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)

您承认这是不安全的,所以我不会再纠缠或评论了。

至于使用logins.xml,就像您的第一个例子一样,我有一个合适的XPath和解决方案。不过,我使用了PHP附带的simpleXML。

//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__是因为在测试XPath表达式时,XML和PHP在同一个文件夹中。我想说的是,永远不要把你的敏感凭据放在web根目录中,或者放在不受某种形式的HTAccess或其他限制保护的地方

为了使用DOMDocument和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