Security policy
How to report a vulnerability in the SDK or the docs site, what to include, what to expect, and the security properties the SDK is built to keep.
If you find a security problem in @unet/id-web or in this documentation site, please tell us privately, so it can be fixed before it is made public.
How to report
UNET publishes its security contact at unet.social/.well-known/security.txt. Use the contact listed there. Do not open a public issue or post the details anywhere public before a fix is out.
What to include
- What the problem is and which version of the SDK (or which page of the site) it affects.
- The steps to reproduce it: a short program or a sequence of requests is best.
- What an attacker could do with it, and what they would need first.
- Your name or handle if you would like to be credited.
What to expect
We will acknowledge your report, look into it, and tell you what we find. We ask you to keep the details private until a fix has been released, and we will agree the time of disclosure with you. Fixes are made in the latest release, and security fixes are released as soon as they are ready, even when they break something (see Versioning and stability). Credit is given in the changelog if you want it.
What is in scope
- The SDK
@unet/id-web, includingverifyAccessTokenandverifyIdToken. - This documentation site and its examples, if an example teaches something unsafe.
Problems in UNET's servers, apps or accounts, or in a site that uses the SDK, are for the same contact: say what you found and where.
The properties the SDK is built to keep
These are the guarantees the SDK aims to maintain, and the tests it is checked against. A report that shows one of them failing is a security report.
| Property | What it means |
|---|---|
| PKCE | Every sign-in uses PKCE (S256). A code stolen from the return URL cannot be redeemed without the verifier, which never leaves the SDK's storage. |
| State | The return is accepted only if its state matches the pending sign-in and the sign-in is younger than 15 minutes. |
| Issuer checks | The iss of the return must be the configured issuer. The issuer must be https (http on localhost only). |
| Discovery is not trusted blindly | The discovery document must name the issuer you asked, and every endpoint it lists must be https and on that issuer's origin. A cached copy is checked the same way, so a poisoned cache is ignored. |
| Tokens go to UNET only | Access tokens are sent to the SDK's own API origin and the provider's endpoints. api.media() takes only the path of a media address, never its host. |
| Request paths | An id that is not a plain id, or a path with a . or .. segment, is refused before any request is made. |
| Redaction | The onTrace output shortens tokens, codes, verifiers and secrets. |
| Link previews | The address and the picture of a link preview are passed on only if they are absolute http(s) addresses. |
| Checks tied to your app | verifyAccessToken accepts only a live token issued to your own app, and verifyIdToken only a token signed by UNET for your own App ID, with the algorithm fixed to RS256. Neither answers "valid" when it cannot be sure. |
| No dependencies | The package has no runtime dependencies, so there is no third-party code in your bundle through it. |
What the SDK cannot do for you
- Protect against script on your own page. If an attacker can run script in your page, they can read the session, whatever the storage. Use a strict content security policy and keep
"session"storage unless you need"local". - Verify on your server for you. The browser can be made to say anything; see Verify on your server.
- Keep a client secret. A single-page or mobile app is a public app and has none; never put an App Secret in browser code.
See the security checklist for how to use the SDK safely.