mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Prevent external domains from submitting more than one perm request at a time (#8148)
This commit is contained in:
parent
293741766f
commit
0775c61f09
@ -44,6 +44,8 @@ export class PermissionsController {
|
|||||||
restrictedMethods: Object.keys(this._restrictedMethods),
|
restrictedMethods: Object.keys(this._restrictedMethods),
|
||||||
store: this.store,
|
store: this.store,
|
||||||
})
|
})
|
||||||
|
this.pendingApprovals = new Map()
|
||||||
|
this.pendingApprovalOrigins = new Set()
|
||||||
this._initializePermissions(restoredPermissions)
|
this._initializePermissions(restoredPermissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +139,7 @@ export class PermissionsController {
|
|||||||
async approvePermissionsRequest (approved, accounts) {
|
async approvePermissionsRequest (approved, accounts) {
|
||||||
|
|
||||||
const { id } = approved.metadata
|
const { id } = approved.metadata
|
||||||
const approval = this.pendingApprovals[id]
|
const approval = this.pendingApprovals.get(id)
|
||||||
|
|
||||||
if (!approval) {
|
if (!approval) {
|
||||||
log.warn(`Permissions request with id '${id}' not found`)
|
log.warn(`Permissions request with id '${id}' not found`)
|
||||||
@ -158,7 +160,7 @@ export class PermissionsController {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.pendingApprovals[id]
|
this._removePendingApproval(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +169,7 @@ export class PermissionsController {
|
|||||||
* @param {string} id - the id of the rejected request
|
* @param {string} id - the id of the rejected request
|
||||||
*/
|
*/
|
||||||
async rejectPermissionsRequest (id) {
|
async rejectPermissionsRequest (id) {
|
||||||
const approval = this.pendingApprovals[id]
|
const approval = this.pendingApprovals.get(id)
|
||||||
|
|
||||||
if (!approval) {
|
if (!approval) {
|
||||||
log.warn(`Permissions request with id '${id}' not found`)
|
log.warn(`Permissions request with id '${id}' not found`)
|
||||||
@ -175,7 +177,7 @@ export class PermissionsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
approval.reject(ethErrors.provider.userRejectedRequest())
|
approval.reject(ethErrors.provider.userRejectedRequest())
|
||||||
delete this.pendingApprovals[id]
|
this._removePendingApproval(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -385,6 +387,38 @@ export class PermissionsController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a pending approval.
|
||||||
|
* @param {string} id - The id of the pending approval.
|
||||||
|
* @param {string} origin - The origin of the pending approval.
|
||||||
|
* @param {Function} resolve - The function resolving the pending approval Promise.
|
||||||
|
* @param {Function} reject - The function rejecting the pending approval Promise.
|
||||||
|
*/
|
||||||
|
_addPendingApproval (id, origin, resolve, reject) {
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.pendingApprovalOrigins.has(origin) ||
|
||||||
|
this.pendingApprovals.has(id)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Pending approval with id ${id} or origin ${origin} already exists.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingApprovals.set(id, { origin, resolve, reject })
|
||||||
|
this.pendingApprovalOrigins.add(origin)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the pending approval with the given id.
|
||||||
|
* @param {string} id - The id of the pending approval to remove.
|
||||||
|
*/
|
||||||
|
_removePendingApproval (id) {
|
||||||
|
const { origin } = this.pendingApprovals.get(id)
|
||||||
|
this.pendingApprovalOrigins.delete(origin)
|
||||||
|
this.pendingApprovals.delete(id)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience method for retrieving a login object
|
* A convenience method for retrieving a login object
|
||||||
* or creating a new one if needed.
|
* or creating a new one if needed.
|
||||||
@ -396,8 +430,6 @@ export class PermissionsController {
|
|||||||
// these permission requests are almost certainly stale
|
// these permission requests are almost certainly stale
|
||||||
const initState = { ...restoredState, permissionsRequests: [] }
|
const initState = { ...restoredState, permissionsRequests: [] }
|
||||||
|
|
||||||
this.pendingApprovals = {}
|
|
||||||
|
|
||||||
this.permissions = new RpcCap({
|
this.permissions = new RpcCap({
|
||||||
|
|
||||||
// Supports passthrough methods:
|
// Supports passthrough methods:
|
||||||
@ -418,12 +450,18 @@ export class PermissionsController {
|
|||||||
* @param {string} req - The internal rpc-cap user request object.
|
* @param {string} req - The internal rpc-cap user request object.
|
||||||
*/
|
*/
|
||||||
requestUserApproval: async (req) => {
|
requestUserApproval: async (req) => {
|
||||||
const { metadata: { id } } = req
|
const { origin, metadata: { id } } = req
|
||||||
|
|
||||||
|
if (this.pendingApprovalOrigins.has(origin)) {
|
||||||
|
throw ethErrors.rpc.resourceUnavailable(
|
||||||
|
'Permission request already pending; please wait.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
this._platform.openExtensionInBrowser(`connect/${id}`)
|
this._platform.openExtensionInBrowser(`connect/${id}`)
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.pendingApprovals[id] = { resolve, reject }
|
this._addPendingApproval(id, origin, resolve, reject)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}, initState)
|
}, initState)
|
||||||
|
Loading…
Reference in New Issue
Block a user