Почему файлы cookie и заголовки файлов cookie не могут быть установлены при создании xmlhttprequest с использованием setRequestHeader?
Мне было интересно, почему нельзя установить заголовки cookie, используя setRequestHeader. Есть ли какая-то конкретная причина или просто они добавляются самим браузером, поэтому эти заголовки отключены? Есть ли проблемы с безопасностью?
--Редактировать
Я работаю над node.js и использовал xmlhttprequest
модуль. Ниже приведен тестовый код:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', "key=value");
xhr.send(null);
Здесь мне нужно установить cookie-заголовок как node.js' xmlhttprequest
явно не добавляет cookie-заголовок (как это делают браузеры). При попытке сделать это, xmlhttprequest
дает ошибкуRefused to set unsafe header
".
Хотя я нашел патч и успешно смог отправить cookie-заголовок. Но было интересно, почему это было отключено, чтобы установить cookie-заголовок? Где бы я ни читал, я обнаружил, что это требуется для обеспечения целостности данных и безопасности, но о том, какую безопасность можно нарушить в этом случае, не упоминается нигде. Я хочу оценить, является ли эта проблема целостности данных допустимой и для приложения node.js, если я пойду с моим патчем.
8 ответов
Я уверен, что вы бы прошли рабочий проект и нашли
Вышеуказанные заголовки контролируются пользовательским агентом, чтобы позволить ему управлять этими аспектами транспорта.
Во-первых, нам нужно понять, что это стандарты, работающие в качестве руководящих принципов для взаимодействия функций между различными браузерами. Это не является обязательным для браузера, и, следовательно, браузеры по разным причинам придерживаются этого уровня.
Во-вторых, технически говоря, вы можете эмулировать пользовательский агент, обращаться с вашей программой как с браузером и очень хорошо устанавливать эти значения в соответствии с упомянутыми стандартами.
Наконец, намерение запретить перезапись заголовков или настройку заголовков для определенных полей, таких как Content-Length
, Cookie
этос secure design approach
, Это препятствует или, по крайней мере, пытается препятствовать контрабанде HTTP-запросов.
Вы можете отключить это поведение:
var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...
Как хорошо известно, для браузеров необходимо тщательно управлять файлами cookie (среди прочих свойств), чтобы не допустить кражи пользовательских сеансов (или других данных) третьими лицами. Это проблема браузеров и неконтролируемого характера посещения веб-сайта, на котором работает произвольный Javascript.
Конечно, этот риск выполнения произвольного кода является низким или не рискованным для node.js, так как вы запускаете только тот сценарий, который вы написали, который может выполнять другой код, который вы запланировали.
Если вы посмотрите на исходный код для XMLDttpRequest.js DriverDan, вы найдете:
// These headers are not user setable.
// The following are allowed but banned in the spec:
// * user-agent
var forbiddenRequestHeaders = [
"accept-charset",
"accept-encoding",
"access-control-request-headers",
"access-control-request-method",
"connection",
"content-length",
"content-transfer-encoding",
"cookie",
"cookie2",
"date",
"expect",
"host",
"keep-alive",
"origin",
"referer",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"via" ];
Это ответит на ваш конкретный вопрос о том, почему ограничение особенно применимо к этому сценарию, используемому для node.js - кодировщик следовал спецификации (настолько близко, насколько это возможно), несмотря на то, что это чувство, вероятно, не было обязательной мерой безопасности в node.js. Тем не менее этот уровень безопасности по умолчанию легко изменяется.
Как указал Робертклеп, вы можете отключить эту меру предосторожности по умолчанию, используя setDisableHeaderCheck
метод. И да, этот последний пункт действительно отвечает или значительно способствует ответу на ваш вопрос, потому что в своем вопросе вы заявили:
I have found a patch and successfully able to send the cookie-header
Теперь мы обнаружили, что вам не нужен этот патч.
Удачи!
Да, это требуется для целостности данных и безопасности. Чтобы понять это, вы должны понимать роль файлов cookie в методах HTTP-запросов.
Файлы cookie важны для идентификации пользователя, браузера, соединения и т. Д. И хранятся в веб-браузере. JavaScript позволяет вам управлять файлами cookie, но не всеми файлами cookie в браузере. Посмотрите файлы cookie HTTP, они устанавливаются только браузером, поэтому пользователь не может использовать их неправильно (через JavaScript).
В поддерживаемом браузере cookie-файл сеанса HttpOnly будет использоваться только при передаче запросов HTTP (или HTTPS), тем самым ограничивая доступ из других не HTTP-API (таких как JavaScript).
Когда вы отправляете xmlhttprequest, он читает файлы HttpOnly и отправляет их на сервер через Cookie
заголовок. Теперь, если вы делаете xhr.setRequestHeader('Cookie', "key=value");
вы пытаетесь изменить файлы cookie, отправленные на сервер. setRequestHeader
добавит дополнительно key=value
это может поставить под угрозу целостность отправленных файлов cookie.
Они используются сервером для аутентификации пользователя (сеанс, электронная почта или любая учетная запись). По сути, это позволяет серверу предотвращать неправильное использование файлов cookie для получения доступа к серверу.
В документации упоминается, что это сделано для защиты целостности данных. http://www.w3.org/TR/XMLHttpRequest/
Вышеуказанные заголовки контролируются пользовательским агентом, чтобы позволить ему управлять этими аспектами транспорта. Это гарантирует целостность данных в некоторой степени. Имена заголовков, начинающиеся с Sec, не могут быть установлены так, чтобы позволять создавать новые заголовки, которые гарантированно не приходят из XMLHttpRequest.
Мне удалось решить эту проблему с помощью следующего Gist:
https://gist.github.com/killmenot/9976859
Оригинальная идея взята отсюда:
https://gist.github.com/jfromaniello/4087861
Я столкнулся с несколькими проблемами:
- Source Gist устарел и не работает для меня. Например, "запрос" lib API был изменен.
- Я мог бы работать с библиотекой "xmlhttprequest" для socket.io-client и не устанавливать ее на одном уровне с socket.io-client.
- Оригинальный "socket.io-client" (0.9.16) использует "xmlhttprequest" (1.4.2), который не поддерживает метод "setDisableHeaderCheck" (а 1.6.0 поддерживает). Итак, я делаю вилку и использую ее https://github.com/intspirit/socket.io-client/tree/0.9.16+20140408120400
socket.io-client (1.0.0-pre) использует engine.io-client, который использует правильную версию xmlhttprequest. Я предполагаю, что в будущем я буду использовать версию 1.0.0 вместо своего форка, указать транспорт "xhr-polling" и смоделировать XMLHttpRequest, как это делает исходная сущность.
добавлять
xhr._restrictedHeaders.cookie = false
до
xhr.setRequestHeader('Cookie', "key=value");
но это плохой способ, я не рекомендую его использовать.
Я считаю, что эти ответы недостаточно полны.
Как и все ответы, вы не можете использовать xhr.setRequestHeader('Cookie', "key=value");
для отправки любых данных из-за целостности безопасности (браузер не может определить, является ли добавляемое вами значение настоящим файлом cookie).
Ожидаемый способ работы с этим специальным заголовком - позволить клиентскому браузеру автоматически принимать все файлы cookie, связанные с запрашиваемым вами сайтом, и помещать их в заголовок 'Cookie', вам не нужно ничего делать, если ваши файлы cookie существуют в вашем браузере, они будут отправлены.
... И если вам интересно, все файлы cookie, хранящиеся в вашем браузере, должны храниться / обновляться каждый раз, когда ответ от запрашиваемого вами сервера отправляет вам Set-Cookie
заголовок. Поэтому нет смысла добавлять заголовок Set-Cookie в запрос, потому что это заголовок, зарезервированный только для ответов, и не нужно добавлять заголовок Cookie в ваши запросы, потому что ваш браузер уже делает это.