Security
Nocly Shortener is built to run safely on shared hosting. This page explains the protections and the settings you control.
Built-in protections
| Area | Protection |
|---|---|
| Forms | Every form has a CSRF token and the request origin is checked |
| Output | All user content is escaped; a strict Content Security Policy allows no inline scripts |
| Database | Every query uses prepared statements |
| Destinations | Only http/https; private and local network addresses, redirect loops and blocklisted domains or keywords are refused |
| Outgoing requests | Webhooks and domain checks only connect to public IP addresses, pinned after DNS lookup, and never follow redirects |
| Files | app, config, storage and database are blocked from the web; uploads can never execute code |
| Passwords | Hashed with PHP password_hash; a minimum length is enforced |
| Sessions | HttpOnly, SameSite cookies (Secure and __Host- prefixed on HTTPS), rotated on sign-in, stored server-side and revocable |
| API keys | Stored as one-way HMAC hashes; shown only once |
| Secrets | SMTP password and webhook secrets are encrypted with the application key |
| Errors | Details are logged, never shown to visitors |
| Audit log | Important actions are recorded in a hash chain; any modification is detected by Verify integrity |
Response headers include Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and Permissions-Policy, plus Strict-Transport-Security when HSTS is on.
Rate limits
| Action | Default |
|---|---|
| Sign-in attempts | 10 per 15 minutes per account and network (30 per network); after 5 failures that network is paused for 15 minutes for that account. Other networks, including the owner's, are not locked out. A cap of 100 attempts per 15 minutes per account slows attacks spread over many networks; networks the user has signed in from before are exempt. IPv6 addresses are grouped by /64 |
| Registration | 5 per hour per IP |
| Password reset | 5 per hour |
| Link creation | 30 per minute per user |
| API | 120 requests per minute per key |
| Password-protected links | 10 attempts per 15 minutes |
| Abuse reports | 10 per hour per IP |
Change them in Admin → Settings → Security.
Roles
| Role | Can |
|---|---|
| User | Manage their own links, analytics, domains, API keys and webhooks |
| Admin | Everything users can, plus manage users, all links, domains, API keys, webhooks, abuse reports, blocklists, system logs and health |
| Super admin | Everything, plus settings, branding, security, maintenance, cron, backups, restore, audit logs and changing roles |
Permissions are checked on the server for every request. Other users' resources return Not found.
Abuse handling
Anyone can report a link at /report. Administrators review reports in Admin → Abuse reports, can disable or block links, suspend users and maintain blocklists of domains, keywords and email domains. Every moderation action is audited.
Recommendations
- Use HTTPS on every domain and turn on HSTS.
- Keep PHP updated through cPanel.
- Use a strong, unique super administrator password and keep the number of super admins small.
- Keep regular backups outside the server.
- Review System health and the Audit log from time to time.
- Only add
security.trusted_proxiesfor proxies you actually use.