Stored XSS in Yahoo News: A $2,000 Bug Bounty Write-Up

Sharing is caring :)
When we share, we open doors to a new beginning.

In 2018, I discovered and reported a stored cross-site scripting (XSS) vulnerability in Yahoo News’ commenting functionality. A crafted comment triggered JavaScript execution when the affected content was rendered.

In this write-up, I explain the proof of concept, break down the payloads, and share the disclosure timeline that led to a $2,000 USD bounty.

What Is Stored XSS?

Stored XSS occurs when an application saves user-controlled input and later renders it in a way that allows JavaScript to execute in a visitor’s browser. Comment fields are a typical entry point because submitted content is displayed again after it has been stored.

The important boundary is between content and code: a reader’s browser should display a comment as text, rather than interpret it as executable HTML.

The Entry Point: Yahoo News Comments

The vulnerable feature was the comment section on Yahoo News. I tested how it handled input containing HTML entities and an image element with a JavaScript event handler.

The original proof-of-concept screenshot shows this encoded input:

"><img src=x onerror=confirm(1);>

For readability, its decoded equivalent is:

"><img src=x onerror=confirm(1);>
HTML-entity-encoded XSS payload in the Yahoo News comment field
Figure 1 — The encoded proof-of-concept payload entered into a Yahoo News comment.

Historical Steps to Reproduce

  1. Visit Yahoo News and open an article with commenting available.
  2. Enter the encoded proof-of-concept payload into the comment field.
  3. Submit the comment and observe the affected content being rendered.
  4. A JavaScript confirmation dialog appears, displaying 1.

The browser identified www.yahoo.com as the source of the dialog. That was the visible confirmation that the injected JavaScript had executed.

JavaScript confirm dialog displaying 1 from www.yahoo.com
Figure 2 — The confirm(1) dialog produced by the first payload.

Understanding the Payload

The executable portion of the decoded payload is:

<img src=x onerror=confirm(1);>
  • <img> creates an HTML image element.
  • src=x points to a resource that failed to load as an image in the tested context.
  • onerror defines an event handler that runs when the image fails to load.
  • confirm(1) opens a confirmation dialog with OK and Cancel buttons.

This is why an XSS payload does not need a <script> tag. An event-handler attribute can also execute JavaScript if the application allows the browser to interpret untrusted input as HTML.

The leading "> is commonly used to attempt to break out of a quoted HTML attribute. The original evidence does not establish whether that prefix was necessary in this particular rendering context.

Why the Encoding Matters

The submitted string used HTML entities: &quot; represents a quotation mark, &lt; represents a less-than sign, and &gt; represents a greater-than sign.

Encoded text does not automatically become executable markup. The observed execution suggests that the application’s processing or rendering path allowed the input to reach an unsafe HTML context. The exact decoding step and underlying implementation were not documented in the original write-up.

A Second Proof of Concept: prompt(1337)

Next, I tested a variant that displayed a dialog with a text input field:

&lt;img src=x onerror=prompt(1337)&gt;

Its decoded equivalent is:

<img src=x onerror=prompt(1337)>

The mechanism remained the same: an image-loading error triggered JavaScript. This time, prompt(1337) displayed the message 1337 and a text field, where I typed “TheShahzada Was Here../”.

JavaScript prompt showing 1337 and TheShahzada Was Here typed into the input field
Figure 3 — The second payload demonstrated JavaScript execution through a prompt dialog.

That was definitely a “like a boss” moment! :)

Like a boss reaction image celebrating the successful proof of concept
The reaction when a small payload turns into a confirmed finding.

Security Impact

The demonstrated impact was JavaScript execution through user-controlled comment content. Stored XSS can potentially affect people who view the affected content, with consequences depending on the page context, user permissions, and browser protections.

Potential consequences include changing visible page content or displaying deceptive interfaces. This proof of concept demonstrated browser dialogs; it did not establish account takeover, cookie theft, or access to another user’s data.

The screenshots capture payload entry and execution. They do not, by themselves, document persistence after a reload or execution in a separate user’s session.

Video Proof of Concept

The original video PoC is embedded below:

Watch the original PoC on YouTube

Disclosure and Bounty Timeline

Report milestones, March–April 2018
DateEvent
Initial vulnerability report submitted.
HackerOne staff requested more information.
Additional information submitted.
Report triaged; initial $300 bounty awarded.
Vulnerability marked resolved.
Additional $1,700 bounty awarded.

Total bounty: $2,000 USD.

Lessons for Developers

Comments must remain untrusted throughout storage, retrieval, and rendering. Plain-text comments should use safe text-rendering methods and context-appropriate output encoding. Where rich HTML is supported, a maintained HTML sanitizer should remove dangerous elements and attributes.

Decoding or modifying content after sanitization can undo those protections. A restrictive Content Security Policy can add another layer of defense, but it cannot replace safe rendering. These are general recommendations; Yahoo’s specific implementation changes were not included in the original report.

Final Thoughts

This finding was a reminder to look closely at ordinary features. A comment box may seem simple, but the way an application processes and renders its content determines whether it remains text or becomes executable code.

The payload was short. Explaining its behavior, capturing the evidence, and responding to requests for additional information helped turn it into an actionable report.

Happy hacking—and keep sharing what you learn.

Written by

Further Reading

Share this field noteConnect on LinkedIn ↗

Discussion

Post a Comment

Discussion on Disqus

Blogger comments are available above. You can also load the existing Disqus discussion.