From a3a10639f89a7229f439e2a3395b2cdbf5fc892d Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Fri, 28 Jun 2024 12:02:01 +0200 Subject: [PATCH] feat(auth): validate user-provided auth signature --- packages/shared/package.json | 3 ++- packages/shared/src/index.ts | 1 + packages/shared/src/schemas.ts | 4 ++++ packages/taco-auth/package.json | 3 ++- packages/taco-auth/src/auth-sig.ts | 18 ++++++++++++++++++ packages/taco-auth/src/providers/eip4361.ts | 5 ++++- packages/taco/package.json | 2 +- packages/taco/src/conditions/const.ts | 3 --- packages/taco/src/conditions/shared.ts | 6 +----- pnpm-lock.yaml | 8 +++++++- 10 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 packages/shared/src/schemas.ts create mode 100644 packages/taco-auth/src/auth-sig.ts diff --git a/packages/shared/package.json b/packages/shared/package.json index 33b60369d..e0163869b 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -47,7 +47,8 @@ "axios": "^1.6.8", "deep-equal": "^2.2.3", "ethers": "*", - "qs": "^6.12.1" + "qs": "^6.12.1", + "zod": "*" }, "devDependencies": { "@typechain/ethers-v5": "^11.1.2", diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 63f08aa5a..0ca14e2b0 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -3,6 +3,7 @@ export * from './porter'; export type * from './types'; export * from './utils'; export * from './web3'; +export * from './schemas'; // Re-exports export { diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts new file mode 100644 index 000000000..0f083c130 --- /dev/null +++ b/packages/shared/src/schemas.ts @@ -0,0 +1,4 @@ +import { z } from 'zod'; + +export const ETH_ADDRESS_REGEXP = new RegExp('^0x[a-fA-F0-9]{40}$'); +export const EthAddressSchema = z.string().regex(ETH_ADDRESS_REGEXP); diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 0e821b87c..639c80f8c 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -41,7 +41,8 @@ "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@nucypher/shared": "workspace:*", - "siwe": "^2.3.2" + "siwe": "^2.3.2", + "zod": "^3.22.4" }, "devDependencies": { "@nucypher/test-utils": "workspace:*" diff --git a/packages/taco-auth/src/auth-sig.ts b/packages/taco-auth/src/auth-sig.ts new file mode 100644 index 000000000..749c1b1ec --- /dev/null +++ b/packages/taco-auth/src/auth-sig.ts @@ -0,0 +1,18 @@ +import { EthAddressSchema } from '@nucypher/shared'; +import { z } from 'zod'; + +import { EIP4361TypedDataSchema } from './providers/eip4361'; +import { EIP4361_AUTH_METHOD, EIP712_AUTH_METHOD } from './types'; + +export const authSignatureSchema = z.object({ + signature: z.string(), + address: EthAddressSchema, + scheme: z.enum([EIP712_AUTH_METHOD, EIP4361_AUTH_METHOD]), + typedData: z.union([ + EIP4361TypedDataSchema, + // TODO(#536): Remove post EIP712 deprecation + z.unknown() + ]) +}); + +export type AuthSignature = z.infer; diff --git a/packages/taco-auth/src/providers/eip4361.ts b/packages/taco-auth/src/providers/eip4361.ts index 48c3fc1a0..0a5ab1362 100644 --- a/packages/taco-auth/src/providers/eip4361.ts +++ b/packages/taco-auth/src/providers/eip4361.ts @@ -1,10 +1,13 @@ import { ethers } from 'ethers'; import { generateNonce, SiweMessage } from 'siwe'; +import { z } from 'zod'; import { LocalStorage } from '../storage'; import { AuthSignature, EIP4361_AUTH_METHOD } from '../types'; -export type EIP4361TypedData = string; +export const EIP4361TypedDataSchema = z.string(); + +export type EIP4361TypedData = z.infer; export type EIP4361AuthProviderParams = { domain: string; diff --git a/packages/taco/package.json b/packages/taco/package.json index fb9f58ca4..90dffe9c4 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -44,7 +44,7 @@ "@nucypher/taco-auth": "workspace:*", "ethers": "*", "semver": "^7.5.2", - "zod": "^3.22.4" + "zod": "*" }, "devDependencies": { "@nucypher/test-utils": "workspace:*", diff --git a/packages/taco/src/conditions/const.ts b/packages/taco/src/conditions/const.ts index 601888c31..45f25c44c 100644 --- a/packages/taco/src/conditions/const.ts +++ b/packages/taco/src/conditions/const.ts @@ -8,8 +8,6 @@ import { export const USER_ADDRESS_PARAM_EXTERNAL_EIP4361 = ':userAddressExternalEIP4361'; -export const ETH_ADDRESS_REGEXP = new RegExp('^0x[a-fA-F0-9]{40}$'); - // Only allow alphanumeric characters and underscores export const CONTEXT_PARAM_REGEXP = new RegExp('^:[a-zA-Z_][a-zA-Z0-9_]*$'); @@ -35,5 +33,4 @@ export const RESERVED_CONTEXT_PARAMS = [ USER_ADDRESS_PARAM_EIP712, USER_ADDRESS_PARAM_EIP4361, // USER_ADDRESS_PARAM_EXTERNAL_EIP4361 is not reserved and can be used as a custom context parameter - // USER_ADDRESS_PARAM_EXTERNAL_EIP4361 ]; diff --git a/packages/taco/src/conditions/shared.ts b/packages/taco/src/conditions/shared.ts index 720fa5038..7f4a63e77 100644 --- a/packages/taco/src/conditions/shared.ts +++ b/packages/taco/src/conditions/shared.ts @@ -1,3 +1,4 @@ +import { EthAddressSchema } from '@nucypher/shared'; import { USER_ADDRESS_PARAM_DEFAULT, USER_ADDRESS_PARAM_EIP4361, @@ -8,9 +9,6 @@ import { z } from 'zod'; import { CONTEXT_PARAM_PREFIX, CONTEXT_PARAM_REGEXP, - ETH_ADDRESS_REGEXP, - - } from './const'; export const contextParamSchema = z.string().regex(CONTEXT_PARAM_REGEXP); @@ -41,8 +39,6 @@ export const returnValueTestSchema = z.object({ export type ReturnValueTestProps = z.infer; -const EthAddressSchema = z.string().regex(ETH_ADDRESS_REGEXP); - const UserAddressSchema = z.enum([ USER_ADDRESS_PARAM_EIP712, USER_ADDRESS_PARAM_EIP4361, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d109aaf3..940db4893 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -512,6 +512,9 @@ importers: qs: specifier: ^6.12.1 version: 6.12.1 + zod: + specifier: '*' + version: 3.23.8 devDependencies: '@typechain/ethers-v5': specifier: ^11.1.2 @@ -553,7 +556,7 @@ importers: specifier: ^7.5.2 version: 7.6.2 zod: - specifier: ^3.22.4 + specifier: '*' version: 3.23.8 devDependencies: '@nucypher/test-utils': @@ -574,6 +577,9 @@ importers: siwe: specifier: ^2.3.2 version: 2.3.2(ethers@5.7.2) + zod: + specifier: ^3.22.4 + version: 3.23.8 devDependencies: '@nucypher/test-utils': specifier: workspace:*