Skip to content

Commit

Permalink
fix: Pass URLs to PhishingController (#2835)
Browse files Browse the repository at this point in the history
Following MetaMask/metamask-extension#25839
full URLs are required as the argument for
`PhishingController:testOrigin`. This PR makes sure that our calls to
`isOnPhishingList` pass strictly full URLs.
  • Loading branch information
FrederikBolding authored Oct 14, 2024
1 parent 4be3dd3 commit b78d274
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
3,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);

expect(content).toStrictEqual(getJsxElementFromComponent(components));
Expand Down Expand Up @@ -118,7 +118,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
3,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);

expect(content).toStrictEqual(element);
Expand Down Expand Up @@ -239,7 +239,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
3,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);
});

Expand Down Expand Up @@ -289,7 +289,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
3,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);
});

Expand Down Expand Up @@ -708,7 +708,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
5,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);
});

Expand Down Expand Up @@ -774,7 +774,7 @@ describe('SnapInterfaceController', () => {
expect(rootMessenger.call).toHaveBeenNthCalledWith(
5,
'PhishingController:testOrigin',
'foo.bar',
'https://foo.bar/',
);
});

Expand Down
4 changes: 2 additions & 2 deletions packages/snaps-utils/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 99.74,
"functions": 98.92,
"lines": 99.45,
"statements": 96.31
"lines": 99.46,
"statements": 96.32
}
44 changes: 27 additions & 17 deletions packages/snaps-utils/src/ui.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -550,38 +550,41 @@ describe('validateLink', () => {
expect(() => validateLink('mailto:[email protected]', fn, fn)).not.toThrow();

expect(fn).toHaveBeenCalledTimes(2);
expect(fn).toHaveBeenCalledWith('foo.bar');
expect(fn).toHaveBeenCalledWith('bar.com');
expect(fn).toHaveBeenCalledWith('https://foo.bar/');
expect(fn).toHaveBeenCalledWith('https://bar.com');
});

it('passes for a valid list of emails', () => {
const fn = jest.fn().mockReturnValue(false);
const getSnap = jest.fn();

expect(() =>
validateLink('mailto:[email protected],[email protected],[email protected]', fn),
validateLink('mailto:[email protected],[email protected],[email protected]', fn, getSnap),
).not.toThrow();

expect(fn).toHaveBeenCalledTimes(3);
expect(fn).toHaveBeenCalledWith('bar.com');
expect(fn).toHaveBeenCalledWith('baz.com');
expect(fn).toHaveBeenCalledWith('qux.com');
expect(fn).toHaveBeenCalledWith('https://bar.com');
expect(fn).toHaveBeenCalledWith('https://baz.com');
expect(fn).toHaveBeenCalledWith('https://qux.com');
});

it('passes for a valid email with a parameter', () => {
const fn = jest.fn().mockReturnValue(false);
const getSnap = jest.fn();

expect(() =>
validateLink('mailto:[email protected]?subject=Subject', fn),
validateLink('mailto:[email protected]?subject=Subject', fn, getSnap),
).not.toThrow();

expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith('bar.com');
expect(fn).toHaveBeenCalledWith('https://bar.com');
});

it('throws an error for an invalid protocol', () => {
const fn = jest.fn().mockReturnValue(false);
const getSnap = jest.fn();

expect(() => validateLink('http://foo.bar', fn, fn)).toThrow(
expect(() => validateLink('http://foo.bar', fn, getSnap)).toThrow(
'Invalid URL: Protocol must be one of: https:, mailto:, metamask:.',
);

Expand Down Expand Up @@ -620,7 +623,7 @@ describe('validateLink', () => {
).toThrow('Invalid URL: The specified URL is not allowed.');

expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith('test.metamask-phishing.io');
expect(fn).toHaveBeenCalledWith('https://test.metamask-phishing.io/');
});

it('throws an error for a phishing email', () => {
Expand All @@ -631,45 +634,52 @@ describe('validateLink', () => {
).toThrow('Invalid URL: The specified URL is not allowed.');

expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith('test.metamask-phishing.io');
expect(fn).toHaveBeenCalledWith('https://test.metamask-phishing.io');
});

it('throws an error for a phishing email when using multiple emails', () => {
const fn = jest.fn().mockImplementation((email) => {
if (email === 'test.metamask-phishing.io') {
if (email === 'https://test.metamask-phishing.io') {
return true;
}

return false;
});
const getSnap = jest.fn();

expect(() =>
validateLink('mailto:[email protected],[email protected]', fn),
validateLink(
'mailto:[email protected],[email protected]',
fn,
getSnap,
),
).toThrow('Invalid URL: The specified URL is not allowed.');

expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith('test.metamask-phishing.io');
expect(fn).toHaveBeenCalledWith('https://test.metamask-phishing.io');
});

it('throws an error for a phishing email when using parameters', () => {
const fn = jest.fn().mockImplementation((email) => {
if (email === 'test.metamask-phishing.io') {
if (email === 'https://test.metamask-phishing.io') {
return true;
}

return false;
});
const getSnap = jest.fn();

expect(() =>
validateLink(
'mailto:[email protected],[email protected]?subject=Subject',
fn,
getSnap,
),
).toThrow('Invalid URL: The specified URL is not allowed.');

expect(fn).toHaveBeenCalledTimes(2);
expect(fn).toHaveBeenCalledWith('bar.com');
expect(fn).toHaveBeenCalledWith('test.metamask-phishing.io');
expect(fn).toHaveBeenCalledWith('https://bar.com');
expect(fn).toHaveBeenCalledWith('https://test.metamask-phishing.io');
});
});

Expand Down
12 changes: 4 additions & 8 deletions packages/snaps-utils/src/ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -360,19 +360,15 @@ export function validateLink(
const emails = url.pathname.split(',');
for (const email of emails) {
const hostname = email.split('@')[1];
assert(
!isOnPhishingList(hostname),
'The specified URL is not allowed.',
);
assert(!hostname.includes(':'));
const href = `https://${hostname}`;
assert(!isOnPhishingList(href), 'The specified URL is not allowed.');
}

return;
}

assert(
!isOnPhishingList(url.hostname),
'The specified URL is not allowed.',
);
assert(!isOnPhishingList(url.href), 'The specified URL is not allowed.');
} catch (error) {
throw new Error(
`Invalid URL: ${
Expand Down

0 comments on commit b78d274

Please sign in to comment.