目标
从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