Storing user login/password input in a Greasemonkey script on install

Here is a framework for getting and storing login credentials. The script prompts for the information on the very first run and stores it, encrypted, using GM_setValue().

It also adds two items to the Greasemonkey context menu to allow changing the username or password.

// ==UserScript==
// @name     _Autologin, sensitive info framework
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  http://crypto.stanford.edu/sjcl/sjcl.js
// @grant    GM_getValue
// @grant    GM_setValue
// @grant    GM_registerMenuCommand
// ==/UserScript==

var encKey  = GM_getValue ("encKey",  "");
var usr     = GM_getValue ("lognUsr", "");
var pword   = GM_getValue ("lognPwd", "");

if ( ! encKey) {
    encKey  = prompt (
        'Script key not set for ' + location.hostname + '. Please enter a random string:',
        ''
    );
    GM_setValue ("encKey", encKey);

    usr     = pword = "";   // New key makes prev stored values (if any) unable to decode.
}
usr         = decodeOrPrompt (usr,   "U-name", "lognUsr");
pword       = decodeOrPrompt (pword, "P-word", "lognPwd");


function decodeOrPrompt (targVar, userPrompt, setValVarName) {
    if (targVar) {
        targVar     = unStoreAndDecrypt (targVar);
    }
    else {
        targVar     = prompt (
            userPrompt + ' not set for ' + location.hostname + '. Please enter it now:',
            ''
        );
        GM_setValue (setValVarName, encryptAndStore (targVar) );
    }
    return targVar;
}

function encryptAndStore (clearText) {
    return  JSON.stringify (sjcl.encrypt (encKey, clearText) );
}

function unStoreAndDecrypt (jsonObj) {
    return  sjcl.decrypt (encKey, JSON.parse (jsonObj) );
}

//-- Add menu commands that will allow U and P to be changed.
GM_registerMenuCommand ("Change Username", changeUsername);
GM_registerMenuCommand ("Change Password", changePassword);

function changeUsername () {
    promptAndChangeStoredValue (usr,   "U-name", "lognUsr");
}

function changePassword () {
    promptAndChangeStoredValue (pword, "P-word", "lognPwd");
}

function promptAndChangeStoredValue (targVar, userPrompt, setValVarName) {
    targVar     = prompt (
        'Change ' + userPrompt + ' for ' + location.hostname + ':',
        targVar
    );
    GM_setValue (setValVarName, encryptAndStore (targVar) );
}

// ADD YOUR CODE TO SET THE USERNAME AND PASSWORD ON THE LOGIN PAGE, HERE.

Important:

  1. Logging in with a userscript always carries risk.
  2. This framework greatly reduces that risk, but the storage mechanisms available to Greasemonkey and Tampermonkey are not secure and browser vendors CYA against storing confidential information. If a bad guy gets both your userscript and your browser data, then he can reverse engineer your password. Of course if he has that, he’s most likely pwned one of your machines anyway.
  3. The smart thing to do is to use a password manager like LastPass, KeePass, etc.
  4. The absolute worst thing to do, is to store credentials in a userscript itself. Even a guest can see them then and you will be “hacked”, guaranteed.

Leave a Comment