Security Architecture & Hardening

Standalone Qwiki applies defense-in-depth across filesystem access, authentication, remote fetching, and user-supplied markup.

Filesystem & Path Traversal Controls

  • Boundary-Checked Path Resolution: File operations pass relative paths through Config::safePath(), verifying resolved realpath() targets remain strictly inside the wiki root.
  • Directory Guards: content/, content/.locks/, content/.logs/, data/, data/trash/, data/revisions/, and data/talk/ include dual Apache 2.2/2.4 .htaccess Deny from all / Require all denied directives, and index.php rejects direct routing into data/ or content/.
  • Extension Whitelisting: Headless uploads (api/publish.php) restrict media strictly to whitelisted image (png, jpg, jpeg, gif, svg, webp) and video (mp4, webm, ogg, ogv, mov) extensions and sanitize filenames before writing into uploads/images/ or uploads/videos/.

Authentication & Session Security

  • Password Hashing: User passwords in users.json are hashed via PHP's password_hash() (Bcrypt) and verified with password_verify().
  • Constant-Time Token Checks: API keys (publishApiKey, llmKeys) and feed tokens (feedAccessToken) use hash_equals() comparisons.
  • Stateless Password Reset Tokens: Signed with HMAC-SHA256 incorporating the user's current password hash so tokens auto-invalidate immediately upon password change.
  • Private Portal Isolation: When requireLoginToView is enabled, unauthenticated requests receive an isolated login gateway without leaking sidebar navigation, document titles, search results, or RSS items.

SSRF & XSS Defenses

  • Remote Transclusion SSRF Guard (RemoteContentManager::validateUrlSafety()): Allows only http/https schemes, blocks localhost, localhost.localdomain, and .local hosts, resolves DNS, and enforces FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE so attackers cannot probe internal RFC 1918 networks, loopback (127.0.0.1 / ::1), or cloud metadata IPs (169.254.169.254).
  • XSS Neutralization: Comments and Talk Page inputs strip unsafe markup; headless HTML publishing (api/publish.php) preserves , `@media print`, SVG, and tags for self-contained reports while stripping dangerous script injection vectors.