Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

audit fix: email nullifier info leak #39

Merged
merged 3 commits into from
Feb 4, 2025
Merged

audit fix: email nullifier info leak #39

merged 3 commits into from
Feb 4, 2025

Conversation

jp4g
Copy link
Contributor

@jp4g jp4g commented Feb 3, 2025

Addresses comment on Email nullifiers may leak information on the message

The issue is slightly more nuanced than relying on the preimage resistance of the hash function. Also note that as we mentioned, the standard_outputs() isn’t actually used anywhere in Z-imburse except for the examples.

The issue is that we are working under the assumption that somehow the signature does get leaked out of band, whereas the contents of the email remain private. We acknowledge this is an extremely unlikely scenario to occur.

However, if this does happen (and the standard_outputs() function is used in Z-imburse) then when the reimbursement transaction is executed and the nullifiers are emitted, an attacker can deduce which provider the reimbursement was for. Additionally, given the strict structure of the emails being verified, an attacker may be able to brute force the contents of the email and attempt to verify the contents against the public key + signature until signature verification passes. At that point he has uncovered the contents of the email and therefore who was reimbursed, from which provider, and for how much.

A: we've removed standard_outputs() technically, but the underlying functionality is still there. Basically inconsequential but worth highlighting
B: we've added zkemail::blinded_nullifier which provides a standard API for doing this kind of logic, this way developers will know to think about this
C: This is a tough problem. We could design an in-library solution for deterministically selecting random bytes out of the header or body, or something else similar that would be quite hard to attack. Specifically for Z-Imburse or similar usecases, if we want to prevent other users from using the same email, we would need such a robust solution. At this point, given the normal email nullifier is at parity with the circom implementation + the undertaking to design a good solution for blinding the nullifier, we are simply including the blinded_nullifier function in the API and electing not to immediately solve this on the z-imburse level.

We will keep this deficiency in mind, and parting suggestions on how best to deterministically select blinding bytes from the header would be appreciated (but not necessary to close the audit)

@jp4g jp4g merged commit 68bddde into main Feb 4, 2025
4 checks passed
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