← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-0228 · CWE-79 · Disclosed 2025-01-05

A vulnerability has been found in code-projects Local Storage Todo App 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is graffiti on a demo whiteboard, not a master key to the building

CVE-2025-0228 is an XSS bug in code-projects Local Storage Todo App 1.0, specifically js-todo-app/index.html, where the Add input is reflected/executed without proper neutralization. The only affected version publicly identified is 1.0, and the vendor page describes the app as a simple educational HTML/CSS/JavaScript project that runs by opening index.html directly in a browser rather than as a hardened enterprise service.

The vendor's LOW 2.4 score is directionally right, and if anything reality is even less urgent for enterprise defenders. The decisive friction is not the XSS class itself; it is the combination of high privileges required, a toy/demo deployment model, no evidence of in-the-wild abuse, and a blast radius limited to one browser session/localStorage context rather than a central multi-user platform.

"This is a toy-app XSS with admin-only reach and near-zero enterprise exposure—track it, don't burn patch cycles on it."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a real deployment worth attacking

An attacker first needs a live instance of this specific Code Projects sample app, not just any todo list. The published project is a downloadable educational app opened locally in a browser, so in many environments there is no internet-reachable target at all and often no central server-side deployment to pivot through.
Conditions required:
  • A defender actually deployed code-projects Local Storage Todo App 1.0
  • The app is reachable by the attacker or shared with other users
Where this breaks in practice:
  • This is an educational sample, not a mainstream enterprise product
  • Vendor instructions say it runs by opening index.html, which sharply reduces centralized exposure
  • Internet-wide exposure is likely negligible compared with normal enterprise web stacks
Detection/coverage: Standard external scanners may miss it entirely because many copies are local-file or intranet-only. Asset inventory/SBOM coverage is usually poor for ad hoc downloaded sample apps.
STEP 02

Get privileged app access

The CNA vector marks this as PR:H, so the attacker needs a privileged or admin-capable position inside the app before they can drive the vulnerable Add path as scored by the vendor. That means this is not a clean unauthenticated internet-to-impact story; it already assumes a prior foothold or authorized access in the target context.
Conditions required:
  • Authenticated access with high privileges in the app context
Where this breaks in practice:
  • Requiring high privileges compounds downward pressure on severity
  • If an attacker already has admin-level access to a toy todo app, the incremental gain from XSS is small
Detection/coverage: Access logging, SSO logs, reverse-proxy logs, and browser telemetry may show abnormal admin interaction, but many sample deployments have little or no audit trail.
STEP 03

Inject script into the Add field

Using the published technique, the attacker submits a payload such as the VulDB example through the Add parameter, which is rendered without safe output encoding. That turns ordinary task content into executable script in the victim browser context.
Conditions required:
  • The vulnerable code path is present in js-todo-app/index.html
  • Input reaches a dangerous DOM sink without sanitization
Where this breaks in practice:
  • The bug is limited to one client-side page and one input flow
  • Modern browser protections reduce some follow-on abuse, especially if the app has no backend session secrets to steal
Detection/coverage: DAST tools and browser-based XSS testing should catch this if the app is actually tested. Generic network IDS coverage is weak for client-side DOM/reflected XSS in a niche app.
STEP 04

Abuse the browser-local impact

Successful execution lets the attacker tamper with page content, manipulate localStorage-backed tasks, and potentially read data available to that page origin. In practice, the impact is mostly confined to that single app/session because the product is a local-storage todo list, not a privileged enterprise control plane.
Conditions required:
  • A victim browser renders the malicious content in the vulnerable origin
Where this breaks in practice:
  • No server-side RCE, no database takeover, no broad tenant compromise
  • LocalStorage todo data is usually low-value and user-scoped
  • Blast radius is usually one origin and one user session
Detection/coverage: Browser dev tools, CSP violation reports if enabled, and EDR/browser isolation telemetry can surface script execution. Most enterprise vulnerability scanners will label the CVE but cannot measure real blast radius.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known active exploitation found in authoritative sources reviewed; CISA ADP Vulnrichment marks exploitation as none.
KEV statusNot listed in the CISA KEV Catalog.
Proof-of-concept availabilityYes, public disclosure/PoC exists. VulDB submission #474049 includes a simple XSS payload example: published by reporter Fergod.
EPSS0.00093 (~0.093%) per user-provided intel; third-party mirrors place it in a low percentile band and consistent with opportunistic, not prioritized, exploitation.
CVSS vector reality checkVendor vector is CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:N/I:L/A:N: network reachable in theory, but requires high privileges and user/browser interaction, with only low integrity impact.
Affected versionsOnly Local Storage Todo App 1.0 is publicly identified in CNA/NVD records.
Fixed versionNo patched version publicly documented. This looks like a one-off sample project release, not a maintained product stream with versioned security updates.
Exposure modelThe vendor page says the app runs by opening index.html directly in a browser. That strongly suggests very low enterprise exposure and often no server-side deployment at all.
Disclosure timelineCVE published 2025-01-05; NVD last modified 2025-01-10; VulDB timeline shows advisory disclosure on 2025-01-04.
Reporter / sourceReported by Fergod (VulDB User); CNA/assigner is VulDB.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to IGNORE (0.8/10)

The single most important severity reducer is deployment reality: this is a niche educational sample app that commonly runs as a local browser file, not a broadly exposed enterprise platform. Even when present, the vendor's own vector requires high privileges, so exploitation usually presupposes access you already should not have.

HIGH This is not an enterprise patch-priority event
MEDIUM The vulnerable behavior is a real XSS in version 1.0
MEDIUM No public fixed version appears to exist

Why this verdict

  • Requires privileged app access: vendor CVSS uses PR:H, which means this is already post-access and not an unauthenticated edge compromise
  • Tiny exposed population: the product is an educational HTML/JS sample that the vendor says is run by opening index.html in a browser, so real enterprise deployment is rare
  • Low blast radius: impact is browser/session/localStorage scoped, with no evidence of server-side code execution, tenant-wide takeover, or infrastructure compromise

Why not higher?

It is not higher because the attack path narrows fast: you need the exact sample app, a real deployment, and privileged access in that app context before the XSS matters. There is also no KEV listing, no campaign reporting, and no sign this sits on a meaningful number of internet-facing enterprise assets.

Why not lower?

It is not pure noise because the underlying bug appears genuine and a public PoC exists. If your developers copied this sample into an internal portal or repackaged it into a shared app, it can still enable session-level browser compromise and content tampering for that specific origin.

05 · Compensating Control

What to do — in priority order.

  1. Document and suppress — If this CVE appears only in vulnerability feeds and you do not knowingly run this sample app, mark it no action required and record the rationale now. For an IGNORE verdict there is no noisgate mitigation SLA and no remediation SLA; this is governance hygiene, not emergency work.
  2. Hunt for copied sample code — Search dev repos, shared drives, and ad hoc intranet sites for Local_Storage_Todo_App_In_JS_With_Source_Code, js-todo-app, or the vendor project title. Do this during normal backlog review, because the real risk is not the vendor sample itself but teams copying unsafe front-end patterns into internal apps.
  3. Remove or isolate hobby deployments — If you find a live deployment, retire it or restrict it to a non-production sandbox with no SSO, no sensitive data, and no shared multi-user access. Treat that as routine cleanup rather than security incident response.
  4. Enforce output encoding and CSP in internal web standards — Use this CVE as a coding-standard reminder: ban unsafe DOM sinks for user content and require a baseline Content Security Policy on internally developed web apps. That reduces recurrence across the broader estate, which matters more than this single sample project.
What doesn't work
  • Blindly prioritizing by NVD 4.8 alone doesn't help; it ignores the admin-only prerequisite and toy deployment model.
  • Perimeter blocking is mostly irrelevant when the app commonly runs as a local file or intranet page rather than a public service.
  • EDR alone will not 'fix' the issue; at best it may catch egregious follow-on browser abuse after script execution.
06 · Verification

Crowdsourced verification payload.

Run this on the host or workstation where the app files live, not on a network scanner. Invoke it with python3 check_cve_2025_0228.py /path/to/js-todo-app/index.html; no admin privileges are required, only read access to the file.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cve_2025_0228.py
# Detects likely vulnerable copies of code-projects Local Storage Todo App 1.0
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/error

import os
import re
import sys
from pathlib import Path

DANGEROUS_SINKS = [
    r'innerHTML\s*=',
    r'insertAdjacentHTML\s*\(',
    r'document\.write\s*\(',
    r'outerHTML\s*=',
]

APP_MARKERS = [
    r'todo',
    r'localStorage',
    r'add',
]

SAFE_HINTS = [
    r'textContent\s*=',
    r'createTextNode\s*\(',
    r'setAttribute\s*\(\s*["\']text',
]

def usage():
    print('UNKNOWN - usage: python3 check_cve_2025_0228.py /path/to/index.html')
    sys.exit(3)

def read_file(p: Path):
    try:
        return p.read_text(encoding='utf-8', errors='ignore')
    except Exception as e:
        print(f'UNKNOWN - cannot read file: {e}')
        sys.exit(2)

def has_any(patterns, text):
    return any(re.search(p, text, flags=re.IGNORECASE | re.MULTILINE) for p in patterns)

def main():
    if len(sys.argv) != 2:
        usage()

    target = Path(sys.argv[1])
    if not target.exists() or not target.is_file():
        print('UNKNOWN - target file does not exist')
        sys.exit(2)

    if target.name.lower() != 'index.html':
        print('UNKNOWN - target is not index.html')
        sys.exit(2)

    content = read_file(target)
    norm = ' '.join(content.split())

    app_like = has_any(APP_MARKERS, norm)
    dangerous = has_any(DANGEROUS_SINKS, norm)
    safe = has_any(SAFE_HINTS, norm)

    # Strong path clue from advisory
    path_hint = 'js-todo-app' in str(target).replace('\\', '/').lower()

    # Heuristic verdicts:
    # - VULNERABLE: looks like the sample app and contains unsafe DOM sinks
    # - PATCHED: looks like the app and uses safer text sinks without dangerous ones
    # - UNKNOWN: anything else
    if (app_like or path_hint) and dangerous:
        print('VULNERABLE - likely CVE-2025-0228 pattern present (unsafe DOM sink in todo app index.html)')
        sys.exit(1)

    if (app_like or path_hint) and safe and not dangerous:
        print('PATCHED - app markers present, but only safer text insertion patterns found')
        sys.exit(0)

    print('UNKNOWN - unable to confirm product/version or vulnerable sink pattern')
    sys.exit(2)

if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not treat this as a patch fire drill. First verify whether this sample app exists anywhere in your estate; if it does not, close the finding with documented rationale. If it does exist, remove or sandbox it during normal cleanup and fold the lesson into front-end secure coding standards. Because the reassessed verdict is IGNORE, there is no noisgate mitigation SLA and no noisgate remediation SLA here—document the exception now and spend your patching budget on internet-facing, pre-auth, actively exploited software instead.

Sources

  1. NVD CVE-2025-0228
  2. OpenCVE record mirror for CVE-2025-0228
  3. VulDB submission #474049
  4. Vendor project page
  5. CISA Known Exploited Vulnerabilities Catalog
  6. JVNDB entry
  7. INCIBE advisory
  8. CVE Details summary with EPSS mirror
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.