Skip to content

security: remove hardcoded private keys from published SDK packageFix/remove hardcoded private keys#255

Open
verseon0980 wants to merge 3 commits intoFhenixProtocol:masterfrom
verseon0980:fix/remove-hardcoded-private-keys
Open

security: remove hardcoded private keys from published SDK packageFix/remove hardcoded private keys#255
verseon0980 wants to merge 3 commits intoFhenixProtocol:masterfrom
verseon0980:fix/remove-hardcoded-private-keys

Conversation

@verseon0980
Copy link
Copy Markdown

@verseon0980 verseon0980 commented May 11, 2026

Issue

Two private keys are hardcoded in packages/sdk/core/consts.ts, which is included in the published npm package:

// packages/sdk/core/consts.ts

export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY =
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' as const;

export const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY =
  '0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512' as const;

The same private keys are also hardcoded in packages/mock-contracts/contracts/MockCoFHE.sol:

// packages/mock-contracts/contracts/MockCoFHE.sol

uint256 constant DECRYPT_RESULT_SIGNER_PRIVATE_KEY =
    0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d;

uint256 constant ZK_VERIFIER_SIGNER_PRIVATE_KEY =
    49099792800763675079532137679706322989817545357788440619111868498148356080914;

0x59c6995e... is Hardhat account #1 — a publicly known key. The decrypt result verification in verifyDecryptResult.ts calls TaskManager.decryptResultSigner() on-chain. If the production TaskManager is ever (accidentally or maliciously) configured with the mock signer address 0x70997970C51812dc3A010C7d01b50e0d17dc79C8, any attacker who has this published key can forge valid decryption result signatures. The SDK will then accept fabricated plaintext values for any ciphertext.

Fix

packages/sdk/core/consts.ts — Remove private key exports entirely. These values have no place in a published package.

// REMOVE these two lines:
export const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = '...' as const;
export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = '...' as const;

Any test file that imports these constants must be updated to read from environment variables instead:

// In test files, replace imports with:
const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = process.env.MOCK_DECRYPT_SIGNER_PK;
const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = process.env.MOCK_ZK_SIGNER_PK;

packages/mock-contracts/contracts/MockCoFHE.sol — Remove the private key constants. The addresses are sufficient for mock verification. Private keys should never exist in Solidity source.

// REMOVE
uint256 constant DECRYPT_RESULT_SIGNER_PRIVATE_KEY = 0x59c6995e...;
uint256 constant ZK_VERIFIER_SIGNER_PRIVATE_KEY = 49099792...;

Why It Is Required

Private keys committed to source code and shipped in npm packages are permanently compromised.
Even after removal, they remain in git history and must be treated as burned.
Any production deployment that shares an address with these keys must rotate its signer immediately.
Shipping secret key material in a published cryptographic library undermines the entire trust model of the SDK.


Note

Medium Risk
Moderate risk because the exported mock private key constants now come from environment variables and may be undefined, potentially breaking downstream tooling/tests that assumed a literal key at build/runtime; otherwise it’s a straightforward security hardening change.

Overview
Removes embedded private keys from shipped code. The mock signer private keys were deleted from MockCoFHE.sol (leaving only signer addresses) and the SDK’s MOCKS_*_SIGNER_PRIVATE_KEY exports were changed from hardcoded literals to process.env lookups.

This prevents publishing known key material in the npm package, but requires consumers/tests that rely on these mock keys to provide MOCK_ZK_SIGNER_PK and MOCK_DECRYPT_SIGNER_PK at runtime.

Reviewed by Cursor Bugbot for commit 5a7dcaa. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 11, 2026

⚠️ No Changeset found

Latest commit: 5a7dcaa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 11, 2026

@verseon0980 is attempting to deploy a commit to the Fhenix Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bb4cec8. Configure here.

Comment thread packages/mock-contracts/contracts/MockCoFHE.sol
/** Private key for the Mock decrypt result signer account */
export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY =
'0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' as const;
export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = process.env.MOCK_DECRYPT_SIGNER_PK;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment variable keys break mock SDK functions

High Severity

MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY and MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY are now process.env lookups that evaluate to string | undefined. These values are passed directly to viem's privateKeyToAccount() and sign({ privateKey: ... }) in cofheMocksZkVerifySign.ts and cofheMocksDecryptForTx.ts, which expect a valid hex private key string. When the env vars are unset, all mock encrypt and decrypt operations will crash at runtime with an unhelpful error.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bb4cec8. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant