通过 Symfony 3.4 上的 CSRF 令牌保护 jquery Ajax 请求免受 CSRF 攻击
Protect jquery Ajax Requests from CSRF attacks via CSRF token on Symfony 3.4
我有以下 Symfony 控制器:
namespace AppBundle\Controller
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
class MyController extends Controller
{
/**
* @Route("/form", name="get_form")
* @Method("GET")
*/
public function getFormAction(Request $request)
{
return $this->render('some_twig.html.twig');
}
/**
* @Route("/form_submit", name="submit_form")
* @Method("POST")
*/
public function ajaxFormAction(Request $request)
{
if($request->isXmlHttpRequest()){
return new JsonResponse(['data':"All midori"],JsonResponse::HTTP_OK);
} else {
return new JsonResponse(['data':"Echi, hentai, baka"],JsonResponse::HTTP_BAD_REQUEST);
}
}
}
表单通过以下 javascript 代码提交:
$("#someform").on('submit',function(e){
e.preventDefault();
var self=this; //To avoid Confusion using this
var url=$(self).attr('action');
$.ajax({
'method': "POST",
'url': url,
'data': $(self).serialize(),
'statusCode': {
400: function(data,textStatus,jqXHR) {
//Handle Error 400
},
500: function(data,textStatus,jqXHR){
//Handle error 500
}
},
'success':function(data){
//DO some stuff
}
});
})
但是我在如何保护 Symfony Ajax 方法免受 CSRF 攻击方面遇到了一些麻烦。当我尝试通过在 aeero 发生时形成 CSRF 令牌来保护时,例如。抛出的异常使我的表单变得垃圾。
不保护也不是最好的选择。那么如何有效保护它呢?
通过过期,最好的可行选择是使用 DunglasAngularCsrfBundle
(查找文档 here)。在您的示例中,将以下代码放入您的 security.yml
:
dunglas_angular_csrf:
# Collection of patterns where to set the cookie
cookie:
set_on:
- {route: ^get_form, methods: [GET]}
secure:
- {route: ^submit_form, methods:[POST]}
然后修改jquery代码如下:
$("#someform").on('submit',function(e){
e.preventDefault();
var self=this; //To avoid Confusion using this
var url=$(self).attr('action');
$.ajax({
'method': "POST",
'url': url,
'data': $(self).serialize(),
'beforeSend': function(request) {
request.setRequestHeader('X-XSRF-TOKEN', Cookies.get('XSRF-TOKEN'));
},
'statusCode': {
400: function(data,textStatus,jqXHR) {
//Handle Error 400
},
500: function(data,textStatus,jqXHR){
//Handle error 500
}
},
'success':function(data){
//DO some stuff
}
});
})
我也使用库 js-cookie but you can use the methods mentioned in the following answer 获取 cookie 值。
整个想法是通过 XSRF-TOKEN
获取 CSRF 令牌(应该大写而不是文档中所说的)和 return 通过自定义 http header 获取值X-XSRF-TOKEN
(也都应该是大写)。
这样你就可以和漏洞说再见了。
我有以下 Symfony 控制器:
namespace AppBundle\Controller
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
class MyController extends Controller
{
/**
* @Route("/form", name="get_form")
* @Method("GET")
*/
public function getFormAction(Request $request)
{
return $this->render('some_twig.html.twig');
}
/**
* @Route("/form_submit", name="submit_form")
* @Method("POST")
*/
public function ajaxFormAction(Request $request)
{
if($request->isXmlHttpRequest()){
return new JsonResponse(['data':"All midori"],JsonResponse::HTTP_OK);
} else {
return new JsonResponse(['data':"Echi, hentai, baka"],JsonResponse::HTTP_BAD_REQUEST);
}
}
}
表单通过以下 javascript 代码提交:
$("#someform").on('submit',function(e){
e.preventDefault();
var self=this; //To avoid Confusion using this
var url=$(self).attr('action');
$.ajax({
'method': "POST",
'url': url,
'data': $(self).serialize(),
'statusCode': {
400: function(data,textStatus,jqXHR) {
//Handle Error 400
},
500: function(data,textStatus,jqXHR){
//Handle error 500
}
},
'success':function(data){
//DO some stuff
}
});
})
但是我在如何保护 Symfony Ajax 方法免受 CSRF 攻击方面遇到了一些麻烦。当我尝试通过在 aeero 发生时形成 CSRF 令牌来保护时,例如。抛出的异常使我的表单变得垃圾。
不保护也不是最好的选择。那么如何有效保护它呢?
通过过期,最好的可行选择是使用 DunglasAngularCsrfBundle
(查找文档 here)。在您的示例中,将以下代码放入您的 security.yml
:
dunglas_angular_csrf:
# Collection of patterns where to set the cookie
cookie:
set_on:
- {route: ^get_form, methods: [GET]}
secure:
- {route: ^submit_form, methods:[POST]}
然后修改jquery代码如下:
$("#someform").on('submit',function(e){
e.preventDefault();
var self=this; //To avoid Confusion using this
var url=$(self).attr('action');
$.ajax({
'method': "POST",
'url': url,
'data': $(self).serialize(),
'beforeSend': function(request) {
request.setRequestHeader('X-XSRF-TOKEN', Cookies.get('XSRF-TOKEN'));
},
'statusCode': {
400: function(data,textStatus,jqXHR) {
//Handle Error 400
},
500: function(data,textStatus,jqXHR){
//Handle error 500
}
},
'success':function(data){
//DO some stuff
}
});
})
我也使用库 js-cookie but you can use the methods mentioned in the following answer 获取 cookie 值。
整个想法是通过 XSRF-TOKEN
获取 CSRF 令牌(应该大写而不是文档中所说的)和 return 通过自定义 http header 获取值X-XSRF-TOKEN
(也都应该是大写)。
这样你就可以和漏洞说再见了。