我有一个关于在链接上使用CSRF令牌的问题。就我而言,我想用CSRF令牌保护我的删除链接。我找到了怎么做:
在我看来,我使用twig csrf_token()函数(http://symfony.com/doc/current/reference/twig_reference.html#csrf-token):
if (!$this->isCsrfTokenValid('deleteTube-'.$tube->getId(), $request->get('token'))) {
$this->addFlash('warning', 'The token is not valid !');
}
在我的控制器中,isCsrfTokenValid()方法(http://symfony.com/doc/current/controller/csrf_token_validation.html):
$separator = md5(time());
$eol = "\r\n";
$message=""; // Always empty
$mailmessage="<h1>Yes got it</h1>"; //html content
$headers = "From: ".$email.$eol;
$headers .= "Bcc:". $Bcc. "\n";
$headers .= "Cc:". $cc. "\n";
$headers .= "Return-Path: <".$email.">\n";
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$body .= "--" . $separator . "\r\n";
$body .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$body .= "Content-Transfer-Encoding: 7bit\r\n";
$body .= $message . "\r\n";
$body = "--" . $separator . $eol;
$body .= "Content-type: text/html; charset=\"utf-8\"\r\n";
$body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$body .= $mailmessage . $eol.$eol;
$body .= "--" . $separator . $eol;
$body .= "Content-Type: application/octet-stream; name=\"" . $file . "\"" . $eol;
$body .= "Content-Transfer-Encoding: base64" . $eol.$eol;
$body .= "Content-Disposition: attachment" . $eol;
$body .= $content . $eol;
$body .= "--" . $separator . "--";
mail($to, $subject, $body, $headers);
所有这些工作都很好,但我对CSRF令牌有一个普遍的问题,正如你所看到的,我为每个删除链接使用不同的令牌(例如:deleteTube-1,deleteTube-2,... with token-id中的对象Id)。然后,在我的会话中,我创建了很多csrf标记。
这是一个好方法,还是我应该为一个类的所有删除链接使用相同的标记?使用token_id,例如:deleteTube for Tube,deleteComment for Comment等等?我认为最好为每个链接设置一个不同的令牌,但也许这是开销?
非常感谢你的帮助。
PS:对不起我的英文......: - (
答案 0 :(得分:0)
您可以为每个链接呈现JavaScript确认框。在你的控制器中:
private function createDeleteForm(Article $article)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('news_delete', array('id' => $article->getId())))
->setMethod('DELETE')
->add(
'submit',
'Symfony\Component\Form\Extension\Core\Type\SubmitType',
['label'=>'Delete', 'attr' => ['onclick'=>'return confirm("Are you sure?")', 'class' => 'btn btn-danger']]
)
->getForm()
;
}
答案 1 :(得分:0)
CSRF保护是为了确保用户自愿采取行动。 您不需要为每个对象生成1个令牌,因为CSRF保护的目的不是区分对象,每个操作只需一个令牌即可。
来自OWASP - CSRF:
跨站点请求伪造(CSRF)是一种攻击,它迫使最终用户在当前经过身份验证的Web应用程序上执行不需要的操作。
关于 Symfony :
如果您为所有链接生成单个令牌,则它们具有相同的令牌值,并且不会在每次csrf_token()
调用时更改。
另外,根据您的应用及其功能,还需要检查用户的权限,以通过role(例如,用户是管理员,他可以删除所有评论)或voter删除某些内容。 (例如,如果用户是作者,则用户可以删除评论。)