mulbc / vaultPass

A Chrome extension to leverage Hashicorp Vault as Credential Storage for teams
MIT License
96 stars 38 forks source link

Provide an additional data item for an entry to do a more specific query selector for input #52

Open kbenson opened 3 months ago

kbenson commented 3 months ago

On some sites, vaultPass does not correctly find the username and/or password inputs to add the saved data to.

Provide inputSelector.username and inputSelector.password (or equivalent) vault data items that if present are used (and preferably prioritized) as additional query selectors in the findPasswordInput() and findUsernameNodeIn() functions in content.js. This likely means sending it as an additional item through the fill_creds message sent inthe extension.

Other than continuously adding additional selectors that are attempted for the username, I'm not sure of how to handle sites automatically that don't meet current expectations for what forms a username input can take. Manual copy and paste works, so this isn't a change required to fix the plugin from being non-functional, but it would be a nice quality of life improvement.

Whether to allow this for the password entry is slightly more complex of a problem, as allowing the password to automatically be entered into a non-password type input and have it visible may be a security regression not worth doing. Even so, I think the username field is in my experience the one more likely to need this help, so not supporting the password input in this way doesn't negate the usefulness of this suggestion entirely.

mulbc commented 3 months ago

Thanks for your suggestion - can you provide a couple of examples where VaultPass currently does not work correctly?

kbenson commented 3 months ago

Sorry, meant to reply sooner. Here's one example, which is from VMware's vrealize product. It actually automatically sets the authentication type dropdown as the username and leaves the username blank.

<div id="loginForm" class="login-group">
            <div id="authField"><div class="x-field x-form-item x-form-item-default x-form-type-text x-field-default x-form-item-no-label x-border-box" role="presentation" id="authSelector"><label id="authSelector-labelEl" data-ref="labelEl" class="x-form-item-label x-form-item-label-default   x-unselectable" style="padding-right:5px;width:105px;" for="authSelector-inputEl"><span class="x-form-item-label-inner x-form-item-label-inner-default" style="width:100px"><span id="authSelector-labelTextEl" data-ref="labelTextEl" class="x-form-item-label-text">Authentication Source:</span></span></label><div id="authSelector-bodyEl" data-ref="bodyEl" role="presentation" class="x-form-item-body x-form-item-body-default x-form-text-field-body x-form-text-field-body-default  "><div id="authSelector-triggerWrap" data-ref="triggerWrap" role="presentation" class="x-form-trigger-wrap x-form-trigger-wrap-default"><div id="authSelector-inputWrap" data-ref="inputWrap" role="presentation" class="x-form-text-wrap x-form-text-wrap-default"><input id="authSelector-inputEl" data-ref="inputEl" type="text" size="1" name="authSelector-inputEl" readonly="readonly" aria-hidden="false" aria-disabled="false" role="combobox" aria-haspopup="true" aria-expanded="false" aria-owns="authSelector-inputEl authSelector-picker-listEl" aria-autocomplete="list" aria-invalid="false" aria-readonly="true" aria-describedby="authSelector-ariaStatusEl" aria-required="false" class="x-form-field x-form-text x-form-text-default " autocomplete="off" data-componentid="authSelector"></div><div id="authSelector-trigger-picker" class="x-form-trigger x-form-trigger-default x-form-arrow-trigger x-form-arrow-trigger-default " role="presentation"></div></div><span id="authSelector-ariaStatusEl" data-ref="ariaStatusEl" aria-hidden="true" class="x-hidden-offsets"></span><span id="authSelector-ariaErrorEl" data-ref="ariaErrorEl" aria-hidden="true" aria-live="assertive" class="x-hidden-clip"></span></div></div></div>
            <div class="username" id="userNameField"><div class="x-field x-form-item x-form-item-default x-form-type-text x-field-default x-form-item-no-label x-border-box" style="width:100%;" role="presentation" id="userName"><label id="userName-labelEl" data-ref="labelEl" class="x-form-item-label x-form-item-label-default   x-unselectable" style="padding-right:5px;width:105px;" for="userName-inputEl"><span class="x-form-item-label-inner x-form-item-label-inner-default" style="width:100px"><span id="userName-labelTextEl" data-ref="labelTextEl" class="x-form-item-label-text"></span></span></label><div id="userName-bodyEl" data-ref="bodyEl" role="presentation" class="x-form-item-body x-form-item-body-default x-form-text-field-body x-form-text-field-body-default  "><div id="userName-triggerWrap" data-ref="triggerWrap" role="presentation" class="x-form-trigger-wrap x-form-trigger-wrap-default"><div id="userName-inputWrap" data-ref="inputWrap" role="presentation" class="x-form-text-wrap x-form-text-wrap-default"><input id="userName-inputEl" data-ref="inputEl" type="text" size="1" name="userName-inputEl" placeholder="User name" aria-hidden="false" aria-disabled="false" role="textbox" aria-invalid="false" aria-readonly="false" aria-describedby="userName-ariaStatusEl" aria-required="false" class="x-form-field x-form-empty-field x-form-empty-field-default x-form-text x-form-text-default " autocomplete="off" data-componentid="userName"></div></div><span id="userName-ariaStatusEl" data-ref="ariaStatusEl" aria-hidden="true" class="x-hidden-offsets"></span><span id="userName-ariaErrorEl" data-ref="ariaErrorEl" aria-hidden="true" aria-live="assertive" class="x-hidden-clip"></span></div></div></div>
            <div class="password" id="passwordField"><div class="x-field x-form-item x-form-item-default x-form-type-password x-field-default x-form-item-no-label x-border-box" style="width:100%;" role="presentation" id="password"><label id="password-labelEl" data-ref="labelEl" class="x-form-item-label x-form-item-label-default   x-unselectable" style="padding-right:5px;width:105px;" for="password-inputEl"><span class="x-form-item-label-inner x-form-item-label-inner-default" style="width:100px"><span id="password-labelTextEl" data-ref="labelTextEl" class="x-form-item-label-text"></span></span></label><div id="password-bodyEl" data-ref="bodyEl" role="presentation" class="x-form-item-body x-form-item-body-default x-form-text-field-body x-form-text-field-body-default  "><div id="password-triggerWrap" data-ref="triggerWrap" role="presentation" class="x-form-trigger-wrap x-form-trigger-wrap-default"><div id="password-inputWrap" data-ref="inputWrap" role="presentation" class="x-form-text-wrap x-form-text-wrap-default"><input id="password-inputEl" data-ref="inputEl" type="password" size="1" name="password-inputEl" placeholder="Password" aria-hidden="false" aria-disabled="false" role="textbox" aria-invalid="false" aria-readonly="false" aria-describedby="password-ariaStatusEl" aria-required="false" class="x-form-field x-form-empty-field x-form-empty-field-default x-form-text x-form-text-default   " autocomplete="off" data-componentid="password"></div></div><span id="password-ariaStatusEl" data-ref="ariaStatusEl" aria-hidden="true" class="x-hidden-offsets"></span><span id="password-ariaErrorEl" data-ref="ariaErrorEl" aria-hidden="true" aria-live="assertive" class="x-hidden-clip"></span></div></div></div>
            <clr-alert style="visibility:hidden" id="errMsgContainer">
                <div id="errMsgWrapper" class="alert ">
                    <div class="alert-items">
                        <clr-alert-item class="alert-item">
                            <div class="alert-icon-wrapper">
                                <clr-icon id="errMsgIcon" class="alert-icon" shape="danger" role="none"><svg version="1.1" class="has-solid " viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" focusable="false" role="img"><path class="clr-i-outline clr-i-outline-path-1" d="M18,6A12,12,0,1,0,30,18,12,12,0,0,0,18,6Zm0,22A10,10,0,1,1,28,18,10,10,0,0,1,18,28Z"></path>
                <path class="clr-i-outline clr-i-outline-path-2" d="M18,20.07a1.3,1.3,0,0,1-1.3-1.3v-6a1.3,1.3,0,1,1,2.6,0v6A1.3,1.3,0,0,1,18,20.07Z"></path>
                <circle class="clr-i-outline clr-i-outline-path-3" cx="17.95" cy="23.02" r="1.5"></circle>
                <path class="clr-i-solid clr-i-solid-path-1" d="M18,6A12,12,0,1,0,30,18,12,12,0,0,0,18,6Zm-1.49,6a1.49,1.49,0,0,1,3,0v6.89a1.49,1.49,0,1,1-3,0ZM18,25.5a1.72,1.72,0,1,1,1.72-1.72A1.72,1.72,0,0,1,18,25.5Z"></path></svg></clr-icon>
                            </div>
                            <span id="errorMsg" class="alert-text"></span>
                        </clr-alert-item>
                    </div>
                </div>
            </clr-alert>
        <a class="x-btn btn btn-primary btn-block x-unselectable x-btn--small x-border-box" hidefocus="on" unselectable="on" role="button" aria-hidden="false" aria-disabled="false" id="loginBtn" tabindex="0" data-componentid="loginBtn"><span id="loginBtn-btnWrap" data-ref="btnWrap" role="presentation" unselectable="on" style="" class="x-btn-wrap x-btn-wrap--small "><span id="loginBtn-btnEl" data-ref="btnEl" role="presentation" unselectable="on" style="" class="x-btn-button x-btn-button--small x-btn-text    x-btn-button-center "><span id="loginBtn-btnIconEl" data-ref="btnIconEl" role="presentation" unselectable="on" class="x-btn-icon-el x-btn-icon-el--small  " style=""></span><span id="loginBtn-btnInnerEl" data-ref="btnInnerEl" unselectable="on" class="x-btn-inner x-btn-inner--small">LOG IN</span></span></span></a></div>

It looks like the following when vaultPass is not filling the fields.

image

I'll try to update with more as I encounter them, I only hit some of these systems every few weeks or longer.

Note: I'm not against doing this myself and providing a PR if I end up with time, I submitted an issue so it was tracked in some way and in the (unfortunately likely) case that I don't get time and get around to it, it's not entirely lost.

mulbc commented 3 months ago

Thanks for replying anyways! I don't have access to vRealize right now... but I could check it out for my vCenter lab... maybe the login is the same style? At the same time, I would highly appreciate a (good) PR ;)