2023-07-26 01:58:33 +02:00
|
|
|
import { PPOM } from '@blockaid/ppom';
|
|
|
|
import { PPOMController } from '@metamask/ppom-validator';
|
|
|
|
|
2023-08-03 12:54:54 +02:00
|
|
|
import {
|
|
|
|
BlockaidReason,
|
|
|
|
BlockaidResultType,
|
|
|
|
} from '../../../../shared/constants/security-provider';
|
2023-08-03 16:56:05 +02:00
|
|
|
import PreferencesController from '../../controllers/preferences';
|
2023-08-03 12:54:54 +02:00
|
|
|
|
|
|
|
const { sentry } = global as any;
|
|
|
|
|
2023-07-26 01:58:33 +02:00
|
|
|
const ConfirmationMethods = Object.freeze([
|
|
|
|
'eth_sendRawTransaction',
|
|
|
|
'eth_sendTransaction',
|
|
|
|
'eth_sign',
|
|
|
|
'eth_signTypedData',
|
|
|
|
'eth_signTypedData_v1',
|
|
|
|
'eth_signTypedData_v3',
|
|
|
|
'eth_signTypedData_v4',
|
|
|
|
'personal_sign',
|
|
|
|
]);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Middleware function that handles JSON RPC requests.
|
|
|
|
* This function will be called for every JSON RPC request.
|
|
|
|
* It will call the PPOM to check if the request is malicious or benign.
|
|
|
|
* If the request is benign, it will be forwarded to the next middleware.
|
|
|
|
* If the request is malicious or warning, it will trigger the PPOM alert dialog,
|
|
|
|
* after the user has confirmed or rejected the request,
|
|
|
|
* the request will be forwarded to the next middleware, together with the PPOM response.
|
|
|
|
*
|
|
|
|
* @param ppomController - Instance of PPOMController.
|
2023-08-03 12:54:54 +02:00
|
|
|
* @param preferencesController - Instance of PreferenceController.
|
2023-07-26 01:58:33 +02:00
|
|
|
* @returns PPOMMiddleware function.
|
|
|
|
*/
|
2023-08-03 12:54:54 +02:00
|
|
|
export function createPPOMMiddleware(
|
|
|
|
ppomController: PPOMController,
|
|
|
|
preferencesController: PreferencesController,
|
|
|
|
) {
|
2023-07-26 01:58:33 +02:00
|
|
|
return async (req: any, _res: any, next: () => void) => {
|
|
|
|
try {
|
2023-08-03 12:54:54 +02:00
|
|
|
const securityAlertsEnabled =
|
|
|
|
preferencesController.store.getState()?.securityAlertsEnabled;
|
|
|
|
if (securityAlertsEnabled && ConfirmationMethods.includes(req.method)) {
|
2023-07-26 01:58:33 +02:00
|
|
|
// eslint-disable-next-line require-atomic-updates
|
2023-08-03 12:54:54 +02:00
|
|
|
req.securityAlertResponse = await ppomController.usePPOM(
|
|
|
|
async (ppom: PPOM) => {
|
|
|
|
return ppom.validateJsonRpc(req);
|
|
|
|
},
|
|
|
|
);
|
2023-07-26 01:58:33 +02:00
|
|
|
}
|
2023-08-03 12:54:54 +02:00
|
|
|
} catch (error: any) {
|
|
|
|
sentry?.captureException(error);
|
2023-07-26 01:58:33 +02:00
|
|
|
console.error('Error validating JSON RPC using PPOM: ', error);
|
2023-08-03 12:54:54 +02:00
|
|
|
req.securityAlertResponse = {
|
|
|
|
result_type: BlockaidResultType.Failed,
|
|
|
|
reason: BlockaidReason.failed,
|
|
|
|
description: 'Validating the confirmation failed by throwing error.',
|
|
|
|
};
|
2023-07-26 01:58:33 +02:00
|
|
|
} finally {
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|