-
-
Notifications
You must be signed in to change notification settings - Fork 266
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
chore: introduce @trezor/metadata package #16110
base: develop
Are you sure you want to change the base?
Conversation
if (!json?.access_token || !json?.refresh_token) { | ||
throw new Error('Could not retrieve the tokens.'); | ||
} | ||
Client.accessToken = json.access_token; | ||
Client.refreshToken = json.refresh_token; | ||
} catch { | ||
// TODO: it looks like that this actually does not work. I tested it even on develop by throwing an artifical error somewhere above. |
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.
cc @komret. not a big deal. if I am not wrong, this doesn't work. at least it helped me discover another potential runtime issue I fixed here https://github.com/trezor/trezor-suite/pull/16110/files#diff-56d44c230c949c29acb06aed65bf1fffef52e38cf29e86546c87b0e92b2c9c25R165
'request-code': (url: string, callback: (credentials: Credentials) => void) => void; | ||
}; | ||
|
||
export abstract class AbstractMetadataProvider extends TypedEmitter<Events> { |
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.
just changed it to event emitter. no changes besides that
🚀 Expo preview is ready!
|
tags: Record<number, PasswordTag>; | ||
}; | ||
|
||
export type Credentials = |
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.
only Credentials
type was added
c6ee3b1
to
935948a
Compare
4b3cb1f
to
7c6725b
Compare
7c6725b
to
6958513
Compare
return Promise.resolve({ success: true as const }); | ||
} | ||
|
||
delete nextMetadata.outputLabels[payload.txid][payload.outputIndex]; |
Check warning
Code scanning / CodeQL
Prototype-polluting assignment Medium
library input
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 6 hours ago
To fix the problem, we need to ensure that payload.txid
cannot be used to modify Object.prototype
. This can be achieved by validating the payload.txid
before using it as a key in the nextMetadata.outputLabels
object. We will reject any keys that are __proto__
, constructor
, or prototype
.
-
Copy modified lines R443-R445
@@ -442,2 +442,5 @@ | ||
if (payload.type === 'outputLabel') { | ||
if (typeof payload.txid === 'string' && (payload.txid === '__proto__' || payload.txid === 'constructor' || payload.txid === 'prototype')) { | ||
return Promise.resolve({ success: false as const, error: 'Invalid txid' }); | ||
} | ||
if (typeof payload.value !== 'string' || payload.value.length === 0) { |
nextMetadata.outputLabels[payload.txid] = {}; | ||
} | ||
|
||
nextMetadata.outputLabels[payload.txid][payload.outputIndex] = payload.value; |
Check warning
Code scanning / CodeQL
Prototype-polluting assignment Medium
library input
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 6 hours ago
To fix the prototype pollution issue, we need to ensure that the keys used in object assignments cannot be __proto__
, constructor
, or prototype
. This can be achieved by adding a check before the assignment to reject these keys. Alternatively, we can use a Map
object instead of a plain object for nextMetadata.outputLabels
.
The best way to fix the problem without changing existing functionality is to add a check before the assignment to ensure the key is not one of the dangerous properties.
-
Copy modified lines R457-R459
@@ -456,2 +456,5 @@ | ||
} else { | ||
if (payload.txid === '__proto__' || payload.txid === 'constructor' || payload.txid === 'prototype') { | ||
return Promise.resolve({ success: false as const, error: 'Invalid key' }); | ||
} | ||
if (!nextMetadata.outputLabels[payload.txid]) { |
|
||
if (payload.type === 'accountLabel') { | ||
if (typeof payload.value !== 'string' || payload.value.length === 0) { | ||
delete nextMetadata.accountLabel; |
Check warning
Code scanning / CodeQL
Prototype-polluting assignment Medium
library input
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 6 hours ago
To fix the problem, we need to ensure that the keys used to modify the nextMetadata
object cannot include dangerous values like __proto__
. One effective way to achieve this is by using a Map
object instead of a plain JavaScript object for nextMetadata
. Map
objects do not have prototype properties and are therefore immune to prototype pollution.
We will replace the plain object nextMetadata
with a Map
and update the code to use Map
methods for setting and deleting values. This change will be made in the addAccountMetadata
method.
-
Copy modified line R440 -
Copy modified line R444 -
Copy modified lines R452-R454 -
Copy modified lines R457-R458 -
Copy modified line R461 -
Copy modified line R467 -
Copy modified line R469 -
Copy modified line R475 -
Copy modified line R477 -
Copy modified lines R490-R492
@@ -439,3 +439,3 @@ | ||
|
||
const nextMetadata = cloneObject(data ?? DEFAULT_ACCOUNT_METADATA) as AccountLabels; | ||
const nextMetadata = new Map(Object.entries(cloneObject(data ?? DEFAULT_ACCOUNT_METADATA) as AccountLabels)); | ||
|
||
@@ -443,3 +443,3 @@ | ||
if (typeof payload.value !== 'string' || payload.value.length === 0) { | ||
if (!nextMetadata.outputLabels[payload.txid]) { | ||
if (!nextMetadata.get('outputLabels').get(payload.txid)) { | ||
// If we try to delete already deleted label it's ok. | ||
@@ -451,12 +451,12 @@ | ||
|
||
delete nextMetadata.outputLabels[payload.txid][payload.outputIndex]; | ||
if (Object.keys(nextMetadata.outputLabels[payload.txid]).length === 0) { | ||
delete nextMetadata.outputLabels[payload.txid]; | ||
nextMetadata.get('outputLabels').get(payload.txid).delete(payload.outputIndex); | ||
if (nextMetadata.get('outputLabels').get(payload.txid).size === 0) { | ||
nextMetadata.get('outputLabels').delete(payload.txid); | ||
} | ||
} else { | ||
if (!nextMetadata.outputLabels[payload.txid]) { | ||
nextMetadata.outputLabels[payload.txid] = {}; | ||
if (!nextMetadata.get('outputLabels').get(payload.txid)) { | ||
nextMetadata.get('outputLabels').set(payload.txid, new Map()); | ||
} | ||
|
||
nextMetadata.outputLabels[payload.txid][payload.outputIndex] = payload.value; | ||
nextMetadata.get('outputLabels').get(payload.txid).set(payload.outputIndex, payload.value); | ||
} | ||
@@ -466,5 +466,5 @@ | ||
if (typeof payload.value !== 'string' || payload.value.length === 0) { | ||
delete nextMetadata.addressLabels[payload.defaultValue]; | ||
nextMetadata.get('addressLabels').delete(payload.defaultValue); | ||
} else { | ||
nextMetadata.addressLabels[payload.defaultValue] = payload.value; | ||
nextMetadata.get('addressLabels').set(payload.defaultValue, payload.value); | ||
} | ||
@@ -474,5 +474,5 @@ | ||
if (typeof payload.value !== 'string' || payload.value.length === 0) { | ||
delete nextMetadata.accountLabel; | ||
nextMetadata.delete('accountLabel'); | ||
} else { | ||
nextMetadata.accountLabel = payload.value; | ||
nextMetadata.set('accountLabel', payload.value); | ||
} | ||
@@ -489,5 +489,5 @@ | ||
data: { | ||
accountLabel: nextMetadata.accountLabel, | ||
outputLabels: nextMetadata.outputLabels, | ||
addressLabels: nextMetadata.addressLabels, | ||
accountLabel: nextMetadata.get('accountLabel'), | ||
outputLabels: Object.fromEntries(nextMetadata.get('outputLabels')), | ||
addressLabels: Object.fromEntries(nextMetadata.get('addressLabels')), | ||
}, |
this PR introduces a new package
@trezor/metadata
. This package is intended to gather all metadata/labelling logic in it so that the suite-mobile team can use it easily when the time comes (cc @matejkriz).resolve #16124