mirror of
https://github.com/screentinker/screentinker.git
synced 2026-06-29 09:23:16 -06:00
123 lines
5.3 KiB
Markdown
123 lines
5.3 KiB
Markdown
# 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](https://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 **3–5 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.
|