Skip to content

Security: WillC822/Lightning-Watch

Security

SECURITY.md

Security

Reporting

Found something? Open an issue, or email the address on my GitHub profile. This is a personal project with no SLA, but credential-exposure issues will be handled promptly.


Threat model

The asset worth protecting is a metered third-party API credential (Xweather client id + secret). Compromise means quota exhaustion and, on a paid plan, financial cost. There is no user data, no PII, and no authentication system.

Secondary concern: this is safety-adjacent software. A wrong or stale reading is a real risk, so availability and correctness are treated as security properties, not just features.


Two deployment modes, two risk profiles

Local-only (browser)

Credentials are entered in Settings and held in localStorage.

  • ✅ Fine on a device you control
  • ❌ Stored in plaintext — inherent to any keyed client-side app
  • Never host this file publicly with credentials saved. Anyone loading the page gets your key from their own browser's storage after first save, and any XSS would expose it

Worker-backed (recommended)

The Cloudflare Worker holds credentials and the browser reads computed state as JSON.

  • ✅ Secrets set via wrangler secret put, encrypted at rest, never in source or git
  • ✅ Client never receives the credential
  • ✅ Server-side fetch also resolves CORS restrictions
  • ⚠️ Read endpoint is unauthenticated — see residual risks

Controls implemented

Area Control
Credential isolation Worker secrets via wrangler secret put; wrangler.toml git-ignored; .example template ships instead
Output encoding All user-controlled strings (site names) pass an HTML-entity encoder before any innerHTML write
URL construction encodeURIComponent on every interpolated value
Input validation Coordinates rejected unless isFinite; numeric inputs bounded by min/max with fallback defaults on every parse
Pre-flight validation Site sets exceeding the API's 100 km radius are rejected before a request that would silently return incomplete data
Response validation success flag checked; warn_no_data distinguished from real errors so "clear skies" is never mistaken for failure
Spend limiting Monthly cap enforced before request dispatch; prevents runaway loops draining the tier
Fail-safe degradation try/catch around storage with in-memory fallback; .catch() on every network call; a failed push can't break the polling loop
Link hygiene External links rel="noopener"; iframes lazy-loaded

Residual risks — known and accepted

Listed because undisclosed weaknesses are worse than disclosed ones.

  1. Plaintext client-side credential storage in local-only mode. Unavoidable for a keyed browser app. Mitigation: use the Worker; never host the raw file publicly.
  2. Unauthenticated Worker read endpoint. Anyone with the URL sees site status. Low sensitivity (public weather), but it is an open endpoint. Fix: add a shared-secret header or Cloudflare Access.
  3. ntfy topics are public by design. Security rests on an unguessable topic name — that's obscurity, not authentication. Mitigation: use a long random topic. Fix: self-host ntfy with auth.
  4. No Content-Security-Policy. The client loads Leaflet from a CDN without SRI. Fix: add SRI hashes and a CSP header, or vendor Leaflet locally.
  5. No automated test suite. Rule-engine logic was validated against 9 timer edge cases and the heat-index math against 8 published NWS reference values, but manually rather than in CI.
  6. Third-party availability. Radar, WBGT, and observations come from external services with no SLA. The app degrades rather than failing, but data can go stale silently.

If you leak a key

  1. Revoke it in the Xweather dashboard immediately
  2. Generate a replacement
  3. If it was committed, rewrite history — deleting the file is not enough:
    git filter-repo --path <file> --invert-paths     # or BFG Repo-Cleaner
    git push --force
    Assume anything pushed to a public repo was scraped within minutes. Rotate regardless.

Safety disclaimer

This software is provided without warranty. It reads detected lightning; many facilities use predictive systems that trigger earlier. Modelled WBGT runs cooler than field measurement and does not satisfy on-site measurement requirements such as Florida's Zachary Martin Act.

Never use this as the sole basis for a decision affecting anyone's safety.

There aren't any published security advisories