{"id":"GHSA-5957-c7qm-m469","kind":"vulnerability","aliases":["GHSA-5957-c7qm-m469"],"related":[],"title":"Possible signature replay in Action Mailbox Mailgun ingress","description":"### Impact\nThe Action Mailbox Mailgun ingress authenticates a request with an HMAC of the `timestamp` and `token` parameters concatenated without a separator, and `ActionMailbox::Ingresses::Mailgun::InboundEmailsController::Authenticator#recent?` rejects only timestamps more than 2 minutes in the past. Because the signature does not fix the boundary between the two values, a captured signed request can be presented with a timestamp far in the future, which the ingress then accepts indefinitely. An attacker who obtains one signed Mailgun webhook request, but not the signing key, could submit arbitrary inbound email that Action Mailbox processes as genuine, possibly leading to forged messages attributed to the sender of the attacker's choosing.\n\nApplications that receive inbound email through the Action Mailbox Mailgun ingress are affected.\n\n### Details\nThe fixed releases also reject a Mailgun request whose timestamp is more than 2 minutes ahead of the server's clock, as they already did for one more than 2 minutes behind it. An application whose clock runs more than 2 minutes behind Mailgun's will now reject genuine webhooks and should synchronize its clock.\n\n### Releases\nThe fixed releases are available at the normal locations.\n\nPatches for those who cannot upgrade at once:\n- 8.1: https://github.com/rails/rails/commit/c3a295c5c22266e8ec4d0e664e6923a299235e7a.patch\n- 8.0: https://github.com/rails/rails/commit/4aa2ec66822bc4eb8b341a0608f1c90a3e371a34.patch\n\n### Credit\nThis issue was responsibly reported by HackerOne researcher [davutselcuk](https://hackerone.com/davutselcuk).","summary":"Action Mailbox's Mailgun ingress signs the timestamp and token without a separator, so a captured signed webhook can be replayed with a future timestamp and accepted indefinitely. An attacker holding one signed Mailgun request could submit arbitrary inbound email that the app processes as genuine.","severity":"low","cvss":3.7,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"actionmailbox","fixed":["8.1.4.1"],"affected":">= 8.1, < 8.1.4.1","ecosystem":"rubygems"},{"name":"actionmailbox","fixed":["8.0.5.2"],"affected":"< 8.0.5.2","ecosystem":"rubygems"}],"ecosystems":["rubygems"],"tags":["action-mailbox","cwe-294","mailgun","package","rails","self-hosted"],"not_affected_if":["no-mailgun-ingress","other-inbound-email-provider"],"how_to_check":"- Check the installed `actionmailbox` version in Gemfile.lock against the ranges below.\n- Look for the Mailgun ingress in use: `config.action_mailbox.ingress = :mailgun` or a Mailgun route to `/rails/action_mailbox/mailgun/inbound_emails/mx`.","fix":"- Rails `actionmailbox` 8.1 series: upgrade to `8.1.4.1`\n- Rails `actionmailbox` 8.0 series: upgrade to `8.0.5.2`\n- Patch commits for those who cannot upgrade at once are linked in the advisory (8.1 and 8.0).","status":"open","published_at":"2026-11-04T03:02:01+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","triaged_at":"2026-11-09T22:57:17+00:00","updated_at":"2026-11-09T22:57:17+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:57:17Z","model":"claude-haiku-5-5","output":{"fix":"- Rails `actionmailbox` 8.1 series: upgrade to `8.1.4.1`\n- Rails `actionmailbox` 8.0 series: upgrade to `8.0.5.2`\n- Patch commits for those who cannot upgrade at once are linked in the advisory (8.1 and 8.0).","reach":"internet","title":"Rails Action Mailbox: forged Mailgun inbound emails via replayed webhook signatures","impact":"medium","summary":"Action Mailbox's Mailgun ingress signs the timestamp and token without a separator, so a captured signed webhook can be replayed with a future timestamp and accepted indefinitely. An attacker holding one signed Mailgun request could submit arbitrary inbound email that the app processes as genuine.","audience":"businesses","category":"package","nicknames":[],"who_cares":["rails","action-mailbox","mailgun","self-hosted"],"confidence":0.8,"fix_status":"available","needs_auth":"yes","worst_case":"forged inbound emails processed as genuine by the app","analyst_note":"","how_to_check":"- Check the installed `actionmailbox` version in Gemfile.lock against the ranges below.\n- Look for the Mailgun ingress in use: `config.action_mailbox.ingress = :mailgun` or a Mailgun route to `/rails/action_mailbox/mailgun/inbound_emails/mx`.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-mailgun-ingress","other-inbound-email-provider"],"who_is_affected":"Applications that receive inbound email through the Action Mailbox Mailgun ingress are affected. Apps that do not use Mailgun ingress, or that take inbound email another way, can skip it. Teams whose server clock runs more than 2 minutes behind Mailgun's will start rejecting genuine webhooks after the fix and should sync their clock.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.00087,"input_tokens":5143,"output_tokens":712,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-294':25B '-5957':10A,15A '/davutselcuk).':295C '/rails/rails/commit/4aa2ec66822bc4eb8b341a0608f1c90a3e371a34.patch':282C '/rails/rails/commit/c3a295c5c22266e8ec4d0e664e6923a299235e7a.patch':278C '2':112C,215C,231C,242C '8.0':279C '8.1':275C 'accept':58B,147C 'action':5A,22B,32B,80C,169C,195C 'action-mailbox':21B 'actionmailbox':19A,20A,101C 'affect':200C 'ahead':217C 'alreadi':225C 'also':205C 'app':74B 'applic':188C,236C 'arbitrari':69B,165C 'attack':61B,150C,185C 'attribut':179C 'authent':84C,105C 'avail':262C 'behind':233C,244C 'boundari':124C 'c7qm':12A,17A 'c7qm-m469':11A,16A 'cannot':271C 'captur':47B,130C 'choos':187C 'clock':222C,238C,256C 'concaten':96C 'could':67B,163C 'credit':283C 'cwe':24B 'davutselcuk':292C 'detail':201C 'email':71B,167C,192C 'far':139C 'fix':122C,203C,259C 'forg':177C 'futur':55B,142C 'genuin':77B,173C,250C 'ghsa':9A,14A 'github.com':277C,281C 'github.com/rails/rails/commit/4aa2ec66822bc4eb8b341a0608f1c90a3e371a34.patch':280C 'github.com/rails/rails/commit/c3a295c5c22266e8ec4d0e664e6923a299235e7a.patch':276C 'hackeron':290C 'hackerone.com':294C 'hackerone.com/davutselcuk).':293C 'hmac':89C 'hold':62B 'host':31B 'impact':78C 'inbound':70B,166C,191C 'inboundemailscontrol':104C 'indefinit':59B,148C 'ingress':8A,36B,83C,102C,145C,198C 'issu':285C 'key':162C 'lead':175C 'locat':266C 'm469':13A,18A 'mailbox':6A,23B,33B,81C,170C,196C 'mailgun':7A,26B,35B,65B,82C,103C,155C,197C,208C,245C 'messag':178C 'minut':113C,216C,232C,243C 'normal':265C 'obtain':152C 'one':63B,153C,228C 'packag':27B 'paramet':95C 'past':116C 'patch':267C 'possibl':1A,174C 'present':135C 'process':75B,171C 'rail':28B 'receiv':190C 'recent':106C 'reject':107C,206C,249C 'releas':204C,257C,260C 'replay':3A,52B 'report':288C 'request':66B,86C,132C,157C,209C 'research':291C 'respons':287C 'run':239C 'self':30B 'self-host':29B 'sender':182C 'separ':44B,99C 'server':220C 'sign':37B,48B,64B,131C,154C,161C 'signatur':2A,119C 'submit':68B,164C 'synchron':254C 'timestamp':39B,56B,92C,109C,138C,211C 'token':41B,94C 'two':127C 'upgrad':272C 'valu':128C 'webhook':49B,156C,251C 'whose':210C,237C 'without':42B,97C","nicknames":[],"mitigations":[],"who_affected":"Applications that receive inbound email through the Action Mailbox Mailgun ingress are affected. Apps that do not use Mailgun ingress, or that take inbound email another way, can skip it. Teams whose server clock runs more than 2 minutes behind Mailgun's will start rejecting genuine webhooks after the fix and should sync their clock.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["actionmailbox"],"ptokens":["actionmailbox"],"labels":["actionmailbox","cwe294","low","mailgun","package","rails","rubygems","selfhosted"],"campaign_type":null,"search_a":"'-5957':10A,15A 'action':5A 'actionmailbox':19A,20A 'c7qm':12A,17A 'c7qm-m469':11A,16A 'ghsa':9A,14A 'ingress':8A 'm469':13A,18A 'mailbox':6A 'mailgun':7A 'possibl':1A 'replay':3A 'signatur':2A","search_b":"'-294':25B 'accept':58B 'action':22B,32B 'action-mailbox':21B 'app':74B 'arbitrari':69B 'attack':61B 'captur':47B 'could':67B 'cwe':24B 'email':71B 'futur':55B 'genuin':77B 'hold':62B 'host':31B 'inbound':70B 'indefinit':59B 'ingress':36B 'mailbox':23B,33B 'mailgun':26B,35B,65B 'one':63B 'packag':27B 'process':75B 'rail':28B 'replay':52B 'request':66B 'self':30B 'self-host':29B 'separ':44B 'sign':37B,48B,64B 'submit':68B 'timestamp':39B,56B 'token':41B 'webhook':49B 'without':42B","search_c":"'/davutselcuk).':295C '/rails/rails/commit/4aa2ec66822bc4eb8b341a0608f1c90a3e371a34.patch':282C '/rails/rails/commit/c3a295c5c22266e8ec4d0e664e6923a299235e7a.patch':278C '2':112C,215C,231C,242C '8.0':279C '8.1':275C 'accept':147C 'action':80C,169C,195C 'actionmailbox':101C 'affect':200C 'ahead':217C 'alreadi':225C 'also':205C 'applic':188C,236C 'arbitrari':165C 'attack':150C,185C 'attribut':179C 'authent':84C,105C 'avail':262C 'behind':233C,244C 'boundari':124C 'cannot':271C 'captur':130C 'choos':187C 'clock':222C,238C,256C 'concaten':96C 'could':163C 'credit':283C 'davutselcuk':292C 'detail':201C 'email':167C,192C 'far':139C 'fix':122C,203C,259C 'forg':177C 'futur':142C 'genuin':173C,250C 'github.com':277C,281C 'github.com/rails/rails/commit/4aa2ec66822bc4eb8b341a0608f1c90a3e371a34.patch':280C 'github.com/rails/rails/commit/c3a295c5c22266e8ec4d0e664e6923a299235e7a.patch':276C 'hackeron':290C 'hackerone.com':294C 'hackerone.com/davutselcuk).':293C 'hmac':89C 'impact':78C 'inbound':166C,191C 'inboundemailscontrol':104C 'indefinit':148C 'ingress':83C,102C,145C,198C 'issu':285C 'key':162C 'lead':175C 'locat':266C 'mailbox':81C,170C,196C 'mailgun':82C,103C,155C,197C,208C,245C 'messag':178C 'minut':113C,216C,232C,243C 'normal':265C 'obtain':152C 'one':153C,228C 'paramet':95C 'past':116C 'patch':267C 'possibl':174C 'present':135C 'process':171C 'receiv':190C 'recent':106C 'reject':107C,206C,249C 'releas':204C,257C,260C 'report':288C 'request':86C,132C,157C,209C 'research':291C 'respons':287C 'run':239C 'sender':182C 'separ':99C 'server':220C 'sign':131C,154C,161C 'signatur':119C 'submit':164C 'synchron':254C 'timestamp':92C,109C,138C,211C 'token':94C 'two':127C 'upgrad':272C 'valu':128C 'webhook':156C,251C 'whose':210C,237C 'without':97C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-04T03:02:01+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-5957-c7qm-m469","url":"https://github.com/rails/rails/security/advisories/GHSA-5957-c7qm-m469","severity":"low","published_at":"2026-11-04T03:02:01+00:00","modified_at":"2026-11-04T03:02:01+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","fetched_at":"2026-11-09T22:53:29+00:00","note":null}],"documents":[{"id":110676,"url":"https://github.com/rails/rails/security/advisories/GHSA-5957-c7qm-m469","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}