-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Detail Bug Report
Summary
- Context:
isBlockedAddressis a security/policy utility used (e.g., inEventManager) to filter out events from non-user addresses like the zero address or the dead address. - Bug: The function uses strict EIP-55 checksum validation on its input, allowing blocked addresses to escape the blocklist if they are provided with an invalid mixed-case checksum.
- Actual vs. expected: A blocked address with an incorrect mixed-case checksum is not recognized as blocked (
false), whereas it should be blocked regardless of casing or checksum validity. - Impact: The blocklist can be easily bypassed by any user or automated process, leading to "dirty" analytics data or potential spam from addresses that were intended to be filtered out.
Code with Bug
export const isBlockedAddress = (
address: Address | null | undefined
): boolean => {
if (!address) return false;
const validAddress = getValidAddress(address); // <-- BUG 🔴 [Enforces strict checksum for mixed-case, returning null if invalid]
if (!validAddress) return false; // <-- BUG 🔴 [Returns false immediately, bypassing the block check]
// Normalize to checksum format for comparison
const checksumAddress = toChecksumAddress(validAddress);
return BLOCKED_ADDRESSES.some(
(blockedAddr) => toChecksumAddress(blockedAddr) === checksumAddress
);
};Explanation
isBlockedAddress first calls getValidAddress. For mixed-case addresses, getValidAddress enforces EIP-55 checksum correctness and returns null when the checksum is invalid. isBlockedAddress then immediately returns false when validAddress is null, so it never compares against BLOCKED_ADDRESSES.
This allows a blocked address (e.g., the dead address) to bypass the blocklist by using an intentionally wrong mixed-case checksum (e.g., changing ...dEaD to ...dEAD). The same address provided as all-lowercase is correctly blocked.
Codebase Inconsistency
The underlying isAddress behavior allows all-lowercase and all-uppercase addresses without checksum validation, but enforces strict checksum validation for mixed-case input. isBlockedAddress inherits this behavior, making blocklist enforcement depend on checksum validity rather than address identity.
Recommended Fix
The isBlockedAddress function should be robust against casing variations and should support both EVM and Solana addresses (by utilizing isBlockedSolanaAddress as well).
export const isBlockedAddress = (
address: Address | null | undefined
): boolean => {
// <-- FIX 🟢
if (!address || typeof address !== "string") return false;
const trimmed = address.trim().toLowerCase();
// Check EVM blocklist (case-insensitive)
if (BLOCKED_ADDRESSES.some((b) => b.toLowerCase() === trimmed)) {
return true;
}
// Also check Solana blocked addresses
if (isSolanaAddress(trimmed) && isBlockedSolanaAddress(trimmed)) {
return true;
}
return false;
};History
This bug was introduced in commit 7374bb4. The commit added address blocking logic that relies on getValidAddress, which returns null for addresses with invalid checksums, allowing blocked addresses to bypass the check by using mixed-case characters.