Подтвердить что ты не робот

Почему файлы cookie и заголовки set-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, если я иду с моим патчем.

4b9b3361

Ответ 1

Я уверен, что вы выполнили рабочий проект и нашли

Указанные выше заголовки управляются пользовательским агентом, чтобы он контролировал эти аспекты транспорта.

Во-первых, нам нужно понять, что это стандарты, работающие в качестве руководства по функциональной совместимости функций между разными браузерами. Это не предусмотрено для браузера, и, следовательно, браузеры имеют разный уровень соблюдения этого стандарта по разным причинам.

Во-вторых, технически вы можете эмулировать пользовательский агент, рассматривать вашу программу как браузер и очень хорошо устанавливать эти значения в соответствии с указанными стандартами.

Наконец, намерение запретить переписывание заголовков или настройку заголовков для определенных полей, таких как Content-Length, Cookie ethos secure design approach. Это должно препятствовать или, по крайней мере, пытаться препятствовать HTTP-запрос контрабанды.

Ответ 2

Вы можете отключить это поведение:

var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...

Ответ 3

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

Конечно, этот риск произвольного выполнения кода является либо низким, либо не подверженным риску для node.js, поскольку вы используете только script, который вы написали, который может запускать другой код, который вы планировали.

Если вы посмотрите на исходный код для driverdan XMLHttpRequest.js, вы найдете:

 // 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"   ];

Это ответ на ваш конкретный вопрос, почему ограничение, в частности, относится к этому script, используемому для node.js - кодер следовал спецификации (насколько это возможно), несмотря на то, что это, вероятно, не было обязательным меры предосторожности в node.js. Тем не менее этот уровень безопасности по умолчанию легко модифицируется.

Как указывал robertklep, вы можете отключить эту предосторожность по умолчанию, используя метод setDisableHeaderCheck. И да, этот последний момент действительно отвечает или вносит существенный вклад в ответ на ваш вопрос, потому что в вашем вопросе вы заявили:

I have found a patch and successfully able to send the cookie-header

Теперь мы обнаружили, что вам не нужен этот патч.

Удачи!

Ответ 4

Да, это необходимо для целостности и безопасности данных. Чтобы понять это, вы должны понимать роль куки файлов в методах HTTP-запросов.

Файлы cookie важны для идентификации пользователя, браузера, подключения и т.д. и хранятся в веб-браузере. JavaScript позволяет вам манипулировать файлами cookie, но не все файлы cookie в браузере. См. HTTP файлы cookie, они устанавливаются только браузером, поэтому пользователь не может злоупотреблять им (через JavaScript).

В поддерживаемом браузере будет использоваться только cookie сеанса HttpOnly при передаче запросов HTTP (или HTTPS), что ограничивает доступ от других API-интерфейсов, отличных от HTTP (например, JavaScript).

Когда вы отправляете xmlhttprequest, он читает куки HttpOnly и отправляет сервер через заголовок Cookie. Теперь, если вы выполняете xhr.setRequestHeader('Cookie', "key=value");, вы пытаетесь вмешаться в файлы cookie, отправленные на сервер. setRequestHeader добавит дополнительные key=value, которые могут нарушить целостность отправленных файлов cookie.

Они используются сервером для аутентификации пользователя (сеанса, учетной записи электронной почты или любой учетной записи). Это, по сути, позволяет серверу предотвращать неправильное использование файлов cookie для доступа к серверу.

Ответ 5

В документации упоминается, что это сделано для защиты целостности данных. http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method

Указанные выше заголовки управляются пользовательским агентом, чтобы он контролировал эти аспекты транспорта. Это гарантирует целостность данных для некоторых степени. Заголовки заголовков, начинающиеся с Sec, не могут быть установлены в разрешить чеканить новые заголовки, гарантированные не XMLHttpRequest.

Ответ 6

Я смог решить эту проблему, используя следующий Gist:
https://gist.github.com/killmenot/9976859

Исходная идея взята здесь:
https://gist.github.com/jfromaniello/4087861

Я столкнулся с несколькими проблемами:

  • Источник Gist устарел и не работает для меня. Например, был изменен API-интерфейс запроса request.
  • Я мог бы работать с библиотекой socket.io-client "xmlhttprequest" и не устанавливайте на том же уровне с 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-poll" и mock XMLHttpRequest, как это делает оригинальный текст.

Ответ 7

Я думаю, что эти ответы недостаточно полны.

Как и во всех ответах, вы не можете использовать xhr.setRequestHeader('Cookie', "key=value"); для отправки каких-либо данных из-за целостности безопасности (браузер не может определить, является ли добавляемое вами значение настоящим cookie).

Ожидаемый способ работы с этим специальным заголовком - позволить клиентскому браузеру автоматически принимать все файлы cookie, относящиеся к запрашиваемому вами сайту, и помещать их в заголовок "Cookie", вам больше ничего не нужно делать, если ваши файлы cookie существуют в вашем браузере, они будут отправлены.

... И если вам интересно, все куки, хранящиеся в вашем браузере, должны сохраняться/обновляться каждый раз, когда ответ от запрашиваемого вами сервера отправляет вам обратно заголовок Set-Cookie. Поэтому нет смысла добавлять заголовок "Set-Cookie" в запрос, потому что это заголовок, зарезервированный только для ответов, и нет необходимости добавлять заголовок "Cookie" в ваши запросы, потому что ваш браузер уже делает это.