Как я могу получить файл cookie HttpOnly с помощью пользовательского скрипта?

Корпоративный веб-сайт, к которому я часто обращаюсь, использует базовую аутентификацию, которая запускает диалог пользователя/пароля. Мой менеджер паролей (LastPass) не может его заполнить. Итак, я хочу использовать пользовательский скрипт для ввода формы входа, которую может заполнить LastPass.

Чтобы протестировать внедренную функцию формы onsubmit, в веб-консоли Firefox я запустил:

var request = new XMLHttpRequest();
request.open("GET", "https://someweb.com/login.do", false);
request.setRequestHeader("Authorization", "Basic " + btoa(USERNAME + ":" + PASSWORD));
request.setRequestHeader("User-Agent", navigator.userAgent);
request.setRequestHeader("Cookie", "JSESSIONID=*****");
request.send();

USERNAME и PASSWORD будут извлечены из заполненной формы.

Все работает так, как ожидалось, за исключением того, что мне нужно получить файл cookie сеанса JSESSIONID. Файл cookie отправляется с главной домашней страницы перед тем, как перейти к якорю входа, и я могу получить его в Firefox из Инспектора хранилища или просмотрев заголовки запросов на вкладке «Сеть» в инструментах разработчика. Поскольку инспектор хранилища помечает этот файл cookie как HttpOnly, я не могу получить его с помощью document.cookie.

Тривиальный

curl -I 'https://someweb.com/home.do'     

выводит файл cookie JSESSIONID, поэтому я попытался получить домашнюю страницу, выпустив файл cookie:

var request = new XMLHttpRequest();
request.open("GET", "https://someweb.com/login.do/home.do", false);
request.send();
request.getAllResponseHeaders();

но файл cookie все еще не отображается.

Я пробовал использовать GM_xmlHttpRequest с различными менеджерами пользовательских скриптов и получать responseHeaders из объекта Response, но файла cookie JSSESSIONID там не было.

Я знаю, что HttpOnly файлы cookie не подвергаются воздействию JavaScript, чтобы избежать внедрения вредоносных скриптов. Однако это не должно быть так для пользовательских скриптов, которые запускаются расширениями (поэтому браузер им доверяет), и должен быть способ заполнить мои учетные данные без ручного копирования и вставки.


person antonio    schedule 16.01.2021    source источник
comment
@double-beep: Tampermonkey — это закрытый источник, которого я бы предпочел избегать. На данный момент лучший вариант — создать простое расширение.   -  person antonio    schedule 27.01.2021


Ответы (2)


Да, это возможно, но только в Tampermonkey Beta с использованием GM_cookie — см. эта проблема. Violentmonkey и Greasemonkey не поддерживает ничего подобного.

В вашем случае это должно быть примерно так:

// ==UserScript==
// @name        Stack Overflow Question 65749907
// @version     0.1
// @include     https://someweb.com/login.do
// @run-at      document-end
// @grant       GM_cookie
// ==/UserScript==

(function() {
  'use strict';

  const cookieName = 'JSESSIONID';
  const urlToFetch = 'https://someweb.com/login.do'
  GM_cookie.list({ url: urlToFetch, name: cookieName }, (cookie, error) => {
    if (!error) console.log(cookie[0]);
    else console.error(error);
  });
})();

Это ищет файлы cookie с именами cookieName в urlToFetch. Обратите внимание, что urlToFetch должно быть в @match/@include, иначе вы получите ошибку!

person double-beep    schedule 16.01.2021

Если ваш бэкэнд внедрил cookie, все, что вам нужно сделать, это установить в вашем запросе withCredentials: true:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

https://developer.mozilla.org/en/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

person Ernesto    schedule 16.01.2021
comment
Я пытался, но хотя вывод curl -I 'HOMEPAGE' включает строку Set-Cookie: JSESSIONID=..., если выполнить ваш код с моим URL и добавить xhr.getAllResponseHeaders(), я просто получаю: "connection: close content-encoding: gzip content-type: text/html;charset=UTF-8 date: Sat, 16 Jan 2021 14:33:22 GMT server: Apache/2.4.10 (Debian) transfer-encoding: chunked vary: Accept-Encoding " - person antonio; 16.01.2021