-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PM-1397] Display a warning when a user attempts to auto-fill an iframe #4994
[PM-1397] Display a warning when a user attempts to auto-fill an iframe #4994
Conversation
Try/catch does not work consistently around the call to confirm() This reverts commit 3046419.
@@ -245,7 +245,7 @@ export abstract class StateService<T extends Account = Account> { | |||
setEntityType: (value: string, options?: StorageOptions) => Promise<void>; | |||
getEnvironmentUrls: (options?: StorageOptions) => Promise<EnvironmentUrls>; | |||
setEnvironmentUrls: (value: EnvironmentUrls, options?: StorageOptions) => Promise<void>; | |||
getEquivalentDomains: (options?: StorageOptions) => Promise<any>; | |||
getEquivalentDomains: (options?: StorageOptions) => Promise<string[][]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add a bit of typing each time I use it 😇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a little treat to myself
this.logService.info("Auto-fill on page load was blocked due to an untrusted iframe."); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had thought we were going to display a popup to the user. This would fail silently to most people.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only hit for autofill on page load case, which I agree that we should fail on.
options.allowUntrustedIframe != undefined && | ||
!options.allowUntrustedIframe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This untrusted iframe stuff seems very weird if there's no user override. It feels like we're excluding command autofill from some legitimate safety measures
Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com>
this.logService.debug("iframe at " + pageUrl + " trusted because it matches a saved URI"); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
// TODO should this be put in a common place (Utils maybe?) to be used both here and by CipherService? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need to recreate the domain matching rules to get access to them here? :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're currently buried in a callback in cipherService.getAllDecryptedForUrl
, so they're not currently accessible. My thought was to extract it to its own public method for reuse, if there are no changes to the code itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this is being treated as a hotfix so I understand the reluctance to refactor unrelated existing methods.
EDIT: and I think that is correct here - I'm OK with the copy + paste personally, provided there's a follow up ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not see another way, besides spending a lot more time than is needed for a hotfix kind of item.
var acceptedIframeWarning = confirm("Are you sure you want to auto-fill your credentials on " + | ||
window.location.hostname + "? Choose OK to auto-fill, or Cancel to stop."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to trace context here, does this display the iframe source's hostname?
Is this display once per iframe in the page?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's definitely the iframe's source, but I haven't been able to test multiple untrusted iframes, yet. I think it'll call once per untrusted iframe since doAutofill
is called once per content script (per iframe message response)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that:
it'll call once per untrusted iframe since doAutofill is called once per content script (per iframe message response)
Although I haven't tested it.
But, it'll only call once per untrusted iframe that we're going to autofill. If an iframe doesn't have a login form to be filled, no fillScript is sent back to the content script for those pageDetails.
So it is possible that you get multiple alerts, but only if you have multiple untrusted iframes with login forms in them. Which I don't think is very common, and if it does happen, the risk is still there to warn the user about. The UX could be improved, but I think that's OK to be out of scope here given that it should be an edge case. (although obviously I am making some assumptions here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will display once per iframe, but if there are multiple it will cancel autofill for all but only show the last one.
} | ||
|
||
// TODO should this be put in a common place (Utils maybe?) to be used both here and by CipherService? | ||
private uriMatches(uri: LoginUriView, url: string): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a lift & shift from CipherService?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relevant discussion: #4994 (comment)
…fill-on-a-site-with-an-iframe' of https://github.com/bitwarden/clients into PM-1397-display-a-warning-when-a-user-attempts-to-auto-fill-on-a-site-with-an-iframe
fillScript.untrustedIframe = | ||
pageDetails.url !== options.tabUrl && // If page URL matches tab URL, we're not in an iframe | ||
!this.iframeUrlMatches(pageDetails.url, options.cipher, options.defaultUriMatch); | ||
inIframe && !this.iframeUrlMatches(pageDetails.url, options.cipher, options.defaultUriMatch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this inFrame
check out of the madness of the other method 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thank you @eliykat !
…me (#4994) * add settingsService.getEquivalentDomains * check that an iframe URL matches cipher.login.uris before autofilling * disable autofill on page load if it doesn't match * show a warning to the user on regular autofill if it doesn't match --------- Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com> Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com> (cherry picked from commit 0d85bdc)
Type of change
Objective
Warn the user before autofilling into an untrusted iframe.
Code changes
autofill.js
.tabUrl
property which was incorrectly set byautofill.js
(it would always be the url of the page, which in an iframe just gives you the src of the iframe rather than the outer tab). This made terminology confusing when we want to distinguish the url of the tab and the url of an iframe. It appeared to be unused so I deleted it.Everything else is updating types/interfaces/parameters, adding tests, and adding documentation comments where it was helpful.
Screenshots
Before you submit