Skip to content
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

Conversation

eliykat
Copy link
Member

@eliykat eliykat commented Mar 14, 2023

Type of change

- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

Warn the user before autofilling into an untrusted iframe.

Code changes

  • autofillService - decide whether an iframe is "trusted" and include this result in the fillScript. FillScripts targeting an untrusted iframe can be discarded (used for autofill on page load) or used but this will be picked up by autofill.js.
  • autofill.js - display an alert to the user before filling an untrusted iframe
  • settingsService - add a method to get equivalent domains for a URL
  • autofillPageDetails - this had a tabUrl property which was incorrectly set by autofill.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

  • Please add unit tests where it makes sense to do so (encouraged but not required)
  • If this change requires a documentation update - notify the documentation team
  • If this change has particular deployment requirements - notify the DevOps team
  • Ensure that all UI additions follow WCAG AA requirements

@eliykat eliykat requested a review from differsthecat March 14, 2023 05:00
@eliykat eliykat requested a review from a team as a code owner March 14, 2023 05:00
@github-actions github-actions bot added the needs-qa Marks a PR as requiring QA approval label Mar 14, 2023
@@ -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[][]>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

Copy link
Member Author

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 😇

Copy link
Member Author

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

Comment on lines +130 to +131
this.logService.info("Auto-fill on page load was blocked due to an untrusted iframe.");
return;
Copy link
Member

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.

Copy link
Member

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.

Comment on lines +127 to +128
options.allowUntrustedIframe != undefined &&
!options.allowUntrustedIframe
Copy link
Member

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?
Copy link
Member

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? :(

Copy link
Member Author

@eliykat eliykat Mar 14, 2023

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.

Copy link
Member Author

@eliykat eliykat Mar 14, 2023

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.

Copy link
Member

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.

Comment on lines 918 to 919
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.");
Copy link
Member

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?

Copy link
Member

@MGibson1 MGibson1 Mar 14, 2023

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)

Copy link
Member Author

@eliykat eliykat Mar 14, 2023

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)

Copy link
Member

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.

apps/browser/src/autofill/content/autofill.js Outdated Show resolved Hide resolved
apps/browser/src/autofill/services/autofill.service.ts Outdated Show resolved Hide resolved
}

// 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 {
Copy link
Member Author

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant discussion: #4994 (comment)

apps/browser/src/autofill/services/autofill.service.ts Outdated Show resolved Hide resolved
apps/browser/src/autofill/services/autofill.service.ts Outdated Show resolved Hide resolved
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);
Copy link
Member

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 💯

Copy link
Member

@differsthecat differsthecat left a 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 !

@eliykat eliykat merged commit 0d85bdc into master Mar 15, 2023
@eliykat eliykat deleted the PM-1397-display-a-warning-when-a-user-attempts-to-auto-fill-on-a-site-with-an-iframe branch March 15, 2023 01:19
eliykat added a commit that referenced this pull request Mar 15, 2023
…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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-qa Marks a PR as requiring QA approval
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants