Skip to content

Add constant-time Assembly notification verification - #85

Open
tim-kos wants to merge 3 commits into
mainfrom
feat/verify-notification-signatures
Open

tim-kos wants to merge 3 commits into
mainfrom
feat/verify-notification-signatures

Conversation

@tim-kos

@tim-kos tim-kos commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Applications receiving Assembly notifications currently have to implement signature verification themselves.

Add Transloadit#verify_notification!(fields), which validates an SHA-1 HMAC over the exact received transloadit field before parsing it. Accept legacy and sha1:-prefixed signatures and string/symbol field keys. Validate signature format and length before using OpenSSL’s constant-time comparison, and raise Transloadit::Exception::InvalidSignature with a generic message on authentication failure. Document that authenticated invalid JSON still raises the parser exception and that applications must handle notification retries/replays idempotently.

Validation: full Ruby 3.3 suite passes (132 tests, 260 assertions; optional live-upload and signature-parity tests skipped), plus bundle exec standardrb and git diff --check. Tests cover valid signatures, exact-byte verification, wrong secrets, malformed/missing fields, unsupported prefixes, and authentication before parsing.

Compatibility: the Ruby 3.1 test bundle pins JSON below 3, because Ruby 3.1 resolves MultiJson 1.19, whose positional parsing options are incompatible with JSON 3 (#89). The pin lives in the Gemfile, with the same lines as #90, so the runtime gemspec is unchanged and applications on newer Rubies can still use JSON 3.

Configuration errors: verifying without an Auth Secret raises Transloadit::Exception::MissingSecret instead of InvalidSignature. Integrations such as the Rails SDK can then answer forged callbacks with 401 and surface misconfiguration as a server error.

The four fixes also merge together cleanly. Their combined Ruby 3.3 suite passes with Node signature parity enabled: 147 tests, 321 assertions, with only the optional live upload skipped.

Closes #83.

@codecov-commenter

codecov-commenter commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.95%. Comparing base (79535b2) to head (d85aa53).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #85      +/-   ##
==========================================
- Coverage   99.40%   98.95%   -0.46%     
==========================================
  Files           9        9              
  Lines         336      382      +46     
  Branches       38       51      +13     
==========================================
+ Hits          334      378      +44     
  Misses          1        1              
- Partials        1        3       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Verifying without an Auth Secret is a configuration error, so raise
Transloadit::Exception::MissingSecret instead of InvalidSignature. Callers
such as Rails integrations can then answer forged callbacks with 401 and
surface misconfiguration as a server error.

Move the JSON < 3 constraint from the gemspec to the Ruby 3.1 test bundle,
matching #90, so applications on newer Rubies can still use JSON 3.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.

Add timing-safe Assembly notification signature verification

2 participants