Thank you for taking the time to look at the security of certmate-tools. The project is a static, client-side toolbox — no server-side code processes user data — but we still take any finding seriously.
Do not file a public GitHub issue for a security bug. Use either of the following private channels:
- GitHub Security Advisories (preferred): open a private advisory at https://github.com/fabriziosalmi/certmate-tools/security/advisories/new. This route is end-to-end private and lets us coordinate a fix and CVE assignment if appropriate.
- Email: fabrizio.salmi@gmail.com with the subject prefix
[certmate-tools security]. PGP key on request.
Please include, when possible:
- A clear description of the issue and its impact.
- Steps to reproduce — minimal page, URL, payload.
- Affected version / commit SHA.
- Your contact handle so we can credit you in the advisory (optional).
- Cross-site scripting / DOM injection in any tool page.
- Logic bugs that cause the tool to send certificate, key or token material off the user's browser (we promise the opposite).
- Cryptographic mis-implementation (incorrect RFC behavior, weak randomness, broken signature checks).
- Supply-chain risks on declared dependencies.
- Findings against third-party tools listed in the curated directory — please contact those projects directly.
- Pure SEO / typo / copywriting issues — open a regular issue or PR.
- Issues affecting unsupported browsers (we target the last two stable versions of Chrome, Firefox, Safari and Edge).
We aim for:
- 48 hours: acknowledgement of your report.
- 7 days: initial triage and severity assessment.
- 30 days: fix released, or a documented mitigation plan if longer.
We coordinate disclosure with the reporter and credit you in the release notes and security advisory unless you ask to stay anonymous.
Only the latest main-branch deployment of https://tools.certmate.org is
supported. Older static builds are not maintained.
The "no upload" promise is enforced by the browser, not just by code review.
- Content-Security-Policy with
default-src 'none',connect-src 'none',frame-ancestors 'none',base-uri 'none',form-action 'none',object-src 'none'. The CSP is delivered via<meta http-equiv>on every HTML page.script-srcandstyle-srcare'self'plus per-pagesha256-…hashes of inline blocks computed at build time — there is no'unsafe-inline'and no'unsafe-eval'. connect-src 'none'is the load-bearing rule: any future regression that introducesfetch(),XMLHttpRequest,WebSocket,EventSource,sendBeaconor a cross-origin dynamic import will be blocked by the browser, even if it slips past review.- Build-time guards fail the production build if either invariant is
broken:
scripts/check-no-network.mjsscansdist/for any network primitive, andscripts/check-no-innerhtml.mjsscanssrc/to preventinnerHTML/outerHTML/insertAdjacentHTML/set:html/document.writefrom ever returning. - DOM-builder helpers (
src/lib/dom.ts:el,frag,mount,text) are the only sanctioned way to render dynamic content. They funnel every string throughcreateTextNode/setAttribute, so escaping is enforced by construction rather than by caller discipline — there is noescapeHtmlto remember to call. - Permissions-Policy disables every powerful browser API the tools do not need (camera, microphone, geolocation, payment, USB, etc.).
- Other hardening headers via meta:
referrer = strict-origin-when-cross-origin,X-Content-Type-Options: nosniff,format-detection: telephone=no. /.well-known/security.txt(RFC 9116) advertises the disclosure channels above.
The repository uses a defensive baseline and expects maintainers to keep these controls enabled in GitHub settings.
- Require pull requests before merging (no direct pushes).
- Require status checks to pass before merging (
CIand deploy checks). - Require up-to-date branches before merge.
- Require conversation resolution before merge.
- Restrict who can push to
main(maintainers only). - Require signed commits where your org/repo policy supports it.
- Pin all third-party actions to full commit SHA (not just mutable tags).
- Use least-privilege permissions at job level.
- Disable credential persistence in checkout steps.
- Keep
fetch-depthminimal unless full history is strictly required. - Install dependencies with
npm ci --ignore-scriptsin CI by default.
- Keep lockfile committed and reviewed in PRs.
- Enable Dependabot security + version updates for npm and GitHub Actions.
- Triage Dependabot alerts promptly.
- Run
npm auditin CI for production dependencies at high severity and above.
- Enable secret scanning and push protection.
- Enable Dependabot alerts.
- Enable Code Scanning (CodeQL) where available.
- Production deployments only from protected
main. - Use GitHub Environments for deploy gates and audit trail.
- Prefer immutable artifacts and reproducible builds.