php - PHP CSRF 令牌脚本阻止我表单上的提交按钮
问题描述
我有一些我正在使用 cookie、会话和 csrf 令牌创建登录页面的 php 脚本。这些脚本是面向对象的并使用类,但是 CSRF 令牌是我表单中的隐藏输入,它阻止了提交按钮的呈现。几个月来我一直在盯着它摆弄它,但我无法弄清楚错误在哪里或为什么它会阻止按钮的呈现,我有错误报告,但没有显示错误。我也在使用 spl_autoload_register() 函数来加载我的类,但我不认为这是问题所在。任何帮助将不胜感激
注册.php
<?php require_once 'Core/init.php';
include 'Core/head.php';
if(!Usr){ // Not doing anything.....
echo '<span style="color:white;">You must be logged in to view properties</span>';
}
?>
<h1 style="color:white;">Let Living Be Life</h1>
<h2 style="color:white;">Property Rentals</h2>
<a href="index.php">Home</a><br>
<a href="profile.php">Profile</a><br>
<a href="register.php">Register</a><br>
<a href="login.php">Login</a><br>
<a href="logout.php">Logout</a><br>
<a href="changepassword.php">Change Password</a><br>
<a href="info.php">Info</a><br>
<input type="radio" name="theme-switch"><span style="color:white;">Theme</span>
<form action="" method="post">
<input id="usrname" type="text" name="usrname"
placeholder="Username" autocomplete="off" required="true">
<input id="psw" type="password" name="psw"
placeholder="password" autocomplete="off" required="true">
<input type="checkbox" name="remember" id="remember"> <span style="color:white;">Remember me.</span>
<!-- This is not being rendered either !!!!!!!!!!!!!!!! -->
<input type="hidden" name="csrf_tokenz" value="<?php echo Token::gen_csrf_token(); ?>"><br> <!-- Added '' around the echo, but it is not generating a valid token, button is back though...-->
<!-- Note, Something is blocking the button from rendering ???????????????????? -->
<button id="Submit_btn" type="submit">Submit</button>
</form>
<a href="index.php">Home</a>
<a href="profile.php">Profile</a>
<a href="register.php">Register</a>
<a href="login.php">Login</a>
<a href="logout.php">Logout</a>
<a href="changepassword.php">Change Password</a>
<a href="info.php">Info</a>
<?php
// $_SESSION['user-type'] = guest; << need to set this at top of loggin page. aswell as other checks.
if(Input::inp_exists()){
if(Token::check_token(Input::post_or_get_inp('csrf_tokenz'))){
$validate = new Validate();
$validation = $validate->check_val($_POST, array(
'usrname' => array('required' => true),
'psw' => array('required' => true)
));
if($validation->vali_passed()){
// Log Usr in..
$usr = new Usr();
$remember = (Input::post_or_get_inp('remember') === 'on') ? true : false;
$login = $usr->login_usr(Input::post_or_get_inp('usrname'), Input::post_or_get_inp('psw'), $remember);
if($login){
Redirect::r_to('index.php');
echo 'Success';
}else{
echo '<p>Sorry Login Failed</p>';
}
}else{
foreach($validation->vali_errors() as $error){
echo $error, '<br>';
}
}
}
}
?>
令牌类.php
<?php // Check all Syntax::>>
class Token{
public static function gen_csrf_token(){ // Csrf Token 1.
return Session::sesh_put(Config::get_conf('session/token_name'), bin2hex(random_bytes(28)).openssl_random_pseudo_bytes(7)); // md5(uniqid()) md5(random_bytes(164))<< this is the old version which is deprecated...
}
public static function gen_csrf_token2(){ // Csrf Token 2.
return Session::sesh_put(Config::get_conf('session/token2_name'), bin2hex(random_bytes(28)).openssl_random_pseudo_bytes(7)); // ::>> Brackets maybe wrong way round in here.
}
public static function genchilli_token(){ // Use this to Build a Pepper, Salt is in the Hash Class. Abstract Away..
$Chilli = bin2hex(128).=openssl_random_psuedo_bytes(48).=md5('x12ii21ii12x');
return $Chilli; // <<:: Test me?
}
public static function check_token($token){
// echo 'I have been run line 15 Token Class';
$token_name = Config::get_conf('session/token_name'); // ::>> index=12
// echo 'I have been run line 16 Token Class';
if(Session::sesh_exists($token_name)&& $token === Session::get_sesh($token_name)){
Session::del_sesh($token_name);
return true;
}
return false;
}
}
Token 类依赖 Session 和 Conig 类来工作。即函数:Session::sesh_put() & Config::conf_get() 但我在这里也找不到任何错误,也没有显示错误。
会话.class.php
<?php
class Session{
public static function get_sesh($name){
// echo 'Debug Only >> Session::Get Ran';
return $_SESSION[$name]; // ::<< these relate to Token Name in Token.class.php
}
public static function sesh_put($name, $value){
// echo 'Debug Only >> Session::put Ran';
return $_SESSION[$name] = $value;
}
public static function sesh_exists($name){
// echo 'Debug Only >> Session::exists Ran';
return (isset($_SESSION[$name])) ? true : false;
}
public static function del_sesh($name){
if(self::sesh_exists($name)){
unset($_SESSION[$name]);
}
}
public static function sesh_flash($name, $string = ''){ // Used for flashing a msg to user.
if(self::sesh_exists($name)){ // Flash eps 13 // Not returning any messages for some reason..
$session = self::get_sesh($name);
self::del_sesh($name); // This deletes the session
return $session;
} else {
self::sesh_put($name, $string);
}
}
}
// After done upload to code review
?>
配置文件
<?php // ::>> This File Has no Errors. Upto eps 8 No errors spotted so far..
class Config{ // ::>> Need to build in here a check for Faulty Paths then Exit script. destroy session, log user out.
public static function get_conf($path = null){
if($path){
$config = $GLOBALS['config'];
$path = explode('/', $path);
foreach($path as $bit){
if(isset($config[$bit])){
$config = $config[$bit];
}
}return $config;
}return false;
}
}
初始化文件
<?php
session_start();
error_reporting(E_ALL & E_NOTICE);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
$GLOBALS['config'] = array(
'mysql' => array(
'host' => 'localhost', // ::> 127.0.0.1
'charset' => 'redacted',
'db-usr' => 'redacted',
'db-psw' => 'redacted',
'db' => 'redacted',
'ssh' => 'false', // ::<< I added these last three for later Updates to Determine access via these three methods.
'cli' => 'false', // <<:: Need very strong Authentication If I every choose to use these.
'cgi' => 'false' // ::>> Set-up two factor Authentication at some point.
),
'remember' => array(
'cookie_name' => 'hashish_cookie',
'cookie_expiry' => '784828'
// 'preferences' => array( // <<:: I added this for later functionality.
// 'usr_pref' => 'has_cat',
// 'needs' => 'null'
// ),
),
'session' => array( // Add different Session types in here ie. Guest, Admin, Mod, ExtMod, RootAd, HasCat.
'session_name' => 'usr_session',
'token_name' => 'csrf_tokenz',
'token2_name' => 'csrf_tokenz2',
'hacker_bait' => 'redacted',
'has_cat' => '0'
)
); // Closing Tag for Globals Array
spl_autoload_register(function($class) {
require_once 'Classes/' . $class . '.class.php';
});
require_once 'Functions/sanitize.php';
if(Cookie::cookie_exists(Config::get_conf('remember/cookie_name')) && !Session::sesh_exists(Config::get_conf('session/session_name'))){
echo 'User Asked to Be remembered!';
$hash = Cookie::get_cookie(Config::get_conf('remember/cookie_name'));
$hashCheck = DB::getInstance()->get_dbr('usr_session', array('hash', '=', $hash)); // <<:: Check if this is xx >> usr_session << Correct one < or usrs_session..
if($hashCheck->count_dbr()){
echo 'Hash matches, log usr in';
} // Unsure if this is dbr_count or count_dbr or a built in pdo version of count?
}
?>
任何帮助或指示将不胜感激,因为我找不到错误及其困扰我。当我重新登录到我的托管站点后,将在一分钟内更新问题并包含 config.php。我已经尝试使用 md5、uniqid、random_bytes、ssl_random_pseudo_bytes 和多种不同的组合,但无法使其正常工作。我知道关于如何安全地生成 CSRF 令牌还有许多其他问题,但我发现没有一个问题是使用类或面向对象的程序,它们也没有解决我的具体问题。我已经阅读了多个不同的,其中一些有助于我的理解,但没有解决这个问题。
图像显示正在渲染的内容以及停止或中断的位置。正如 Mike 在评论中建议的那样使用 Ctrl + U 。
更新,在阅读 Mike 分享的帖子后,刚刚在 E_NOTICE 错误报告中添加了一个 ~:错误报告,它生成了一个以前没有显示的新通知,因此这可能有助于解决这些问题。图片如下:
修正:注释掉辣椒功能的内部......
解决方案
您收到的错误消息让我陷入了一个循环,因为错误中的行号与产生错误的代码中的行号不同,这意味着您必须在发布问题之间更新代码以及当您发布错误消息时。重要的是要确保您发布的错误消息是通过执行您拥有的代码实际产生的错误消息,否则没有人将能够重现您的错误。
你的问题是这一行:
$Chilli = bin2hex(128).=openssl_random_psuedo_bytes(48).=md5('x12ii21ii12x');
这是一个语法错误,应该是这样的:
$Chilli = bin2hex(128) . openssl_random_psuedo_bytes(48). md5('x12ii21ii12x');
或这个:
$Chilli = bin2hex(128);
$Chilli .= openssl_random_psuedo_bytes(48);
$Chilli .= md5('x12ii21ii12x');
推荐阅读
- dbeaver - 有没有办法找到引用 DBeaver 中另一个表/列的所有表?
- sql-server - SQL SERVER:子查询中的 WHERE 子句从外部查询中获取属性
- firebase - Firebase 身份验证和谷歌云翻译
- r - R 函数仅显示列的 20% 最高值
- laravel - 如何使用两个输入文本进行搜索,一个用于搜索,另一个用于排除
- sql - MS Access 查询输入必须包含至少一个表或查询
- c - 内部带有指针的结构是一个数组(C)
- delphi - 如何在 OnHint 事件处理程序中检测提示发送者控制?
- mysql - MySQL 查询:使用 DateTime 从 1 列中获取数据
- azure-active-directory - 如何通过守护程序应用程序在团队频道中发送消息