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

Use the URL origin instead of hostname to identify subject websites #11029

Open
rekmarks opened this issue Sep 4, 2024 · 10 comments
Open

Use the URL origin instead of hostname to identify subject websites #11029

rekmarks opened this issue Sep 4, 2024 · 10 comments
Assignees
Labels
INVALID-ISSUE-TEMPLATE Issue's body doesn't match any issue template. permission-system New UI components for Permission System Sev2-normal An issue that may lead to users misunderstanding some limited risks they are taking team-mobile-platform team-sdk SDK team type-bug Something isn't working

Comments

@rekmarks
Copy link
Member

rekmarks commented Sep 4, 2024

Due to some error made in the days of yore, the extension originally used the URL hostname component to identify dapps / websites/ (In the language of the permission controller, "subjects" that we identify by a part of their URLs.) This was changed to the more appropriate origin component in MetaMask/metamask-extension#8717. This change never made it to mobile, creating a confusing and potentially dangerous discrepancy in permission enforcement between the two applications. The offending line in mobile is here, although this may have implications for the SDK as well. Note that this may require a state migration.

@rekmarks rekmarks added team-sdk SDK team permission-system New UI components for Permission System team-mobile-platform team-api-platform labels Sep 4, 2024
@metamaskbot metamaskbot added the INVALID-ISSUE-TEMPLATE Issue's body doesn't match any issue template. label Sep 4, 2024
@owencraston
Copy link
Contributor

owencraston commented Sep 4, 2024

I suspect we are seeing the below error because of this line in the SSK Snap. The pre defined permissions map is here. Since I am testing with the published dapp (https://metamask.github.io/snap-simple-keyring/latest/) I figured that it would work but somewhere in the chain of commands the prefix (https://) is being stripped so the permissions are not accepted. Is there a reason we are stripping the prefix on mobile and not on extension?

@owencraston
Copy link
Contributor

I tried changing this line to ensure that we are using the raw url in the snapMethodMiddlewareBuilder but it did not completely trickle down to the snap.

from

app/core/BackgroundBridge/BackgroundBridge.js

snapMethodMiddlewareBuilder(
        Engine.context,
        Engine.controllerMessenger,
        origin,
        // We assume that origins connecting through the BackgroundBridge are websites
        SubjectType.Website,
      ),

to

snapMethodMiddlewareBuilder(
        Engine.context,
        Engine.controllerMessenger,
        this.url,
        // We assume that origins connecting through the BackgroundBridge are websites
        SubjectType.Website,
      ),

@owencraston
Copy link
Contributor

I also tried this change but got the following error.
Screenshot 2024-09-04 at 10 46 57 AM

WARN  [MetaMask DEBUG]: {"code": -32603, "message": "Must specify non-empty string origin."}
 LOG  [MetaMask DEBUG]: RPC (https://metamask.github.io): {"id": 771516241, "jsonrpc": "2.0", "method": "wallet_requestSnaps", "origin": "https://metamask.github.io", "params": {"npm:@metamask/snap-simple-keyring-snap": {"version": "1.1.2"}}, "toNative": true} -> {"error": {"code": -32603, "message": "Must specify non-empty string origin."}, "id": 771516241, "jsonrpc": "2.0"}

@rekmarks
Copy link
Member Author

rekmarks commented Sep 5, 2024

@owencraston assuming that this.url is a URL, that last one has to be const { origin } = this.url.

@gauthierpetetin gauthierpetetin added the type-bug Something isn't working label Sep 5, 2024
@github-project-automation github-project-automation bot moved this to To be fixed in Bugs by severity Sep 5, 2024
@gauthierpetetin gauthierpetetin added the Sev2-normal An issue that may lead to users misunderstanding some limited risks they are taking label Sep 5, 2024
@joaoloureirop joaoloureirop self-assigned this Sep 5, 2024
@github-project-automation github-project-automation bot moved this to To be fixed in Bugs by team Sep 19, 2024
github-merge-queue bot pushed a commit that referenced this issue Sep 20, 2024
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

1. What is the reason for the change?
- This change adds lays the foundation for third party snap accounts by
implementing/integrating the
[eth-snap-keyring](https://github.com/MetaMask/eth-snap-keyring) into
mobile flask
- this is flask only feature
- this change is needed to unlock the future of account management
beyond native EOA accounts. This will enable third party MPC accounts
such as [Capsule](https://usecapsule.com/). This also paves the way for
multi chain accounts such as bitcoin.
- This work has already been implemented and launched on the extension
in production. We are finally going to bring these feature to mobile.
2. What is the improvement/solution?
- implement the SnapKeyring builder. This implementation mirrors the
[one on
extension](https://github.com/MetaMask/metamask-extension/tree/develop/app/scripts/lib/snap-keyring).
- Implement and wire up the necessary snaps methods
(getAllowedKeyringMethods, handleSnapRpcRequest, getSnapKeyring,
hasPermission). The methods need to be implemented in the `Engine` as
well as the `snapMethodMiddlewareBuilder`
- add `'endowment:keyring': 'endowment:keyring'` to the set of available
snap permissions
- implement `keyringSnapPermissionsBuilder` which derives the
permissions for a specific origin.
- include the new SnapKeyring in the
[additionalKeyring](https://github.com/MetaMask/metamask-mobile/pull/10829/files#diff-1a656ef42f595bb9c6c1251b29808fd70d31da7a3e1a6e9be85574ad866dc1b0R796-R803)
section of the keyring controller. This is where we add non "native"
keyrings such as ledger and qr hardware wallets. The snapkeyring will
now be included in this list `IF THE BUILD TYPE IS FLASK`.
- I had to make some controllers properties on the Engine class for
easier access across the file. This matches more closely what the
extension is doing in the `metamask-controllers.js` file.


### This PR DOES NOT
- Allow users to confirm or deny snap account addition/removal. For now
we will accept all incoming snap account additions/removals. Those
confirmations will be handled in these following changes.
MetaMask/accounts-planning#152 and
MetaMask/accounts-planning#151
- This PR does not support custom for account snaps
- This PR does not support asynchronous approvals 
- This PR does not implement the improved account list U.I for snap
accounts. For now the snap accounts in the account list will look
exactly like the rest of the accounts.
- This PR does not support granular permissions required in production
since there seems to be come issues with the mobile snaps permissions in
general. see #11029.
For now we will eagerly grant keyring permissions to dapps since this is
just a flask feature and is not doing into production.
- Restrict wallet usage based on account permissions. Even if an account
does not have signing permissions these flows will be available in the
U.I and likely break.


## **Related issues**

Fixes: MetaMask/accounts-planning#149

## **Manual testing steps**

1. run yarn setup on this branch
2. navigate to .js.env and set `export METAMASK_BUILD_TYPE=flask`
5. `source .js.env`
6. `yarn watch:clean`
7. create/import a wallet
8. navigate to settings/snaps
9. there should be only one pre installed snap
10. open the browser
11. navigate to `https://metamask.github.io/snap-simple-keyring/latest/`
12. click connect and accept all of the permissions
13. you should now see this snap in the settings/snaps list
14. click create account on the snap simple keyring
15. the call should succeed and return the account info as a json obkect
16. navigate to the home page and open the account list, the selected
account should be a new account named `Snap Account 1`
17. repeat step 15 as many times as you want, each time the new account
should be added
18. clicking list accounts on the SSK dapp should give you the entire
list of accounts
19. extract an id value from the listed accounts and paste it into the
Remove accounts field and click.
20. the call should succeed and return null
21. navigate back to the home page and open the account list, that
account should no longer be there and another account should be the
selected account
22. 

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

N/A

### **After**



https://github.com/user-attachments/assets/79b0a22d-2bf3-4124-883d-82b91ab0121f



## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
@joaoloureirop joaoloureirop removed their assignment Oct 8, 2024
@Daniel-Cross
Copy link
Contributor

Daniel-Cross commented Oct 16, 2024

@owencraston I'm looking into this but I'm getting the following message.

Does anyone know what version I need to be on to connect first before I can debug?

{"version": "1.1.6"}}, "toNative": true} -> {"error": {"code": -32603, "data": {"originalError": [Object]}, "message": "Installing Snaps is currently disabled in this version of MetaMask."}, "id": 1160102261, "jsonrpc": "2.0"}

Image

@FrederikBolding
Copy link
Member

FrederikBolding commented Nov 11, 2024

Does anyone know what version I need to be on to connect first before I can debug?

@Daniel-Cross You'll need to set METAMASK_BUILD_TYPE=flask when building, which will enable installation of all types of Snaps.

@Daniel-Cross
Copy link
Contributor

Daniel-Cross commented Nov 14, 2024

@owencraston @FrederikBolding

Has this been fixed or is there currently some kind of workaround in place?

Tried to replicate and got a success message:

Image

@owencraston
Copy link
Contributor

I created a temporary work around by passing the entire URL as the snap origin. This is working with the current code. To truly test this we will need to swap current implementation of keyringSnapPermissionsBuilder for the one on the extension that uses the subject metadata controller..

Mobile:

export function keyringSnapPermissionsBuilder(
  origin: string,
): () => string[] {
  return () => {
    if (origin === 'metamask') {
      return METAMASK_ALLOWED_METHODS;
    }

    if (PORTFOLIO_ORIGINS.includes(origin)) {
      return PORTFOLIO_ALLOWED_METHODS;
    }
    return isProtocolAllowed(origin) ? WEBSITE_ALLOWED_METHODS : [];
  };
}

Extension:

export function keyringSnapPermissionsBuilder(
  controller: SubjectMetadataController,
  origin: string,
): () => string[] {
  return () => {
    if (origin === 'metamask') {
      return METAMASK_ALLOWED_METHODS;
    }

    if (PORTFOLIO_ORIGINS.includes(origin)) {
      return PORTFOLIO_ALLOWED_METHODS;
    }

    const originMetadata = controller.getSubjectMetadata(origin);
    if (originMetadata?.subjectType === SubjectType.Website) {
      return isProtocolAllowed(origin) ? WEBSITE_ALLOWED_METHODS : [];
    }

    return [];
  };
}

The current issue is that the subject metadata controller uses the snapId as the key so passing in an origin that resembles a url (https://www.snap.com) will not work for referencing the preferences controller. solution could be passing in the snap id to this function (then we lose the https check) or modifying the subject metadata to use the url as the key.

@Cal-L
Copy link
Contributor

Cal-L commented Nov 21, 2024

@Daniel-Cross it seems like a more general issue across subjects that use permissions controller. Did the fix apply to those areas as well? For example, connecting to dapps, WC, snaps, etc?

@FrederikBolding
Copy link
Member

FrederikBolding commented Nov 22, 2024

@Cal-L As far as I know there has been no fix. Owen has worked around the previously blocking issue, but as the original ticket states we should migrate from using hostname to origin everywhere to truly fix the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
INVALID-ISSUE-TEMPLATE Issue's body doesn't match any issue template. permission-system New UI components for Permission System Sev2-normal An issue that may lead to users misunderstanding some limited risks they are taking team-mobile-platform team-sdk SDK team type-bug Something isn't working
Projects
Status: To be fixed
Status: To be fixed
Development

When branches are created from issues, their pull requests are automatically linked.

10 participants