151 lines
5.3 KiB
Markdown
151 lines
5.3 KiB
Markdown
|
|
# Threat Model
|
||
|
|
|
||
|
|
Bliish.space intentionally allows user-controlled profiles. That makes security boundaries explicit and non-optional.
|
||
|
|
|
||
|
|
## Assets
|
||
|
|
|
||
|
|
- Account credentials.
|
||
|
|
- Session tokens.
|
||
|
|
- CSRF tokens.
|
||
|
|
- Email addresses.
|
||
|
|
- Profile data.
|
||
|
|
- Uploaded profile images, post images, and audio.
|
||
|
|
- Private profile visibility.
|
||
|
|
- Admin actions, reports, and automod rules.
|
||
|
|
- SQLite database and uploads directory.
|
||
|
|
|
||
|
|
## Actors
|
||
|
|
|
||
|
|
- Anonymous visitor.
|
||
|
|
- Signed-up user.
|
||
|
|
- Profile owner.
|
||
|
|
- Friend.
|
||
|
|
- Moderator.
|
||
|
|
- Admin.
|
||
|
|
- Instance operator.
|
||
|
|
- Malicious user.
|
||
|
|
- Compromised reverse proxy or host.
|
||
|
|
|
||
|
|
## Trust Boundaries
|
||
|
|
|
||
|
|
- Browser to Hono request.
|
||
|
|
- Cookie/session middleware to route handlers.
|
||
|
|
- Form parser to validators.
|
||
|
|
- Sanitizer to HTML renderer.
|
||
|
|
- Upload parser to filesystem.
|
||
|
|
- Route handler to SQLite query module.
|
||
|
|
- Admin-only routes.
|
||
|
|
- Reverse proxy to app process.
|
||
|
|
|
||
|
|
## Primary Risks
|
||
|
|
|
||
|
|
### Cross-Site Scripting
|
||
|
|
|
||
|
|
Risk: profile bio, skin HTML, posts, comments, blogs, private messages, and reports render user content.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- sanitize before storage;
|
||
|
|
- restrict tags, attributes, schemes, and inline styles;
|
||
|
|
- allow skin CSS only through the skin sanitizer, which strips active code, unsafe URL schemes, arbitrary CSS attribute selectors, high-risk selector functions, and absolute/fixed/sticky positioning, while keeping page-level skin selectors variable-only and preserving documented profile skin hooks;
|
||
|
|
- allow skin resource URLs only when they are local paths or HTTPS URLs;
|
||
|
|
- allow iframe embeds only for host/path-validated mainstream player URLs, with fixed sandbox and referrer policy attributes;
|
||
|
|
- avoid rendering raw input;
|
||
|
|
- keep sanitizer tests near sanitizer code;
|
||
|
|
- render stored sanitized HTML through the shared `trustedHtml` boundary, and treat any direct `dangerouslySetInnerHTML` use as security-sensitive.
|
||
|
|
|
||
|
|
### CSRF
|
||
|
|
|
||
|
|
Risk: form-first app has many mutating POST routes.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- form-based mutations require CSRF tokens;
|
||
|
|
- mutating form actions use per-action rate limits backed by short-lived SQLite counters keyed to accounts or submitted form subjects;
|
||
|
|
- invalid tokens return 403;
|
||
|
|
- cookies use SameSite=Lax;
|
||
|
|
- destructive forms stay POST-only.
|
||
|
|
|
||
|
|
Email verification is the exception: `/verify/:token` consumes a one-time token stored as a hash in SQLite because the token itself authorizes that action.
|
||
|
|
|
||
|
|
### Session Theft
|
||
|
|
|
||
|
|
Risk: stolen session token gives account access.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- random opaque tokens;
|
||
|
|
- store only token hashes;
|
||
|
|
- HTTP-only cookie;
|
||
|
|
- secure cookies when base URL is HTTPS;
|
||
|
|
- revocation on logout.
|
||
|
|
|
||
|
|
### Upload Abuse
|
||
|
|
|
||
|
|
Risk: executable files, oversized files, or disguised content.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- size cap;
|
||
|
|
- request body size cap before form parsing;
|
||
|
|
- allowed MIME and extension;
|
||
|
|
- file signature validation;
|
||
|
|
- local image normalization before storage;
|
||
|
|
- random filenames;
|
||
|
|
- separate upload buckets for profile images, post images, and theme songs;
|
||
|
|
- uploads stored under the configured upload directory;
|
||
|
|
- production deployment docs place uploads under `/var/lib/bliishspace/uploads`;
|
||
|
|
- local development defaults use `data/uploads`, which is ignored by git.
|
||
|
|
|
||
|
|
### Authorization Bypass
|
||
|
|
|
||
|
|
Risk: user mutates or reads resources they should not access.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- route-level auth checks;
|
||
|
|
- owner/admin checks before edit/delete;
|
||
|
|
- moderator checks for report queue actions, with role hierarchy checks before staff can delete content or ban an author;
|
||
|
|
- admin-only automod rule management, with rule length limits, regex compile validation, scan length caps, default critical rule packs, evasion-aware text normalization, and review matches routed through the same moderated report queue;
|
||
|
|
- private profile checks on direct profile, profile friends, profile blog, and wall routes;
|
||
|
|
- group post creation, props, and comments require group membership;
|
||
|
|
- protected admin friendship and default group membership checks prevent users from disconnecting from the instance admin account or leaving group id `1`;
|
||
|
|
- per-entry blog privacy checks for public, friends-only, and private diary entries;
|
||
|
|
- admin routes require the `admin` role; report moderation routes require a staff role with moderation capability.
|
||
|
|
|
||
|
|
### Open Redirect
|
||
|
|
|
||
|
|
Risk: attacker abuses redirect after delete actions.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- redirects from request headers are restricted to local paths or same-origin URLs.
|
||
|
|
|
||
|
|
### Third-Party Profile Resources
|
||
|
|
|
||
|
|
Risk: customized skins can cause visitor browsers to fetch HTTPS images, CSS backgrounds, Google Fonts resources, or whitelisted embedded players chosen by profile authors.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- remote resources are limited to HTTPS URLs by the skin sanitizer;
|
||
|
|
- iframe embeds are limited to mainstream player URLs such as YouTube, SoundCloud, Vimeo, Spotify, Bandcamp, TikTok, and Dailymotion, rewritten or validated by the skin sanitizer, sandboxed, and constrained by CSP `frame-src`;
|
||
|
|
- ordinary user text fields do not allow image tags;
|
||
|
|
- instance operators can tighten `sanitizeSkinHtml` and CSP if they want local-only skin assets.
|
||
|
|
|
||
|
|
### Data Loss
|
||
|
|
|
||
|
|
Risk: SQLite file or uploads are lost or corrupted.
|
||
|
|
|
||
|
|
Controls:
|
||
|
|
|
||
|
|
- WAL mode;
|
||
|
|
- documented backup and restore;
|
||
|
|
- uploads and database kept in predictable directories.
|
||
|
|
|
||
|
|
## Residual Risks
|
||
|
|
|
||
|
|
- Sanitizer policy may need tightening as skin support expands.
|
||
|
|
- Instance operators can weaken privacy with proxy logs or CDN configuration.
|
||
|
|
- New features may miss moderation edge cases.
|
||
|
|
- Deleted data can remain in backups outside the app.
|