Отключить History API
На беке проверяется реферер, который указан в ajax запросе.
На фронте посетители могут исполнять JS. Я заметил, что на фронте можно сделать history.pushState() и обратиться к серверу с нужным реферером. Я знаю, что на этой странице History никогда не понадобится.
History = function() {};
history.__proto__.pushState = function() {};
history.__proto__.replaceState = function() {};
history.__proto__.back = function() {};
history.__proto__.forward = function() {};
history.__proto__.go = function() {};
После этого кода History API восстановить не получится? |
Клиенту доверять нельзя. Если у сторонних скриптов есть доступ к вашему домену - вам можно только смириться.
|
Aetae, тема не посвящена защите от XSS :) Но я пока уверен, что мы нашли защиту от любого способа атаки.
А входные данные очень простые: 1) есть страница /project/123, вы можете разместить на ней скрипт. 2) есть страница /account, с этой страницы админ может выполнить запрос по адресу /del с параметром {id: 123} Вопрос: что сделает ваш скрипт, чтобы я (админ) при посещении страницы /project/123 случайно её удалил? Сабж актуален. History API можно восстановить? |
document.body.append( document.createElement('iframe') );
history.__proto__.pushState = window.frames[0].history.pushState;
|
Вариантов куча на самом деле. Под чужие скрипты - только заводить отдельный домен.
|
Вообще, стандартная защита - сессионные токены: https://learn.javascript.ru/csrf
А свои велосипеды лучше не изобретать если не являешься эскпертом в данной области. |
Белый шум, сессионный токен есть на другой странице.
Но с помощью JS можно получить код другой страницы и спарсить хеш :) Против этого сервер отфутболивает все запросы, которые приходят от страницы с пользовательским скриптом. Судя по всему, есть только один способ подменить referer в запросах. Против вашего кода я попробовал сделать так:
function overrideContentAccess(iface) {
var contentWindowDescriptor = Object.getOwnPropertyDescriptor(iface.prototype, "contentWindow");
// По-видимому, в HTMLObjectElement.prototype.contentWindow не существует
// в более ранних версиях Chrome, таких как 42.
if (!contentWindowDescriptor) {
return;
}
var getContentWindow = Function.prototype.call.bind(contentWindowDescriptor.get);
contentWindowDescriptor.get = function () {
return false;
};
Object.defineProperty(iface.prototype, "contentWindow", contentWindowDescriptor);
}
var interfaces = [HTMLFrameElement, HTMLIFrameElement, HTMLObjectElement];
for (var i = 0; i < interfaces.length; i++) {
overrideContentAccess(interfaces[i]);
}
var iframe = document.createElement('iframe');
document.body.append( iframe );
console.log('iframeWindow:', iframe.contentWindow);
Но frames[0] по прежнему возвращает объект. |
brizing,
Это как можно спарсить код другой вкладки? Пример покажите, а то я не в курсах. |
Белый шум,
$.get('/account', function(data) {
console.log(data);
});
|
Я же не о вкладке говорю.
|
| Часовой пояс GMT +3, время: 06:44. |