[英]CSRF session token
我正在尝试在表单上实现简单的CSRF保护,但是我做对了。 如果有人指出我在做什么错,我将不胜感激。
错误:每次提交表单时,都会收到“无效的Submission2”,因为令牌更改了(提交表单后),因为令牌是在同一页面上生成的?
编辑-我忘了提及,另一个文件(config.php)已经具有session_start()。
<?php
class Module_Post extends Base_Module {
public function start()
{
requireLogin();
if (isset($_GET['act'])) {
switch($_GET['act']) {
case 'text':
$this->text();
break;
case 'image':
$this->image();
break;
default:
$this->text();
break;
}
} else {
$this->text();
}
}
private function text()
{
// Generate random unique token to prevent cross-site request forgery (CSRF).
if(empty($_SESSION['form_token']))
{
$form_token = md5(uniqid(rand(), TRUE));
$_SESSION['form_token'] = $form_token;
}
if(isset($_POST['submit']))
{
// Clean the content from cross-site scripting (xss)
$content = trim($_POST['content']);
$content = Xss::clean($content);
// Validate that the form token
if(!isset($_POST['form_token'], $_SESSION['form_token'])) {
$err = 'Invalid Submission';
} elseif ($_POST['form_token'] != $_SESSION['form_token']) {
$err = 'Invalid Submission2';
} elseif (strlen($content) < 10) {
$err = 'Your content contains too few characters.';
}
if(isset($err)) {
unset( $_SESSION['form_token']);
$this->setMessage($err, 'FAIL');
header('Location: index.php?mod=post');
exit;
}
// Insert database data here, then redirect
$this->setMessage('Your post was published successfully.', 'GOOD');
header('Location: index.php');
exit;
}
$this->tpl->assign('form_token', $form_token);
$this->tpl->display('new/text.tpl');
}
}
?>
HTML(text.tpl文件)
<form method='post' enctype='multipart/form-data' action='#'>
<fieldset>
<textarea rows="8" id="new_post" name="content" class="input-block-level"></textarea>
<input type="hidden" name="form_token" value="{$form_token}" />
<button type="submit" name="submit" class="btn btn-info pull-left">Create Post</button>
</fieldset>
</form>
您需要更改此行
$this->tpl->assign('form_token', $form_token);
成:
$this->tpl->assign('form_token', $_SESSION['form_token']);
那是因为您仅在以下条件下生成令牌:
if(empty($_SESSION['form_token']))
{
$form_token = md5(uniqid(rand(), TRUE));
$_SESSION['form_token'] = $form_token;
}
并使用以下条件取消设置:
if(isset($err)) {
unset( $_SESSION['form_token']);
}
因此,如果您发送一次表单然后重新加载页面(不提交表单,而仅提交URL),则$form_token
变量是未知的,因为其中有$_SESSION['form_token']
不为空,然后在表单中您具有空令牌。
如果您在PHP中打开了显示错误,在这种情况下,您会在PHP中看到:
Undefined variable: form_token in
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.