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

feat: SES lockdown v0.18.8 (iOS JSC) #6586

Merged
merged 83 commits into from
Nov 10, 2023
Merged

feat: SES lockdown v0.18.8 (iOS JSC) #6586

merged 83 commits into from
Nov 10, 2023

Conversation

leotm
Copy link
Member

@leotm leotm commented Jun 13, 2023

Description

Problem being solved: prototype pollution/poisoning

SES lockdown (shim v0.18.8) on iOS JSC, baked early into RN core before RN initialisation for the simplest minimal solution
as opposed to previous approach of shim'ing at the beginning of our entry file requiring further complex lib patches

with SES lockdown on Android Hermes (introduced earlier in our RN v0.71.6 upgrade) being followed up separately
currently bundling successfully, but runtime not yet functional

SES lockdown on Android JSC was also passing smoke tests after some work prior to Hermes
so a backup engine worth keeping on ice being followed up separately

Previous patches no longer required: eth-keyring-controller, ethjs-contract (one not two), web3-core-methods, metro-react-native-babel-preset, Sentry config (see previous PR: #3794)

Nb: @babel/plugin-transform-regenerator removed from metro-react-native-babel-preset since initial investigation
Nb: @babel/plugin-transform-runtime config opt regenerator: true previously caused iOS animated node assertion failures
Nb: default @babel/plugin-transform-runtime via metro-react-native-babel-preset causes additional 4 SES warnings

Nb: Current behaviour (not SES)
main, jsc
- import wallet via SRP
  - tap form field: disables cmd+D (app must be closed, no Metro restart)

main, v8
- (fresh) import wallet via SRP
  - if cmd+v paste ok, bot Import btn tappable when filled, but spinner hang (no error/warn), ~20s Metro dc
  - restart, enter pw, tap Unlock btn, spinner hang, still ~20s Metro dc
  - tap Reset Wallet, hang
- import (continued)
  - partial responsiveness
    - tap form field: dev menu disabled (cmd+d, app must be closed)
    - unresponsive: tap Back, tap Show, cannot tap Import, cmd+v disabled
    - responsive: cycle/input fields
    - still ~20s Metro dc
Previous SES warnings when locking down at entry file (not RN InitializeCore)

https://www.diffchecker.com/fjj1iObp

# JSC (26)
Removing intrinsics.Object.setPrototypeOf.default
Removing intrinsics.Object.setPrototypeOf.__esModule
Removing intrinsics.Object.assign.default
Removing intrinsics.Object.assign.__esModule
Removing intrinsics.Reflect.construct.default
Removing intrinsics.Reflect.construct.__esModule
Removing intrinsics.Reflect.decorate
Removing intrinsics.Reflect.metadata
Removing intrinsics.Reflect.defineMetadata
Removing intrinsics.Reflect.hasMetadata
Removing intrinsics.Reflect.hasOwnMetadata
Removing intrinsics.Reflect.getMetadata
Removing intrinsics.Reflect.getOwnMetadata
Removing intrinsics.Reflect.getMetadataKeys
Removing intrinsics.Reflect.getOwnMetadataKeys
Removing intrinsics.Reflect.deleteMetadata
Removing intrinsics.%ArrayPrototype%.toReversed
Removing intrinsics.%ArrayPrototype%.toSorted
Removing intrinsics.%ArrayPrototype%.toSpliced
Removing intrinsics.%ArrayPrototype%.with
Removing intrinsics.%ArrayPrototype%.@@unscopables.toReversed
Removing intrinsics.%ArrayPrototype%.@@unscopables.toSorted
Removing intrinsics.%ArrayPrototype%.@@unscopables.toSpliced
Removing intrinsics.%TypedArrayPrototype%.toReversed
Removing intrinsics.%TypedArrayPrototype%.toSorted
Removing intrinsics.%TypedArrayPrototype%.with
# V8 (33)
Removing intrinsics.Object.assign.default
Removing intrinsics.Object.assign.__esModule
Removing intrinsics.Object.setPrototypeOf.default
Removing intrinsics.Object.setPrototypeOf.__esModule
Removing intrinsics.JSON.rawJSON
Removing intrinsics.JSON.isRawJSON
Removing intrinsics.Reflect.construct.default
Removing intrinsics.Reflect.construct.__esModule
Removing intrinsics.Reflect.decorate
Removing intrinsics.Reflect.metadata
Removing intrinsics.Reflect.defineMetadata
Removing intrinsics.Reflect.hasMetadata
Removing intrinsics.Reflect.hasOwnMetadata
Removing intrinsics.Reflect.getMetadata
Removing intrinsics.Reflect.getOwnMetadata
Removing intrinsics.Reflect.getMetadataKeys
Removing intrinsics.Reflect.getOwnMetadataKeys
Removing intrinsics.Reflect.deleteMetadata
Removing intrinsics.%ArrayPrototype%.toReversed
Removing intrinsics.%ArrayPrototype%.toSorted
Removing intrinsics.%ArrayPrototype%.toSpliced
Removing intrinsics.%ArrayPrototype%.with
Removing intrinsics.%ArrayPrototype%.@@unscopables.toReversed
Removing intrinsics.%ArrayPrototype%.@@unscopables.toSorted
Removing intrinsics.%ArrayPrototype%.@@unscopables.toSpliced
Removing intrinsics.%ArrayBufferPrototype%.transferToFixedLength
Removing intrinsics.%ArrayBufferPrototype%.detached
Removing intrinsics.%StringPrototype%.isWellFormed
Removing intrinsics.%StringPrototype%.toWellFormed
Removing intrinsics.%RegExpPrototype%.unicodeSets
Removing intrinsics.%TypedArrayPrototype%.toReversed
Removing intrinsics.%TypedArrayPrototype%.toSorted
Removing intrinsics.%TypedArrayPrototype%.with
Notes on patch creation
  • --exclude 'nothing' to include package.json changes, then trim patch
  • react-native requires trimming majority of patch after initial diffs
  • upon failure on symlinks, git clean -fdx and re-create

Related issues

Worthy read for everyone on adding/upgrading libraries

Fixes

Manual testing steps

App functions normally

Screenshots/Recordings

Before

Previously failing iOS (JSC) E2E tests have now been fixed

And more screenshots in related issues linked above

After

App functioning normally

Pre-merge author checklist

  • I’ve followed MetaMask Coding Standards.
  • I've clearly explained what problem this PR is solving and how it is solved.
  • I've linked related issues
  • I've included manual testing steps
  • I've included screenshots/recordings if applicable
  • I’ve included tests if applicable
  • I’ve documented my code using JSDoc format if applicable
  • I’ve applied the right labels on the PR (see labeling guidelines). Not required for external contributors.
  • I’ve properly set the pull request status:
    • In case it's not yet "ready for review", I've set it to "draft".
    • In case it's "ready for review", I've changed it from "draft" to "non-draft".

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.

@github-actions
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@socket-security
Copy link

socket-security bot commented Jun 22, 2023

No dependency changes detected. Learn more about Socket for GitHub ↗︎

👍 No dependency changes detected in pull request

@leotm
Copy link
Member Author

leotm commented Jun 27, 2023

@SocketSecurity ignore [email protected]

Unmaintained (via devDep)

[email protected] /Users/leo/Documents/GitHub/metamask-mobile
├─┬ @storybook/[email protected]
│ └─┬ @storybook/[email protected]
│   └── [email protected]
└─┬ @storybook/[email protected]
  └─┬ @storybook/[email protected]
    └── [email protected]

@leotm leotm changed the title SES lockdown feature: SES lockdown Jun 27, 2023
@leotm leotm changed the title feature: SES lockdown feat: SES lockdown Jun 27, 2023
@leotm leotm force-pushed the feature/ses-lockdown-2 branch 2 times, most recently from 65a7945 to 615abc6 Compare June 28, 2023 17:41
Fix iOS native animation (non-nil/non-zero) assertion failure (on initial parentNode then childNode), after nav to bot 4th WebView tab (unable to load pages, likely caused by current excluded RN Promise polyfillGlobal)
- Df (Foundation) *** Assertion failure in - disconnectAnimatedNodes:childTag
  - E [com.facebook.react.log:native] Exception thrown while executing UI block: 'parentNode' is a required parameter
- Df (Foundation) *** Assertion failure in - connectAnimatedNodes:childTag
  - E [com.facebook.react.log:native] Exception thrown while executing UI block: 'childNode' is a required parameter

Exclude iOS native animation (non-nil/non-zero) assertion macros - for now, when nodes (pointers to tags) attach/detach (to old/new parents and new views)
QA: no empty animation frames observed ✅

Low probability possible risks introduced
- incomplete node invalidation (outdated nodes)
- race condition: prop updated before UIManager created view (outdated props)
QA: no outdated animation frames observed ✅
iOS native animation assertion refs
- Summary: facebook/react-native@c858420
- PR: facebook/react-native#10663
- Examples: facebook/react-native#9120
- nb: mimics ReactAndroid (i.e. NativeAnimatedNodesManager.java)

nb: metro-react-native-babel-preset (0.72.3)
  - @babel/plugin-transform-regenerator has been removed since initial investigation
  - @babel/plugin-transform-runtime (removed) - 4 fewer SES warnings
    - intrinsics: Object.setPrototypeOf.default, Object.setPrototypeOf.__esModule, Reflect.construct.default, Reflect.construct.__esModule
  - @babel/plugin-transform-runtime > regenerator: false - immediate error thrown (recurring)

Todo: Fix WebView page load (likely caused by current excluded RN Promise polyfillGlobal), thus fixing these assertion failures on nav, then revert this patch
  - Problem: Including (default) RN Promise polyfillGlobal causing app to boot empty root view
Todo: Root cause of above 'regenerator: false' causing nil/zero parent/child nodes immediately to reoccur
@leotm leotm changed the title feat: SES lockdown (iOS JSC) feat: SES lockdown v0.18.8 (iOS JSC) Nov 2, 2023
Until Hermes runtime working on Android (currently only bundling successful)
@leotm leotm marked this pull request as ready for review November 2, 2023 15:49
Copy link
Contributor

github-actions bot commented Nov 2, 2023

E2E test started on Bitrise: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/2643987a-2d33-44ce-88f1-db28cf311e11
You can also kick off another Bitrise E2E smoke test by removing and re-applying the (Run Smoke E2E) label

ses.cjs Show resolved Hide resolved
"lint:eslint": "*.js"
},
- "main": "lib/index.js",
+ "main": "src/index.js",
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, I don't understand here why we needed to point to the src

Copy link
Member Author

@leotm leotm Nov 8, 2023

Choose a reason for hiding this comment

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

good question ^ these couple ethjs contract/query libs we use (transitively via ethjs) to init our engine service
both optimise their bundles with few Babel runtime helpers (notably regenerator and asyncToGenerator)
both currently incompatible with SES, so using their source code instead is less problematic

Copy link
Member Author

@leotm leotm Nov 8, 2023

Choose a reason for hiding this comment

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

so captured the details mentioned here
both in a code comment and issue

Copy link
Member

Choose a reason for hiding this comment

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

Have you considered patching babel-runtime and regenerator-runtime instead? They're used in quite a few packages (including some that we'll be introducing soon to the codebase, like our ethjs-* forks of packages like this one). It may be easier to fix the problem at the source. The extension already has patches for them to make them SES compatible.

@leotm leotm requested a review from tommasini November 8, 2023 18:25
Copy link
Contributor

@tommasini tommasini left a comment

Choose a reason for hiding this comment

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

Thanks for the answers Leo! LGTM!

@leotm
Copy link
Member Author

leotm commented Nov 10, 2023

branch updated to re-run smoke tests before merge, but all CI broken on yarn audit, fixed in

after fix merged ^ re-update branch, re-run smoke tests, then merge squash

edit: merged

Copy link

sonarcloud bot commented Nov 10, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link
Contributor

E2E test started on Bitrise: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/156c9199-a45a-41b6-a518-6f6232b927d0
You can also kick off another Bitrise E2E smoke test by removing and re-applying the (Run Smoke E2E) label

@leotm
Copy link
Member Author

leotm commented Nov 10, 2023

E2E test started on Bitrise: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/156c9199-a45a-41b6-a518-6f6232b927d0 You can also kick off another Bitrise E2E smoke test by removing and re-applying the (Run Smoke E2E) label

ios_e2e_test
android_e2e_test

@leotm leotm merged commit 6edfe34 into main Nov 10, 2023
29 checks passed
@leotm leotm deleted the feature/ses-lockdown-2 branch November 10, 2023 16:30
@github-actions github-actions bot locked and limited conversation to collaborators Nov 10, 2023
@github-actions github-actions bot removed the needs-dev-review PR needs reviews from other engineers (in order to receive required approvals) label Nov 10, 2023
@metamaskbot metamaskbot added the release-7.12.0 Issue or pull request that will be included in release 7.12.0 label Nov 10, 2023
index.js Show resolved Hide resolved
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
release-7.12.0 Issue or pull request that will be included in release 7.12.0 team-lavamoat
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants