JavaScript — EXTJS CSRF защита

Я пытаюсь реализовать защиту в одном приложении от 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 с включенным 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
});
}
});
}

ИЛИ от Создание приложений с помощью 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 Tools:

Файл csrfprotector.js загружен

В загруженных файлах php у меня есть »Метод: POST, Status 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 () запрос выполняется, успех ложен, и я получаю код состояния 403 и сообщение 403 Доступ запрещен CSRFProtector!

Если я добавлю эхо ‘Test 1’, перед csrfProtector :: init (); и эхо «Test 2» после, только первое эхо работает. Так что это не проблема в моем php-коде, но в проверке csrfprotector.

В Dev Tools вы видите, что ошибка 403 вызывается при упоминании следующей строки скрипта: csrfprotector: 259.
строка 259 этого файла: вернуть this.old_send (data);

Я собираюсь исследовать возможную несовместимость csrfprotector с JSON.

Если бы мы смогли запустить CSRFProtector с PHP и EXTJS (с JSON), это было бы решение, которое могло бы иметь значение для многих, поскольку его очень легко реализовать.

Пример формата данных, полученных на стороне сервера:

Array
(
[action] => create
[_dc] => 1505398990654
[data] => {"id_cars":"id_1","cars":"test"},
)

10

Решение

Учитывая, что вы используете PHP, мое основное предложение — взглянуть и использовать какое-то существующее решение, такое как CSRF-протектор которая специально разработана для использования с PHP и должна работать с любой клиентской средой, включая ExtJS. Вероятно, это намного лучше и безопаснее, чем все, что вы можете сделать сами.

ПРИМЕЧАНИЕ: вики проекта теперь содержит две разные страницы со ссылками на скачивание — этот содержит ссылки на устаревшая версия а также этот ссылки на новейшая версия. Обязательно загрузите текущую версию или клон репо!

Я знаю, что ваш вопрос нацелен на решение ExtJS, но оно слишком широкое и содержит некоторые важные детали, необходимые для хорошего ответа. Далее следуют некоторые вещи, которые вам нужно решить, прежде чем вы сможете начать думать о том, «как сделать это в коде» …

Прежде чем я углублюсь в детали, я настоятельно рекомендую проверить следующую страницу для общих соображений при разработке защиты CSRF: Шпаргалка по профилактике межсайтовых запросов (CSRF)

Есть и другие способы защиты от CSRF. Для простоты я буду обсуждать только способ «Токены синхронизатора (CSRF)», описанный на странице, упомянутой выше.

Защита от CSFR с использованием токенов Synchronizer (CSRF) всегда работает следующим образом:

  1. Существует незащищенная (с точки зрения CSRF) страница \ действие \ запрос, которая включает в себя некоторую форму или ссылку действия, которая выполняет защищенное действие (запрос). В вашем примере это страница, которая включает в себя ExtJs APP.MyApp учебный класс. Этот запрос также должен сгенерировать токен CSRF, сохранить его в сеансе (для последующей проверки), а также как-то включить его в сгенерированный ответ
  2. Защищенное действие запрашивается, а токен защиты прикреплен к запросу.
  3. Защищенный запрос на стороне сервера обрабатывает извлечение токена из запроса и проверяет его на соответствие значению, сохраненному в сеансе

Теперь есть еще несколько способов отправки сгенерированных токенов CSRF с сервера на клиент — мета, cookie, скрытое поле (все это упоминается в вашем вопросе). Правильный способ сделать это действительно зависит от вашего приложения и желаемого уровня защиты.

Основные соображения:

  • Как генерируется страница, инициирующая защищенный запрос
  • Какой тип токена вы используете (для сеанса или для запроса)

Приложение Token Generation \ Страница образа жизни

Как описано в пункте 1. выше, токен генерируется только при запросе страницы, инициирующей защищенное действие.

Это хорошо для многостраничного приложения, потому что перед тем, как защищенное действие может быть вызвано, должна быть сгенерирована страница, содержащая форму \ ссылку (и токен). Это означает, что очень легко использовать токены для каждого запроса, и вы можете отправить токен в скрытом поле мета или формы.

В приложении SPA на другой стороне, где исходная страница создается только один раз, и защищенное действие может быть выполнено несколько раз без полного обновления страницы, ваши возможности ограничены. Либо вы должны использовать токен для каждой сессии (см. Ниже), переданный через meta \ header, либо вы должны использовать более сложный механизм для получения нового токена с помощью AJAX каждый раз, прежде чем вызывать защищенное действие. В этом случае лучше использовать cookie, как описано в приведенной выше ссылке в главе «Double Submit Cookie».

Тип токена

Сначала вам нужно решить, будет ли ваш токен для каждого сеанса или для каждого запроса. Токены для каждого запроса генерируются для каждого запроса страницы, инициирующей защищенное действие, и удаляются после его использования (т. Е. Защищенное действие выполняется после успешной проверки токена). Может храниться в поле meta \ header \ hidden. По определению, они также не могут использоваться в приложениях SPA.
Существуют также проблемы с удобством использования, такие как кнопка «назад», приводящая к ложному срабатыванию события безопасности на сервере, если предыдущая страница защищена.

Персональные токены генерируются только один раз.
Это может привести к снижению безопасности, поскольку позволяет повторять атаки, но если ваш сайт безопасен XSS (что и должно быть), это нормально. Токены сеанса проще использовать в приложениях SPA. Может быть передано через мета \ скрытое поле.

Похоже, что текущая версия CSRF-Protector (v0.2.1) не работает с запросами POST, содержащими полезную нагрузку JSON (application/json) — увидеть Эта проблема в трекере ошибок проекта. Чтобы обойти это, убедитесь, что вы всегда POST с Content-type: application/x-www-form-urlencoded,

Для регулярных запросов с использованием Ext.Ajax.request сделать это с помощью params конфиг вместо jsonData (играть на скрипке)

Ext.Ajax.request({
url: 'https://jsonplaceholder.typicode.com/posts/',
method: 'POST',
params: {
"userId": 1,
"id": 1,
"title": "sunt",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et"}
})

Для магазинов убедитесь, что вы настроили писатель с encode: true (увидеть документы) как это (играть на скрипке):

var store = new Ext.data.Store({
model: 'MyApp.model.Post',
storeId: 'postsStore',
autoLoad: true,
autoSync: true,
loading: true,

proxy: {
type: 'rest',

actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},

api: {
create: 'https://jsonplaceholder.typicode.com/posts',
read: 'https://jsonplaceholder.typicode.com/posts',
update: 'https://jsonplaceholder.typicode.com/posts',
destroy: 'https://jsonplaceholder.typicode.com/posts'
},

reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'total',
successProperty: 'success'
},

writer: {
type: 'json',
writeAllFields: true,
encode: true,
rootProperty: 'data'
}
}
});
5

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector