Releases: kristoferlund/ic-siwe
v0.1.1
v0.1.0 - Security fixes, making nonce required
Important
This release introduces breaking changes with new call signatures for the prepare_login
and login
functions.
This PR focuses on improving the security and reliability of the SIWE (Sign-In with Ethereum) process by ensuring proper cleanup of SIWE messages, implementing nonce-based security measures, and validating signature expiration. These changes help prevent replay attacks and ensure that expired signatures are not accepted.
Key Changes
- Ensure Expired SIWE Messages Removal: Added logic to remove SIWE messages on failed login attempts to prevent stale data retention.
- Nonce Generation for SIWE Messages: Implemented nonce generation for SIWE messages to enhance security by preventing replay attacks.
- Signature Expiry Validation: Added functionality to return an error if a signature has expired.
Detailed Changes
Commits
- 6daf4563f95f4dc653cb717f053e45e2fed578b9:
- Fix: Remove stored SIWE message on failed login attempts.
- 0b1118b822201b5bb124cfc0bd505a3c9550e29a:
- Feature: Secure generated SIWE messages using a nonce.
- c4cd84dc3125408100e3f37a1138e4a4cd3b5c2d:
- Fix: Return error if signature has expired.
Detailed Code Changes
-
New Functionality:
- Added
is_expired
function inSignatureMap
to check if a signature has expired:pub fn is_expired(&self, now: u64, seed_hash: Hash, delegation_hash: Hash) -> bool { let expiration = self .expiration_queue .iter() .find(|e| e.seed_hash == seed_hash && e.delegation_hash == delegation_hash); if let Some(expiration) = expiration { return now > expiration.signature_expires_at; } false }
- Modified
login
function to remove SIWE message on failed login attempts:match recover_eth_address(&message_string, signature) { Ok(recovered_address) => { if recovered_address != address.as_str() { siwe_messages.remove(address, nonce); return Err(LoginError::AddressMismatch); } } Err(e) => { siwe_messages.remove(address, nonce); return Err(LoginError::EthError(e)); } };
- Added
-
Nonce Implementation:
- Updated
prepare_login
to generate and include a nonce:pub fn prepare_login(address: &EthAddress) -> Result<(SiweMessage, String), EthError> { let nonce = generate_nonce(); let message = SiweMessage::new(address, &nonce); SIWE_MESSAGES.with_borrow_mut(|siwe_messages| { siwe_messages.insert(message.clone(), address, &nonce); }); Ok((message, nonce)) }
- Updated
-
Signature Expiry Validation:
- Added signature expiry validation in
witness
function:pub fn witness( seed: Hash, delegation_hash: Hash, ) -> Result<HashTree, DelegationError> { let seed_hash = hash::hash_bytes(seed); if signature_map.is_expired(get_current_time(), seed_hash, delegation_hash) { return Err(DelegationError::SignatureExpired); } let witness = signature_map .witness(seed_hash, delegation_hash) .ok_or(DelegationError::SignatureNotFound)?; Ok(witness) }
- Added signature expiry validation in
v0.0.7
ic_siwe
Changed
- Updated dependencies: candid, ic-cdk, ic-cdk-timers
ic_siwe_provider
Changed
- Updated dependencies: candid, ic-cdk, ic-stable-structures
v0.0.6
What's Changed
- Add/runtime feature
IncludeUriInSeed
by @kristoferlund in #5 - Add/runtime feature
DisableEthToPrincipalMapping
andDisablePrincipalToEthMapping
by @kristoferlund in #6
Runtime Features
The runtime behaviour of the ic_siwe_provider
canister and the ic_siwe
library can be customized using the following settings:
IncludeUriInSeed
Default: URI is not included in the seed
When set, the URI is included in the seed used to generate the principal. Including the URI in the seed does not add any additional security in a scenario where ic_siwe_provider
is deployed and configured to serve only one domain. However, if the ic_siwe
library is used in a custom canister, that delagetes identities for more than one domain, it is recommended to enable this feature to ensure that the principal is unique for each domain.
runtime_features = opt vec { \
variant { IncludeUriInSeed } \
};
DisableEthToPrincipalMapping
Default: Mapping is enabled
When set, the mapping of Ethereum addresses to Principals is disabled. This also disables the canister endpoints get_principal
.
runtime_features = opt vec { \
variant { DisableEthToPrincipalMapping } \
};
DisablePrincipalToEthMapping
Default: Mapping is enabled
When set, the mapping of Principals to Ethereum addresses is disabled. This also disables the canister endpoints get_address
and get_caller_address
.
runtime_features = opt vec { \
variant { DisablePrincipalToEthMapping } \
};
v0.0.10, ic-use-siwe-identity
Changed
- The
login
function now returns aPromise
that resolves to theIdentity
of the logged in user. New signature:login: () => Promise<DelegationIdentity | undefined>
. - Upgraded wagmi to v2.5.7.
- This introduces TanStack Query as an additional dependency.
- Also, this means the signture for
signMessageStatus
has changed slightly tosignMessageStatus: "error" | "idle" | "pending" | "success"
.
- Upgraded viem to v2.8.4
v0.0.9, ic-use-siwe-identity
Changed
- Moved @dfinity/xxx dependencies from dependencies to peerDependencies to reduce package size.
v0.0.5
ic_siwe_provider
Fixed
- Pre-built provider canister did not include metadata, now fixed.
v0.0.4
ic_siwe
Aligning version numbers with ic_siwe_provider
Added
EthAddress
andEthSignature
structs for type safety.- Added basic validation of delegation targets. Duplicate targets are now rejected.
Changed
- Library functions now mostly returns custom error types instead of strings. As a result, many error messages now differ slighlty to previous version.
prepare_login
andlogin
now requiresEthAddress
andEthSignature
structs instead of strings.- Replaced
create_user_canister_pubkey
with a more readable implementation.
ic_siwe_provider
Changed
- Service functions
prepare_login
,login
andget_delegation
have been renamedsiwe_prepare_login
,siwe_login
andsiwe_get_delegation
respectively. See ic_siwe_provider.did for details.
ic_siwe_provider v0.0.3
- First binary release of
ic_siwe_provider
. ic_siwe_provider
has not yet been audited and should not be used in production.
See: README for more details.
Full Changelog: https://github.com/kristoferlund/ic-siwe/commits/v0.0.3