Я пытаюсь реализовать защиту в одном приложении от CSRF.
В PHP это относительно просто реализовать. У меня много вопросов о том, как это сделать с Extjs.
Книги по EXTJS, которые я читал, не затрагивают эту тему, и я не могу найти конкретных руководств по этому вопросу — с EXTJS — в Интернете.
Некоторые вопросы:
Используя PHP, токен отправляется в EXTJS?
Должен ли я создавать скрытое поле в каждой форме, как в PHP?
Должен ли я отправлять на сервер токен в Ext.Ajax.requestt? Как это сделать?
Некоторый очень простой код в качестве отправной точки:
Токен класса: https://www.youtube.com/watch?v=VflbINBabc4
<?php
class Token {
public static function generate() {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
public static function check($token) {
if(isset($_SESSION['token']) && $token === $_SESSION['token']){
unset($_SESSION['token']);
return true;
}
return false;
}
}
?>
Запрос
<?php
require('conect.php');
require_once('token.php');
$action = $_REQUEST['action'];
switch($action){
case "create":{
$records = $_POST['records'];
$data = json_decode(stripslashes($records));
if(isset($_POST['cars'], $_POST['token'])){
$cars = $data->{'cars'};
if(Token::check($_POST['token'])){
$sqlQuery = "INSERT INTO the_cars (cars) VALUES (?)";
if($statement = $con->prepare($sqlQuery)){
$statement->bind_param("s", $cars);
$statement->execute();
$success= true;
}else{
$erro = $con->error;
$success = false;
}
}else{
//error
}
echo json_encode(array(
"success" => $sucess,
'errors'=> $erro
));
$statement->close();
$conexao->close();
break;
}
}
?>
Я был бы признателен за помощь в подробном понимании того, как реализовать этот тип защиты, используя приведенный выше код в качестве примера.
Заранее спасибо.
Несколько полезных постов:
Предотвращение CSRF для вызова AJAX из extjs в действие Struts а>
Как реализовать CSRFGuard в ExtJs AjaxRequest?
ExtJS Store SYNC с включенной Spring Security
http://blog.gugl.org/archives/category/extjs
ОТРЕДАКТИРОВАНО
Мне нравится одна из возможностей — отправлять токен при каждом запросе Ajax: https://www.sencha.com/forum/showthread.php?134125
Мейб в Aplication.js. файл
init: function () {
Ext.require(["Ext.util.Cookies", "Ext.Ajax"], function(){
// Add csrf token to every ajax request
var token = Ext.util.Cookies.get('csrftoken');
if(!token){
Ext.Error.raise("Missing csrftoken cookie");
} else {
Ext.Ajax.defaultHeaders = Ext.apply(Ext.Ajax.defaultHeaders || {}, {
'X-CSRFToken': token
});
}
});
}
ИЛИ из видео Building Applications with EXT JS, опубликованного PACKT, но с узлом на стороне сервера
var csrfToken = Ext.query('meta[name=csrf-token]')[0].getAttribute('content');
Ext.Ajax.defaultHeaders = ('X-CSRF-Token': csrfToken);
Ext.Ajax.extraParams = {'csrf': csrfToken};
У меня все еще есть сомнения относительно того, как правильно связать серверную часть (сгенерировать токен и выполнить соответствующую проверку) с клиентской стороной.
ОТРЕДАКТИРОВАНО
За последние несколько дней я предпринял несколько попыток запустить CSRFProtector с php и EXTJS.
В результате проведенного анализа с помощью Chrome Dev Tools я смог проверить следующее:
Если я добавляю только в начале индекса файла (а не в других файлах php):
include_once __DIR__ .'csrfp/libs/csrf/csrfprotector.php';
csrfProtector::init()
Я получаю инструменты Chrome Dev:
файл csrfprotector.js загружен
В загруженных файлах php у меня есть »Метод: POST, статус 200, тип xhr, инициатор csrfprotector.js: 259
Я вижу, что данные (в формате JSON) и токен отправляются, а заголовки запрашиваются как файл cookie с тем же токеном.
Кроме того, в файле index.php, как и ожидалось, создается следующее:
(...)
<script type="text/javascript"
src="http://my_path/csrfp/js/csrfprotector.js"></script>
<script type="text/javascript">
window.onload = function() {
csrfprotector_init();
};
</script>
</body>
</html>
Ошибка не возвращается
Когда я добавляю в начало файла php (содержащего запрос, который будет получать данные запроса, например, для создания записи) include_one и csrfProtector::init(), запрос выполняется, успех равен false, и я получаю код состояния 403 и сообщение 403 Access Forbidden by CSRFProtector!
Если я добавлю эхо «Тест 1», перед csrfProtector::init(); и эхо «Тест 2» после этого работает только первое эхо. Так что проблема не в моем php-коде, а в проверке с помощью csrfprotector.
В Dev Tools вы видите, что ошибка 403 возникает при упоминании следующей строки скрипта: csrfprotector: 259. Строка 259 этого файла: return this.old_send (data);
Я собираюсь исследовать возможную несовместимость csrfprotector с JSON.
Если бы мы могли запустить CSRFProtector с PHP и EXTJS (с JSON), это было бы решение, которое могло бы иметь большое значение для многих, поскольку его очень легко реализовать.
Пример формата данных, полученных на стороне сервера:
Array
(
[action] => create
[_dc] => 1505398990654
[data] => {"id_cars":"id_1","cars":"test"},
)
Content-type: application/x-www-form-urlencoded
(пример в связанной Sencha Fiddle), либо открыть вопрос\помощь, чтобы исправить Protector на заставить его работать с json. Другого пути сейчас нет... - person Michal Levý   schedule 13.09.2017