Skip to content

Security

Security overview

How Gradency protects your account and your students’ data — and what we don’t claim.

At a glance

Sessions
HttpOnly cookies + CSRF
2FA
TOTP with backup codes
Isolation
Cross-account requests return 404
Uploads
Type, size and encrypted-PDF checks
Rate limits
Login 5/min per IP
Frontend
CSP header, sanitized math
What we don’t claim

Gradency has not undergone third-party penetration testing or compliance certification (SOC 2, ISO 27001 or similar). If your institution works under specific regulatory requirements (FERPA, HIPAA or similar), contact us before uploading student data.

Authentication

  • Passwords hashed with bcrypt (cost factor 12) — never stored or logged in plaintext.
  • Session tokens (JWT) live in HttpOnly, SameSite=Strict cookies. JavaScript cannot read them, so XSS attacks cannot exfiltrate sessions.
  • CSRF protection via the double-submit-cookie pattern: every mutating request requires a matching X-CSRF-Token header.
  • Login rate-limited to 5 attempts per minute per IP.
  • Optional two-factor sign-in (authenticator app) with single-use backup codes; turning it on or off signs out your other sessions.
  • Changing your password immediately invalidates all existing sessions across devices.
  • API keys are stored only as hashes; webhook URLs are checked against private and internal network addresses.

Authorization

  • Every protected endpoint loads resources through a single ownership-verifying helper. Cross-user attempts return HTTP 404 (not 403) to avoid existence-leak side channels.
  • Admin endpoints require an explicit admin role check.
  • The cross-user contract is covered by the automated test suite.

Data protection

  • All traffic is served over HTTPS (TLS).
  • Database access requires authenticated connections inside our private network.

Input validation

  • All API inputs are validated by Pydantic schemas.
  • SQL queries are parameterized — SQL injection is prevented by design.
  • File uploads go through MIME validation, size caps, and chunked streaming (no full-file slurping).
  • Encrypted/password-protected PDFs are rejected at upload with a clear error.
  • Path-traversal attempts (../, URL-encoded variants, NUL bytes) are rejected at the route level.

Frontend hardening

  • A Content-Security-Policy header limits scripts and network requests to our own origin and stops other sites from framing Gradency. It still allows inline scripts — the framework’s page bootstrap and the script that applies your light or dark theme before the page paints — so it is not a strict, nonce-based policy.
  • The only exception to the no-framing rule is the small Canvas launch page, which only the Canvas sites registered for your institution can display. One page is an exception: the Google Drive import page also allows scripts and frames from Google (apis.google.com, accounts.google.com, docs.google.com, drive.google.com) so it can show Google’s file picker. No other page loads Google’s scripts.
  • Math rendering (KaTeX) runs with trust: false; output sanitized through DOMPurify with a strict allowlist.
  • PDF rendering uses pdfjs-dist 4.x (CVE-2024-4367 patched).

Operational

  • Dependencies are pinned to versions patched for known CVEs.
  • Production environment requires explicit non-default secrets (the application refuses to boot otherwise).
  • Health endpoints (/health/live, /health/ready) for liveness and readiness probes.

Reporting a vulnerability

Found a security issue? We want to know — please use our contact page and pick the “Security disclosure” subject. Please give us reasonable time to respond before public disclosure; we treat security reports with priority.