Skip to content

Commit

Permalink
fix(connector-quorum/ethereum): strengthen contract parameter validation
Browse files Browse the repository at this point in the history
Signed-off-by: Shivam Purohit <[email protected]>

feat(cactus-plugin-ledger-connector-quorum):additional type checking

Signed-off-by: Shivam Purohit <[email protected]>

chore(deps): add dependency for cactus-plugin-ledger-connector-ethereum

Signed-off-by: Shivam Purohit <[email protected]>

feat(cactus-plugin-ledger-connector-ethereum):additional type checking

Signed-off-by: Shivam Purohit <[email protected]>

chore(deps):fix autoupgrade dependency

feat(cactus-plugin-ledger-connector-ethereum):remove typechecking logic

Signed-off-by: Shivam Purohit <[email protected]>

feat(cactus-plugin-ledger-connector-ethereum):additional type checking

Signed-off-by: Shivam Purohit <[email protected]>

chore(deps):fix autoupgrade

Signed-off-by: Shivam Purohit <[email protected]>

feat(cactus-plugin-ledger-connector-quorum):remove typechecking logic

Signed-off-by: Shivam Purohit <[email protected]>

feat(cactus-plugin-ledger-connector-quorum):additional type checking

Signed-off-by: Shivam Purohit <[email protected]>

fix(cactus-plugin-ledger-connector-quorum):remove import

Signed-off-by: Shivam Purohit <[email protected]>
  • Loading branch information
shivam-Purohit committed Dec 29, 2023
1 parent f8f6bcb commit da7ef0a
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"@types/uuid": "9.0.6",
"body-parser": "1.20.2",
"chalk": "4.1.2",
"ethers": "6.8.1",
"js-yaml": "4.1.0",
"socket.io": "4.5.4",
"uuid": "9.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { PayableMethodObject } from "web3-eth-contract";

import OAS from "../json/openapi.json";

import { Interface, FunctionFragment, isAddress} from "ethers";

import {
ConsensusAlgorithmFamily,
IPluginLedgerConnector,
Expand Down Expand Up @@ -85,6 +87,8 @@ import {
convertWeb3ReceiptStatusToBool,
} from "./types/util-types";

import { assert } from "console";

// Used when waiting for WS requests to be send correctly before disconnecting
const waitForWsProviderRequestsTimeout = 5 * 1000; // 5s
const waitForWsProviderRequestsStep = 500; // 500ms
Expand Down Expand Up @@ -1135,6 +1139,49 @@ export class PluginLedgerConnectorEthereum
`Invalid method name provided in request. ${args.contractMethod} does not exist on the Web3 contract object's "methods" property.`,
);
}
const abiInterface = new Interface(args.abi);
const methodFragment: FunctionFragment | null = abiInterface.getFunction(
args.contractMethod,
);
if (!methodFragment) {
throw new RuntimeError(
`Method ${args.contractMethod} not found in ABI interface.`,
);
}

// validation for the contractMethod
if (methodFragment.inputs.length !== contractMethodArgs.length) {
throw new Error(`Incorrect number of arguments for ${args.contractMethod}`);
}
methodFragment.inputs.forEach((input, index) => {
const argValue = contractMethodArgs[index];
const isValidType = typeof argValue === input.type;

if (!isValidType) {
throw new Error(`Invalid type for argument ${index + 1} in ${args.contractMethod}`);
}
});

//validation for the invocationParams
const invocationParams = args.invocationParams as Record<string, any>;
const allowedKeys = ['from', 'gasLimit', 'gasPrice', 'value'];

if(invocationParams){
Object.keys(invocationParams).forEach((key) => {
if (!allowedKeys.includes(key)) {
throw new Error(`Invalid key '${key}' in invocationParams`);
}
if (key === 'from' && !isAddress(invocationParams[key])) {
throw new Error(`Invalid type for 'from' in invocationParams`);
}
if (key === 'gasLimit' && typeof invocationParams[key] !== 'number') {
throw new Error(`Invalid type for '${key}' in invocationParams`);
}
if (key === 'gasPrice' && typeof invocationParams[key] !== 'number') {
throw new Error(`Invalid type for '${key}'in invocationParams`);
}
});
}

const methodRef = contract.methods[args.contractMethod] as (
...args: unknown[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export class InvokeRawWeb3EthContractEndpoint implements IWebServiceEndpoint {
public async handleRequest(req: Request, res: Response): Promise<void> {
const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`;
this.log.debug(reqTag);

try {
const methodResponse =
await this.options.connector.invokeRawWeb3EthContract(req.body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"@types/uuid": "9.0.6",
"body-parser": "1.20.2",
"chalk": "4.1.2",
"ethers": "6.8.1",
"socket.io": "4.5.4",
"uuid": "9.0.1",
"web3-core": "1.6.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { TransactionReceipt } from "web3-eth";

import OAS from "../json/openapi.json";

import { Interface, FunctionFragment, isAddress} from "ethers"

import {
ConsensusAlgorithmFamily,
IPluginLedgerConnector,
Expand Down Expand Up @@ -903,6 +905,49 @@ export class PluginLedgerConnectorQuorum
`Invalid method name provided in request. ${args.contractMethod} does not exist on the Web3 contract object's "methods" property.`,
);
}
const abiInterface = new Interface(args.abi);
const methodFragment: FunctionFragment | null = abiInterface.getFunction(
args.contractMethod,
);
if (!methodFragment) {
throw new RuntimeError(
`Method ${args.contractMethod} not found in ABI interface.`,
);
}

// validation for the contractMethod
if (methodFragment.inputs.length !== contractMethodArgs.length) {
throw new Error(`Incorrect number of arguments for ${args.contractMethod}`);
}
methodFragment.inputs.forEach((input, index) => {
const argValue = contractMethodArgs[index];
const isValidType = typeof argValue === input.type;

if (!isValidType) {
throw new Error(`Invalid type for argument ${index + 1} in ${args.contractMethod}`);
}
});

//validation for the invocationParams
const invocationParams = args.invocationParams as Record<string, any>;
const allowedKeys = ['from', 'gasLimit', 'gasPrice', 'value'];

if(invocationParams){
Object.keys(invocationParams).forEach((key) => {
if (!allowedKeys.includes(key)) {
throw new Error(`Invalid key '${key}' in invocationParams`);
}
if (key === 'from' && !isAddress(invocationParams[key])) {
throw new Error(`Invalid type for 'from' in invocationParams`);
}
if (key === 'gasLimit' && typeof invocationParams[key] !== 'number') {
throw new Error(`Invalid type for '${key}' in invocationParams`);
}
if (key === 'gasPrice' && typeof invocationParams[key] !== 'number') {
throw new Error(`Invalid type for '${key}'in invocationParams`);
}
});
}

return contract.methods[args.contractMethod](...contractMethodArgs)[
args.invocationType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export class InvokeRawWeb3EthContractEndpoint implements IWebServiceEndpoint {
public async handleRequest(req: Request, res: Response): Promise<void> {
const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`;
this.log.debug(reqTag);

try {
const methodResponse =
await this.options.connector.invokeRawWeb3EthContract(req.body);
Expand Down
54 changes: 54 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ __metadata:
languageName: node
linkType: hard

"@adraffy/ens-normalize@npm:1.10.0":
version: 1.10.0
resolution: "@adraffy/ens-normalize@npm:1.10.0"
checksum: af0540f963a2632da2bbc37e36ea6593dcfc607b937857133791781e246d47f870d5e3d21fa70d5cfe94e772c284588c81ea3f5b7f4ea8fbb824369444e4dbcb
languageName: node
linkType: hard

"@adraffy/ens-normalize@npm:1.9.0":
version: 1.9.0
resolution: "@adraffy/ens-normalize@npm:1.9.0"
Expand Down Expand Up @@ -7574,6 +7581,7 @@ __metadata:
axios: 1.6.0
body-parser: 1.20.2
chalk: 4.1.2
ethers: 6.8.1
express: 4.18.2
http-proxy-middleware: 2.0.6
js-yaml: 4.1.0
Expand Down Expand Up @@ -7771,6 +7779,7 @@ __metadata:
axios: 1.6.0
body-parser: 1.20.2
chalk: 4.1.2
ethers: 6.8.1
express: 4.18.2
minimist: 1.2.8
prom-client: 13.2.0
Expand Down Expand Up @@ -10119,6 +10128,15 @@ __metadata:
languageName: node
linkType: hard

"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
dependencies:
"@noble/hashes": 1.3.2
checksum: bb798d7a66d8e43789e93bc3c2ddff91a1e19fdb79a99b86cd98f1e5eff0ee2024a2672902c2576ef3577b6f282f3b5c778bebd55761ddbb30e36bf275e83dd0
languageName: node
linkType: hard

"@noble/ed25519@npm:^1.6.0":
version: 1.7.3
resolution: "@noble/ed25519@npm:1.7.3"
Expand Down Expand Up @@ -10147,6 +10165,13 @@ __metadata:
languageName: node
linkType: hard

"@noble/hashes@npm:1.3.2":
version: 1.3.2
resolution: "@noble/hashes@npm:1.3.2"
checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474
languageName: node
linkType: hard

"@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:^1.5.4, @noble/secp256k1@npm:~1.7.0":
version: 1.7.1
resolution: "@noble/secp256k1@npm:1.7.1"
Expand Down Expand Up @@ -13374,6 +13399,13 @@ __metadata:
languageName: node
linkType: hard

"@types/node@npm:18.15.13":
version: 18.15.13
resolution: "@types/node@npm:18.15.13"
checksum: 79cc5a2b5f98e8973061a4260a781425efd39161a0e117a69cd089603964816c1a14025e1387b4590c8e82d05133b7b4154fa53a7dffb3877890a66145e76515
languageName: node
linkType: hard

"@types/node@npm:20.4.7":
version: 20.4.7
resolution: "@types/node@npm:20.4.7"
Expand Down Expand Up @@ -15108,6 +15140,13 @@ __metadata:
languageName: node
linkType: hard

"aes-js@npm:4.0.0-beta.5":
version: 4.0.0-beta.5
resolution: "aes-js@npm:4.0.0-beta.5"
checksum: cc2ea969d77df939c32057f7e361b6530aa6cb93cb10617a17a45cd164e6d761002f031ff6330af3e67e58b1f0a3a8fd0b63a720afd591a653b02f649470e15b
languageName: node
linkType: hard

"agent-base@npm:6, agent-base@npm:^6.0.2":
version: 6.0.2
resolution: "agent-base@npm:6.0.2"
Expand Down Expand Up @@ -24560,6 +24599,21 @@ __metadata:
languageName: node
linkType: hard

"ethers@npm:6.8.1":
version: 6.8.1
resolution: "ethers@npm:6.8.1"
dependencies:
"@adraffy/ens-normalize": 1.10.0
"@noble/curves": 1.2.0
"@noble/hashes": 1.3.2
"@types/node": 18.15.13
aes-js: 4.0.0-beta.5
tslib: 2.4.0
ws: 8.5.0
checksum: 78b48d2fd13cf77c7041379595a3155eaf6e4da423999b782e6ff14cc58e452ef8c52f3e2f6995fcd2b34dfdd55eaf5ece6067cd754fe0c72388b12e1768f1b3
languageName: node
linkType: hard

"ethers@npm:^4.0.32, ethers@npm:^4.0.40":
version: 4.0.49
resolution: "ethers@npm:4.0.49"
Expand Down

0 comments on commit da7ef0a

Please sign in to comment.