Introduction: The "N/A" Reality Check

In the world of Bug Bounty, we often talk about the wins — the Criticals, the P1s, the big payouts. But we rarely talk about the rejections.

The truth is, understanding why a bug is rejected is just as important as understanding why one is accepted. It sharpens your understanding of "Risk" vs. "Impact."

In my recent streak of findings on a major Sportswear Giant (Redacted), I found a fascinating endpoint. I discovered a way to trick their official website into generating a QR Code that redirected to any malicious site I wanted.

I thought I had found a unique Open Redirect. The security team disagreed.

This is the story of that discovery, the specific exploit, and a breakdown of why this modern attack vector — known as "Quishing" — is often a point of debate in the security world.

The Concept: What is "Quishing"?

We all know Phishing (sending fake emails) and Smishing (sending fake SMS). But recently, a new threat has emerged: Quishing (QR Code Phishing).

Attackers send a legitimate-looking email or letter with a QR Code. Because humans can't read QR codes with their eyes, they trust them. They scan the code with their phone, and bam — they are redirected to a malware site or a fake login page.

My goal was to see if I could make the target company's own website generate these malicious QR codes for me.

Phase 1: The Discovery

I was still digging through the "Return Label" functionality where I had found my previous two bugs (Rate Limiting and HTML Injection).

I noticed that when a user completes a return, the website offers a "Mobile Return Code." This allows the user to take their phone to a shipping store (like UPS or FedEx), scan a QR code, and print the label there.

I looked at the URL that generated this page:

https://www.redacted.com/en-us/qrcode/?qrtrackingcode=09587268112601267&RMID=...

My eyes immediately locked onto the parameter: qrtrackingcode.

It looked like the application was taking this value (09587...) and dynamically generating a QR code image on the screen.

The Hypothesis:

What happens if I replace that tracking number with a website URL? Will the server validate it? Or will it blindly encode whatever I type into a QR block?

Phase 2: The Exploit

I didn't even need Burp Suite for this one. A simple browser test would do.

I took the original URL and replaced the qrtrackingcode value with a URL encoded link to my "malicious" site.

Original Parameter:

qrtrackingcode=09587268112601267

My Payload:

qrtrackingcode=https%3a%2f%2fevil.com%2f%23

(This decodes to: https://evil.com/#)

The Full Malicious Link:

https://www.redacted.com/en-us/qrcode/?qrtrackingcode=https%3a%2f%2fevil.com%2f%23&RMID=11111111...

I hit Enter.

The Result:

The page loaded perfectly. It was the official Redacted.com website. It had the official header, the official footer, and the SSL padlock was green.

But in the center of the page, the QR Code had changed pattern.

I took out my smartphone. I opened the camera app and scanned the QR code on my computer screen.

Notification: "Open link in Safari: evil.com"

It worked. I had successfully turned the company's trusted webpage into a generator for my malicious links.

Phase 3: The Business Impact (The "Quishing" Attack)

I wrote up the report, arguing that this was a variation of an Open Redirect.

Usually, an Open Redirect looks like this:

https://site.com/login?redirect=evil.com -> Browser immediately goes to evil.com.

This was slightly different. The browser stayed on site.com, but the device scanning the screen was redirected.

My Argument for Impact:

  • The Perfect Phishing Setup: An attacker could send an email saying: "Your return is ready! Click here to view your Return QR Code on our official website."
  • User Trust: The user clicks the link. They see they are on https://www.redacted.com. They trust the site.
  • The Action: The page says "Scan this code at the store." The user scans it, thinking it's safe.
  • The Compromise: The scan redirects their phone to a phishing page, bypassing the desktop's security filters.

I categorized it as:

  • VRT: Unvalidated Redirects and Forwards > Open Redirect
  • Impact: Phishing / Social Engineering

Phase 4: The Verdict (Not Applicable)

I submitted the report and waited.

A few days later, the status update came in: Closed (Not Applicable).

Why?

This is a classic debate in Bug Bounty. Here is likely why the team rejected it:

  • No Direct Browser Redirection: A true "Open Redirect" vulnerability means the browser is forced to leave the legitimate site. In this case, the browser stays on the legitimate site. The "redirect" only happens if the user performs a second physical action (scanning with a phone).
  • "Reflected Input" vs. Vulnerability: The site is doing exactly what it was designed to do: encode the input into a QR code. It's similar to a "Text Reflection" (where you type "Hello" and the site displays "Hello"). Unless that text executes script (XSS), it's often considered "functionality," not a bug.
  • High User Interaction: The attack requires the user to (1) Click the link, (2) See the QR code, (3) Take out their phone, (4) Scan it, and (5) Click the link on their phone. This complex chain lowers the severity significantly.

Phase 5: Lessons Learned

Was this a waste of time? Absolutely not.

Here is what I learned from this "failed" report:

1. Know Your Definitions

Strictly speaking, this wasn't an "Open Redirect" in the VRT sense. It was more of a "Content Spoofing" issue. If I had reported it as "Content Spoofing leading to Quishing," I might have had a better conversation (though it likely still would have been N/A).

2. The Rise of "Quishing"

While this program rejected it, some programs accept this. As QR code fraud increases, companies are starting to care more about validating what goes into those black-and-white squares. This is a vulnerability class to keep an eye on in the future.

3. Move On Fast

I didn't argue. I didn't get angry. I accepted the decision and went back to hunting. That attitude is what led me to the other valid bugs I found later.

The takeaway:

You can find 10 bugs, and 5 might be rejected. That's the game. But the 5 that get accepted? Those are the ones that pay the bills and build your reputation.

Never stop looking at the URL parameters. Even the ones that just make squares.