Skip to content

Add PayerCheck to validate V2 receipt payer field#915

Merged
neithanmo merged 1 commit intomainfrom
fix/payer_check
Jan 29, 2026
Merged

Add PayerCheck to validate V2 receipt payer field#915
neithanmo merged 1 commit intomainfrom
fix/payer_check

Conversation

@neithanmo
Copy link
Copy Markdown
Collaborator

Adds a new PayerCheck to validate that V2 receipts have a payer field matching the on-chain recovered sender before storage. This closes a security gap similar to TRST-H-1.

Problem

V2 receipts contain a payer field in the message that was not validated against the on-chain recovered sender. An attacker could:

  1. Use a signer authorized by PayerA (legitimate on-chain mapping)
  2. Set receipt.message.payer = PayerB (arbitrary address)
  3. Receipt passes SenderBalanceCheck because signer → PayerA has escrow balance
  4. Receipt is stored with payer = PayerB (claimed, not validated)
  5. tap-agent queries WHERE payer = PayerAnever finds the receipt
  6. Receipts remain orphaned, causing DB bloat and potential DoS

Solution

Add PayerCheck that compares receipt.message.payer against the recovered sender (injected by sender_middleware via get_sender_for_signer()). Mismatched receipts are rejected before storage.

Add validation to ensure V2 receipt's claimed `payer` field matches the
on-chain recovered sender (from signer → payer escrow mapping).

Without this check, an attacker could submit receipts with a mismatched
payer field that would pass balance checks but be stored with the wrong
payer, causing receipts to never be aggregated by tap-agent (which
queries by the recovered sender).

This prevents:
- Database bloat from orphaned receipts
- Potential DoS via flooding DB with invalid receipts

Similar to TRST-H-1 fix for service_provider validation.
@github-actions
Copy link
Copy Markdown
Contributor

Pull Request Test Coverage Report for Build 21482936739

Details

  • 92 of 95 (96.84%) changed or added relevant lines in 2 files are covered.
  • 3 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.2%) to 68.439%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/service/src/tap/checks/payer_check.rs 91 94 96.81%
Files with Coverage Reduction New Missed Lines %
crates/watcher/src/lib.rs 3 85.42%
Totals Coverage Status
Change from base Build 21422655829: 0.2%
Covered Lines: 10385
Relevant Lines: 15174

💛 - Coveralls

@neithanmo neithanmo marked this pull request as ready for review January 29, 2026 15:18
Copy link
Copy Markdown
Member

@anirudh2 anirudh2 left a comment

Choose a reason for hiding this comment

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

Nice!

@neithanmo neithanmo merged commit 3ec85ba into main Jan 29, 2026
12 checks passed
@neithanmo neithanmo deleted the fix/payer_check branch January 29, 2026 16:02
@github-actions github-actions bot mentioned this pull request Jan 29, 2026
This was referenced Feb 5, 2026
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.

3 participants