Skip to content

feat: Add S030 rule to detect require_auth instead of require_auth_for_args#911

Open
meshackyaro wants to merge 1 commit into
HyperSafeD:mainfrom
meshackyaro:flag-require-auth-for-args
Open

feat: Add S030 rule to detect require_auth instead of require_auth_for_args#911
meshackyaro wants to merge 1 commit into
HyperSafeD:mainfrom
meshackyaro:flag-require-auth-for-args

Conversation

@meshackyaro
Copy link
Copy Markdown
Contributor

@meshackyaro meshackyaro commented May 31, 2026

Summary

This PR implements the S030 security rule to detect when require_auth() is used instead of require_auth_for_args() in Soroban smart contracts with multiple Address parameters, which enables replay/scope-confusion attacks on multi-arg admin operations.

Closes #753

Note: Originally planned as S029, but changed to S030 due to upstream adding S029 for timestamp randomness detection.

Changes

Core Implementation

  • Finding Code S030: Added REQUIRE_AUTH_FOR_ARGS constant with High severity
  • Rule Implementation: RequireAuthForArgsRule in tooling/sanctifier-core/src/rules/require_auth_for_args.rs
  • Detection Logic: Flags public functions with 2+ Address parameters that:
    • Use require_auth() instead of require_auth_for_args()
    • Perform sensitive operations (storage mutations or external calls)

Documentation

  • Rule Documentation: Comprehensive guide at docs/rules/require-auth-for-args.md including:
    • Vulnerability explanation with attack scenarios
    • Detection criteria
    • Vulnerable vs. safe code examples
    • Mitigation strategies
    • Configuration options

Testing

  • Unit Tests: 6 tests covering all edge cases:
    • Detects vulnerable multi-address functions
    • Allows safe require_auth_for_args() usage
    • Ignores single-address functions
    • Ignores read-only functions
    • Ignores private functions
  • Integration Tests: 2 CLI tests for JSON and NDJSON output formats
  • Fixtures: Test cases at contracts/fixtures/finding-codes/s030_require_auth_for_args.rs

Additional Updates

  • Updated contracts/fixtures/finding-codes/README.md to include S030
  • Updated Cargo.lock with dependencies

Security Impact

Vulnerability Prevented

Replay/Scope-Confusion Attacks: When a function has multiple Address parameters (e.g., set_admin(caller, new_admin)), using require_auth() only verifies that caller signed something, but not what they signed. An attacker can:

  1. Capture a valid signature for one set of arguments
  2. Replay it with different arguments
  3. Bypass authorization for unintended operations

Example Attack Scenario

// VULNERABLE
pub fn set_admin(env: Env, caller: Address, new_admin: Address) {
    caller.require_auth();  // ❌ Only checks caller signed
    env.storage().instance().set(&symbol_short!("admin"), &new_admin);
}

Attack:

  1. Alice (admin) calls set_admin(alice, bob) to make Bob admin
  2. Attacker intercepts Alice's signature
  3. Attacker replays with set_admin(alice, attacker_address)
  4. Contract accepts it because alice.require_auth() only checks Alice signed
  5. Attacker is now admin

Mitigation

// SAFE
pub fn set_admin(env: Env, caller: Address, new_admin: Address) {
    caller.require_auth_for_args((new_admin.clone(),).into_val(&env));  // ✅ Binds to exact args
    env.storage().instance().set(&symbol_short!("admin"), &new_admin);
}

Testing

All tests pass:

# Unit tests
cd tooling/sanctifier-core
cargo test require_auth_for_args

# Integration tests
cd tooling/sanctifier-cli
cargo test test_s029  # Note: test names still reference s029 for consistency

Checklist

  • New finding code (S030) implemented
  • Rule documentation in docs/rules/
  • Fixtures with positive and negative cases
  • Unit tests (6 tests)
  • Integration tests (2 tests)
  • README updated
  • Rule registered in RuleRegistry
  • Follows existing code patterns
  • Rebased on latest main
  • Conflicts resolved (S029 → S030)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

@meshackyaro is attempting to deploy a commit to the gbangbolaoluwagbemiga's projects Team on Vercel.

A member of the Team first needs to authorize it.

…r_args

Implements detection for replay/scope-confusion attacks on multi-arg admin operations.

- Add S029 finding code for require_auth_for_args violations
- Implement RequireAuthForArgsRule with comprehensive detection logic
- Add rule documentation with attack scenarios and mitigation strategies
- Add test fixtures with vulnerable and safe code examples
- Add 6 unit tests covering all edge cases
- Add 2 CLI integration tests for JSON and NDJSON output
- Update fixtures README to include S029 (and missing S025-S027)

The rule flags public functions with 2+ Address parameters that use
require_auth() instead of require_auth_for_args() when performing
sensitive operations (storage mutations or external calls).

Closes HyperSafeD#753
@meshackyaro meshackyaro force-pushed the flag-require-auth-for-args branch from a8e49bd to 13b7c78 Compare May 31, 2026 09:56
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented May 31, 2026

@meshackyaro Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@meshackyaro meshackyaro changed the title feat: Add S029 rule to detect require_auth instead of require_auth_for_args feat: Add S030 rule to detect require_auth instead of require_auth_for_args May 31, 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.

[contrib-wave] Engine: New rule — flag 'require_auth_for_args' missed on multi-arg privileged fns

1 participant