Is BBC Sport safe?

Low risk

BBC Sport renders remote feed content in its popup via unescaped HTML and reports a persistent device ID to its feed server.

The extension fetches sports news items from notifiernews.com and inserts fields like title, author, and link directly into the popup page using raw string substitution and innerHTML, without any HTML encoding, so a malicious or compromised feed response could run code inside the popup. Separately, the background script generates a persistent identifier the first time it runs, stores it in synced Chrome storage, and sends it along with two disguised timestamp fields (labeled 'hash' and 'public_key') to the same feed server roughly every 3-5 minutes.

killianbyrnnev1.0.01Chrome Web Store
17Risk
Who publishes it

killianbyrnne - 1 other listing from the same operator, none carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
killianbyrnne

Same store account

1 other listing published from this account, 85 users between them, none of them carrying a finding.

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Third-party feed content is written into the popup without HTML escaping

Code analysis shows the popup writes each feed item's title, author, and other text straight into the page with innerHTML, with no escaping step anywhere in the pipeline.

A feed item containing markup would run as live HTML in the popup.

Severity
Low vulnerability
Type
Unexpected
CWE
CWE-829
Source
Static analysis
What actually happens
You did this

You open the extension's popup to check the latest BBC Sport headlines.

The extension did this

The popup takes each item's headline, summary, and author text and writes them into the page with innerHTML instead of a text-only method.

The same unescaped path also fills the link and image attributes for each item.

Feed fields written into the popup without escaping
  • Article headline
    England win T20 series decider by six wickets

    Rendered directly into the news list; written with innerHTML rather than a text-only method.

  • Article summary
    A last-over finish sealed the win at Edgbaston.

    Inserted the same way as the headline, straight into the page markup.

  • Author name
    BBC Sport Staff

    Also written with innerHTML, with no content check first.

  • Category tag
    Cricket

    Fills the small tag badge on each item through the same unescaped path.

  • Article link
    https://www.bbc.com/sport/cricket/12345678

    Placed into a link attribute the same way, so it can carry more than a plain URL.

  • Thumbnail image URL
    https://notifiernews.com/bbc_sport/image?id=48291

    Built into an img src attribute without checking it is actually a URL.

The code that does this

The popup's template-fill has no escaping step

Readable version
st(t) {  let e = document.querySelector("#tpl").innerText,    o = document.querySelector("#tpl-day-separator").innerText,    n = document.querySelector("#tpl-photo").innerText,    i = document.querySelector("#feed-box"),    s = null;  i.innerHTML = "";  for (let _ = 0; _ < t.length; _++) {    let c = t[_],      r = e;    c.is_show_image && (r = n);    let a = new Date(c.ptime);    if (s && s !== a.getDate()) {      let t = o;      t = t.replace("{{text}}", chrome.i18n.getMessage("month_" + a.getMonth(), [a.getDate(), a.getFullYear()])), i.innerHTML += t    }    s = a.getDate(), a = (a.getHours() < 10 ? "0" : "") + a.getHours() + ":" + (a.getMinutes() < 10 ? "0" : "") + a.getMinutes(), r = r.replace(/{{url}}/g, c.url), r = r.replace("{{time}}", a), r = r.replace("{{title}}", c.title), r = r.replace("{{image_url}}", c.image_url), r = r.replace("{{tagTitle}}", c.tag), r = r.replace("{{author}}", c.author), r = r.replace("{{annotation}}", c.annotation), r = r.replace("{{fun_type}}", c.post_type), i.innerHTML += r, i.querySelectorAll("img").forEach((t => {      t.addEventListener("load", (() => {        t.style.opacity = "1"      }))    }))  }  return this.rt(), this.ut()}
Where the rendered content originates
    • notifiernews.com

    Serves the JSON feed of BBC Sport items whose title, annotation, author, tag, url, and image_url fields are trusted and rendered into the popup without escaping.

Reproduce it yourself

Reproduces the popup's template-fill sink offline using the extension's own templates and replace() logic against a local mock feed item, no live server needed.

Requires
  • Any modern browser, no build step
feed-injection-repro.html · html
<!doctype html><html><head><meta charset="utf-8"><title>Feed injection sink reproducer</title></head><body><script type="tpl" id="tpl"><div class="ChronologyItem ChronologyItem--noImage ChronologyItem--news" >	<div class="ChronologyItem-info">		<div class="ChronologyItem-meta">			<span class="MaterialTag">{{tagTitle}}</span>			<span class="NewsTime">{{time}}</span>			<span class="NewsAuthor">{{author}}</span>		</div>		<div class="NewsTitle">			<span><span>{{title}}</span></span>			<span>{{annotation}}</span>		</div>	</div>	<a class="Link" data-href="{{url}}"></a></div></script><div id="feed-box"></div><script>// This is the extension's own st() template-fill logic, copied verbatim,// pointed at a local mock item instead of a live notifiernews.com response.function renderItem(c) {  let r = document.querySelector('#tpl').innerText;  const a = new Date(c.ptime);  const time = (a.getHours() < 10 ? '0' : '') + a.getHours() + ':' + (a.getMinutes() < 10 ? '0' : '') + a.getMinutes();  r = r.replace(/{{url}}/g, c.url);  r = r.replace('{{time}}', time);  r = r.replace('{{title}}', c.title);  r = r.replace('{{tagTitle}}', c.tag);  r = r.replace('{{author}}', c.author);  r = r.replace('{{annotation}}', c.annotation);  document.querySelector('#feed-box').innerHTML += r;}// A feed item shaped like the real notifiernews.com response, with an// <img onerror> payload in the title field instead of plain text.renderItem({  ptime: Date.now(),  title: '<img src=x onerror="document.title=\'injected\'">',  annotation: 'Reproducer annotation',  author: 'Reproducer',  tag: 'Test',  url: 'https://example.com'});setTimeout(() => {  console.log('document.title is now:', document.title);}, 100);</script></body></html>
How to run it
  1. 1Save as feed-injection-repro.html and open it in a browser.
  2. 2Open the console and confirm document.title changed to 'injected'.
  3. 3This proves the sink executes markup; it does not require access to the live notifiernews.com backend.
Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

What it can do

Permissions this extension asks for, as declared in version 1.0.01. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Schedule its own background tasks

    alarms

  • Store data in your browser

    storage

  • See the address and title of every tab you have open

    tabs

Where it sends data

Destinations our analysis observed BBC Sport contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • notifiernews.com

    BBC Sport sends data to notifiernews.com. 3 other extensions we have analyzed send data here.