antonio
antonio

Reputation: 11130

How can I access and possibly modify a cookie with a userscript?

A corporate website, which I happen to access often, uses a Basic Auth which triggers a user/pass dialogue. My password manager (LastPass) is unable to fill it. So I want to use a userscript to inject a login form, which is fillable by LastPass.

To test the injected form onsubmit function, in the Firefox Web Console I ran:

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 and PASSWORD would be retrieved from the filled form.

Everything works as expected, except that I have to retrieve the JSESSIONID session cookie. The cookie is sent from the main home page before following the login anchor and I can retrieve it in Firefox from the Storage Inspector or by examining request headers in the Network tab from the Developer Tools. Since the Storage Inspector labels this cookie as HttpOnly, I cannot retrieve it with document.cookie.

A trivial

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

outputs the JSESSIONID cookie, so I tried to fetch the home page releasing the cookie:

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

but the cookie is still not shown.

I've tried using GM_xmlHttpRequest with various userscript managers and getting responseHeaders from the Response object, but the JSSESSIONID cookie wasn't there.

I know HttpOnly cookies are not exposed to JavaScript to avoid the injection of malicious scripts. However, it shouldn't be so for userscripts, which are run by extensions (therefore trusted by the browser) and there should be a way to fill my credentials without a manual copy and paste.

Upvotes: 2

Views: 4958

Answers (2)

double-beep
double-beep

Reputation: 5520

This is now possible in Tampermonkey with GM_cookie (see: docs with types and examples). To enable access to HttpOnly cookies, follow these instructions. Violentmonkey and Greasemonkey do not support anything similar.

You should use GM_cookie.list(details, callback):

// ==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);
        }
    );
})();

This searches for a cookie names cookieName in urlToFetch. You can only access cookies on the URLs the script is allowed to run - otherwise, you'll get an error.

To set or delete a cookie, you should use GM_cookie.set() or GM_cookie.delete() respectively.

Upvotes: 3

Ernesto
Ernesto

Reputation: 4272

If yow backend injected the cookie all you need to do is on yow request set the 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

Upvotes: 0

Related Questions