Only the latest minor release of Specter Core receives security updates. Currently: v0.6.x.
When a new minor lands (e.g. v0.7.0), security fixes for the previous minor (v0.6.x) continue for 90 days; after that, you'll need to upgrade.
Please do not open public GitHub issues for security vulnerabilities.
Email instead: hello@spectersync.com, subject prefix [SECURITY].
Please include:
- A description of the vulnerability.
- Steps to reproduce.
- The affected Specter version (
Specter → Aboutorghost-sync --versionfrom the CLI). - Your OS and version.
- Whether the vulnerability has been disclosed elsewhere (no judgment — just so we can coordinate).
We'll acknowledge receipt within 48 hours and provide a fix or mitigation timeline within 7 days. Critical issues (remote code execution, credential exfiltration) get a fix in days; lower-severity issues may take weeks.
- Specter Core — the desktop app and daemon in this repo.
- The Specter URL scheme (
specter://) — anything that could be triggered remotely by malicious URLs. - OAuth flows — the Shopify OAuth broker at
web/src/pages/api/oauth/shopify/*.ts(if you're auditing the server side too). - Credential storage — how access tokens are written to disk, file permissions, etc.
- HTML / Markdown sanitization — XSS in
markdownToHtmlor related paths.
- Specter Cloud — separate codebase, separate security policy. Report Cloud issues via the dashboard at
app.spectersync.com. - Third-party services we connect to (Shopify, Ghost, GitHub Releases, etc.) — report to the respective vendors.
- Issues that require local user privileges beyond what Specter would normally have (e.g. "if an attacker has root, they can read your config.json" — yes, that's how root works).
- Outdated Sparkle / dependency advisories that don't affect the way we use them — we triage these but treat them as low-priority unless the exposure is real.
- Configuration lives at
~/.config/ghost-sync/config.jsonwithchmod 600. The Mac and Electron config writers both use atomictempfile + renamewrites (chmod 600 reapplied post-rename) so an interrupted save can't leave a half-written or world-readable file. - The Shopify OAuth broker exchanges the merchant's authorization code for an access token server-side (Cloudflare Worker). The merchant's browser is then redirected to
specter://oauth/complete?code=<short-lived-exchange-code>— the access token never appears in any URL. The desktop app POSTs the exchange code back to the Worker over HTTPS to retrieve the token, then writes it to local config. Exchange codes are single-use with a 5-minute TTL. - HTML emitted to a remote CMS (Shopify push, etc.) runs through
sanitize-htmlwith an explicit safe-tag allowlist.<script>,<iframe>, event handlers, andjavascript:URLs are stripped.trustVaultContent: trueis the documented opt-out for users who fully control their vault. - All GDPR / lifecycle webhooks (
customers/data_request,customers/redact,shop/redact,app/uninstalled) verify the Shopify HMAC-SHA256 signature againstSHOPIFY_CLIENT_SECRETand return HTTP 401 on invalid or missing signatures.
Once a fix lands, we'll:
- Release a patched version (typically within 7 days for confirmed issues).
- Acknowledge the reporter in the changelog (unless you ask to stay anonymous).
- Open a public GitHub Security Advisory at https://github.com/gospecter/specter/security/advisories with a CVE if the issue meets the criteria.
Thank you for helping keep Specter merchants safe.