screentinker/SECURITY.md
screentinker 1e1ed7e29a
Some checks are pending
CI / Unit tests (node --test) (push) Waiting to run
CI / OpenAPI spec lint (push) Waiting to run
CI / Android unit tests (Kotlin schedule evaluator vectors) (push) Waiting to run
CI / Boot smoke + version check (push) Waiting to run
Update SECURITY.md
2026-06-24 12:09:25 -05:00

5.3 KiB
Raw Permalink Blame History

Security Policy

Thanks for taking the time to look at ScreenTinker's security. The project is a one-person open-source effort, so response times reflect that — but reports are taken seriously and handled in good faith.

Reporting a vulnerability

Primary channel — GitHub Security Advisories (preferred):

github.com/screentinker/screentinker/security/advisories/new

GitHub's private advisory flow keeps the report off public issues, lets us draft a fix collaboratively, and produces a CVE if appropriate. Use this unless you have a reason not to.

Fallback — email:

support@bytetinker.net (the maintainer's consultancy inbox; the domain intentionally differs from screentinker.com — it's the actively-monitored business address rather than a project-domain alias that might not have working mail delivery).

Please include:

  • A description of the issue and its impact
  • Steps to reproduce (the more concrete, the better)
  • The commit SHA or release tag you observed it on
  • Any proof-of-concept code or payload, if you have one

Response timeline

I aim to acknowledge reports within 35 business days and update with a triage assessment within 10 business days. If you haven't heard back in that window, please feel free to nudge — life happens, and reports occasionally slip past.

Fix timelines depend on severity, complexity, and whether the issue is on the hosted instance (screentinker.com) or affects self-hosted deployments too. Critical issues affecting the hosted instance generally get same-week turnaround.

In scope

Reports about the following are welcome and treated as security issues:

  • Authentication / session bypass (e.g. JWT forgery, login bypass, privilege escalation)
  • Multi-tenancy boundary violations (one workspace's data leaking into another, organization-level isolation breaks)
  • XSS in widget rendering or admin UI (e.g. unsandboxed widget content, unescaped user input in dashboard surfaces)
  • CSRF on state-changing endpoints
  • SQL injection (deviations from parameterized queries are reportable)
  • Server-side request forgery (SSRF) via widget URLs, content uploads, webhook handlers, or similar
  • Insecure direct object reference (accessing a resource by ID without the proper tenancy gate)

Out of scope

The following are acknowledged but not treated as in-scope security issues for this project:

  • Denial of service via excessive resource usage (uploading large files, opening many sockets, etc.) — operational concerns, not security vulnerabilities. Rate limits exist where it matters most.
  • Social engineering of the maintainer or other users
  • Misconfigurations of self-hosted instances (e.g. exposing the server to the internet without TLS, weak JWT secrets, default passwords). The README documents recommended configuration; deviations are the operator's responsibility.
  • Vulnerabilities in third-party dependencies (Express, better-sqlite3, socket.io, etc.) — please report those upstream. If a dependency CVE affects ScreenTinker in a non-obvious way, that's worth flagging here too.
  • Reports generated by automated scanners with no manual triage or proof-of-concept (e.g. "your /robots.txt is missing" — not what this project worries about)

Coordinated disclosure

Please wait until a fix has shipped to the hosted instance and origin/main before public disclosure. I'll keep you in the loop on timing and confirm when it's safe to publish. For most issues that window is a few weeks at most; if it stretches longer, that's a signal something is more complex than expected and we'll coordinate.

If you find a critical issue that's being actively exploited (or you believe might be), please say so in the report — I'll prioritize accordingly.

Acknowledgments

If you'd like to be credited for a report, I'm happy to acknowledge you by name in release notes and (when applicable) in the GitHub advisory itself. Let me know in your report whether you'd like credit and how you'd like to be named. Anonymous reports are also welcome — no credit is required.

Uploaded content access model

Uploaded content (images, videos) served under /uploads/content is public by unguessable URL, not access-controlled:

  • Filenames are UUIDv4 (122 bits of randomness), so URLs are not enumerable or guessable.
  • There is no per-request authentication on content bytes, and CORS is open (Access-Control-Allow-Origin: *) because the web player's canvas-based screenshot capture requires cross-origin access.
  • Anyone who obtains a content URL can read that file, cross-tenant, with no expiry (immutable 30-day cache) and no revocation short of deleting the file.

This is an intentional design choice for digital signage, where content is destined for public display. It is security-through-unguessability, not access control.

Do not upload content you require to remain confidential - including material that is destined for a screen but not yet public (e.g. a scheduled promotion before its reveal, or an internal board containing names or other sensitive details). Such content is world-readable from the moment of upload. If pre-launch or tenant-private confidentiality is a requirement for your deployment, open an issue - signed/expiring URLs are tracked but not yet implemented.