Security
Nexo Share is built as a secure, self-hosted alternative to public file transfer services. This guide covers security features (2FA with admin enforcement, passkeys, ClamAV, SSO), hardening, and best practices.
Security Architecture
Defense in Depth
Nexo Share implements multiple security layers:
- Network: HTTPS, firewall, rate limiting
- Application: Input validation, CSRF protection, secure headers
- Authentication: Strong passwords, 2FA, passkeys, session management
- Authorization: Role-based access control (RBAC)
- Data: Encryption at rest (database), in transit (HTTPS)
- Files: Virus scanning, type validation, isolated storage
Threat Model
Nexo Share protects against:
- Unauthorized Access: Authentication, authorization, session management
- Data Breaches: Encryption, access controls, audit logging
- Malware: ClamAV virus scanning, file type validation
- Injection Attacks: Input sanitization, parameterized queries
- CSRF/XSS: Security headers, token validation, content sanitization
- Brute Force: Rate limiting, account lockout (via rate limits)
- SSRF: Private IP blocking, URL validation
Authentication Security
Password Requirements
Enforced minimum requirements:
- At least 8 characters
- 1+ uppercase letter (A-Z)
- 1+ lowercase letter (a-z)
- 1+ number (0-9)
Recommendations:
- Use 16+ character passwords
- Avoid dictionary words
- Use unique passwords per service
- Consider password managers
Password Storage
- Hashed with bcrypt (cost factor 10)
- Salted automatically
- Never stored in plaintext
- Timing-attack resistant comparison
Two-Factor Authentication
TOTP-based (Time-based One-Time Password):
- Compatible with all authenticator apps
- Secret encrypted with AES-256-GCM
- 6-digit codes, 30-second window
- 2-code tolerance for clock drift
Backup Codes:
- 8 codes generated at setup
- SHA-256 hashed before storage
- Single-use (deleted after use)
- Downloadable for offline storage
Admin Controls:
- Force 2FA for all users
- Emergency 2FA reset
- Audit logging of 2FA events
Passkeys (WebAuthn)
Phishing-Resistant:
- Cryptographic authentication
- Biometric or hardware-based
- Origin-bound (can’t be phished)
- No password needed
Implementation:
- FIDO2/WebAuthn standard
- Public key cryptography
- Counter-based replay protection
- Multiple devices supported
Security Benefits:
- Impossible to phish
- No password reuse
- No credential database breach risk
- Biometric privacy (keys never leave device)
Session Management
JWT Tokens:
- Signed with HS256 (HMAC-SHA256)
- 512-bit secret (64 hex characters)
- Configurable expiration (default: 7 days)
- Automatic expiration handling
Cookies:
HttpOnlyflag (XSS protection)Secureflag in production (HTTPS only)SameSite: strict(CSRF protection)- Automatic cleanup on logout
Security Recommendations:
- Keep sessions short for sensitive environments
- Enable secure cookies (requires HTTPS)
- Rotate JWT secret periodically
Input Validation & Sanitization
File Uploads
Type Validation:
- Configurable Blocklist: Admins can block specific extensions via the UI
- Separate Policies: Distinct blocklists for internal users and external guests
- MIME type checking
- Double extension detection (
.php.jpg) - Maximum file size limits
Virus Scanning:
- Real-time ClamAV integration
- Automatic virus definition updates
- Infected files rejected immediately
- Fail-closed mode available
Storage Isolation:
- Files stored outside web root
- Unique, random filenames
- No execution permissions
- Separate folders per share
Secure Staging:
- Randomized IDs: Temporary files use cryptographically random 32-character IDs, preventing enumeration attacks during upload.
- Client-Side Rendering: File previews (Word, Excel, PDF) are rendered entirely in the browser. The server never converts or executes user-submitted files.
- Sanitization: All preview content is passed through
DOMPurifyto neutralize XSS vectors before display.
User Input
Email Addresses:
- RFC-compliant validation
- Domain verification (require TLD)
- Header injection prevention
- Blacklist for invalid patterns
Text Fields:
- Length limits enforced
- HTML/JavaScript stripped (except specific fields)
- SQL injection prevention (parameterized queries)
- Special character escaping
Passwords:
- Complexity requirements
- Length limits (8-128 chars)
- No truncation
- Hashed immediately after receipt
Network Security
HTTPS (TLS)
Requirements:
- TLS 1.2+ only
- Strong cipher suites
- Valid certificate (Let’s Encrypt recommended)
- HTTP to HTTPS redirect
Security Headers:
Nexo Share sets these automatically:
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; img-src 'self' data: blob: https:; ...
HSTS (HTTP Strict Transport Security):
- Forces HTTPS for 1 year
- Prevents SSL stripping attacks
- Applied in production only
CORS (Cross-Origin Resource Sharing)
Configuration:
ALLOWED_ORIGINS: "https://share.company.com,https://share.company.nl"
Restrictions:
- Only specified origins allowed
- Credentials required
- Preflight validation
- No wildcards in production
Rate Limiting
Per-IP address limits:
| Action | Limit | Window |
|---|---|---|
| Login | 5 attempts | 15 min |
| Password Reset | 3 requests | 1 hour |
| Upload Chunks | 10,000 | 1 hour |
| Downloads | 100 | 1 hour |
Implementation:
- In-memory tracking
- Automatic cleanup
- Generic error messages (no enumeration)
Authorization & Access Control
Role-Based Access Control
User Role:
- Upload files
- Create shares
- Manage own shares
- View own profile
- Enable 2FA/passkeys
Admin Role:
- All user permissions
- Manage users
- Configure system
- View audit logs
- Force 2FA resets
Enforcement:
- Every API endpoint checks permissions
- Database-level constraints
- No privilege escalation possible
Share Access
Password-Protected Shares:
- bcrypt-hashed passwords
- Generic error messages
- Rate-limited attempts
- No password in URL
Link-Based Access:
- Cryptographically random IDs (12+ chars)
- 62^12 = 3.2 trillion combinations
- Time-limited (optional)
- Download count limits (optional)
Data Protection
Encryption
In Transit:
- HTTPS/TLS for all connections
- Certificate pinning (client-side)
At Rest:
- Database credentials encrypted in environment
- JWT secrets rotated periodically
- 2FA secrets encrypted with AES-256-GCM
- Backup codes hashed with SHA-256
Not Encrypted:
- Upload files (stored as-is for performance)
- Consider filesystem encryption (LUKS, dm-crypt) for sensitive environments
Data Minimization
Principles:
- Collect only necessary data
- Auto-delete expired shares
- No tracking/analytics
- Minimal logging (audit only)
Retention:
- Shares deleted after expiration
- Logs deleted after 1 year
- Temp files cleaned every 15 minutes
- Orphaned data cleaned hourly
Privacy
User Data:
- Email required for account creation
- Name required but can be pseudonym
- IP addresses logged for security only
- No third-party services
Share Metadata:
- Not indexed by search engines
- Not publicly listed
- Share IDs are random
- No filename in URLs
Vulnerability Mitigation
SQL Injection
Prevention:
- Parameterized queries (100% of database calls)
- ORM/query builder where possible
- Input validation
- Principle of least privilege
Example (Safe):
pool.query('SELECT * FROM users WHERE email = $1', [userEmail]);
Cross-Site Scripting (XSS)
Prevention:
- Content Security Policy (CSP)
- Input sanitization (DOMPurify)
- Output encoding
- HttpOnly cookies
CSP Policy:
default-src 'self';
script-src 'self' 'unsafe-inline';
img-src 'self' data: blob: https:;
Cross-Site Request Forgery (CSRF)
Prevention:
- SameSite cookies (
strict) - Double-submit cookie pattern
- Origin header validation
- CORS enforcement
Server-Side Request Forgery (SSRF)
Prevention:
- Private IP blocking (169.254.169.254, 127.0.0.1, etc.)
- URL validation
- Protocol whitelist (http/https only)
- DNS rebinding protection
Blocked IPs:
127.0.0.0/8(localhost)10.0.0.0/8(private)172.16.0.0/12(private)192.168.0.0/16(private)169.254.0.0/16(link-local)- Cloud metadata services
Path Traversal
Prevention:
path.basename()for filenames- Filesystem jails (Docker volumes)
- Whitelist directories
- No direct user-provided paths
Email Header Injection
Prevention:
- Newline/carriage return stripping
- Email validation
- Header length limits
- Sanitized sender names
Audit & Monitoring
Audit Logging
Logged Events:
- User login/logout
- Share creation/deletion
- File downloads
- Admin actions
- 2FA changes
- Configuration updates
Log Contents:
- User ID
- Action type
- Resource type/ID
- IP address
- User agent
- Timestamp
- Additional details (JSON)
Security:
- Logs cannot be modified by users
- Admin-only access
- Automatic cleanup (1 year retention)
Security Monitoring
Indicators to Watch:
- Failed logins: Brute force attempts
- Rate limit hits: Potential abuse
- Large file uploads: Quota bypass attempts
- Repeated 401/403: Authorization probing
- Virus detections: Malware distribution
Review Regularly:
# Failed logins
docker compose logs nexoshare | grep "Invalid credentials"
# Rate limits hit
docker compose logs nexoshare | grep "429"
# Virus detections
docker compose logs nexoshare | grep -i "virus"
Security Hardening
System Level
Docker Security:
Nexo Share:
security_opt:
- no-new-privileges:true
read_only: true # Make filesystem read-only
tmpfs:
- /tmp
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
File Permissions:
# Uploads folder
chmod 750 ./uploads
chown 1000:1000 ./uploads # Node user in container
# Config files
chmod 600 docker-compose.yml
Firewall:
# Allow only necessary ports
sudo ufw allow 22/tcp # SSH
sudo ufw allow 443/tcp # HTTPS
sudo ufw deny 3000/tcp # Block direct access
sudo ufw enable
Application Level
Enable All Security Features:
- Settings → General → Secure Cookies ✓
- Settings → Security → Require 2FA ✓
- Settings → System → Enforce Virus Scan ✓
- Settings → Security → Strong Session Duration
Disable Unnecessary Features:
- Password reset (if using SSO only)
- Passkeys (if not needed)
- Guest uploads (reverse shares)
Regular Updates:
docker compose pull
docker compose up -d
Database Hardening
Connection Security:
postgres:
environment:
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
command: >
postgres
-c ssl=on
-c max_connections=50
Backup Encryption:
# Encrypted backup
docker compose exec postgres pg_dump -U nexoshare nexoshare | \
gpg --symmetric --cipher-algo AES256 > db_backup.sql.gpg
Security Checklist
Before Going Live
- HTTPS with valid certificate
- Secure cookies enabled
- Strong JWT secret (64 hex chars)
- Strong database password
- Firewall configured
- 2FA enforced for admins
- Virus scanning enabled
- Rate limiting active
- CORS configured correctly
- Regular backups scheduled
- Security headers verified
- Admin password changed from default
- Test account deleted
- Audit logging enabled
Monthly Tasks
- Review audit logs
- Check for failed login attempts
- Verify backups are working
- Update Docker images
- Review user accounts
- Check ClamAV virus definitions
- Monitor disk space
- Review rate limit hits
Quarterly Tasks
- Test backup restore
- Rotate JWT secret
- Rotate database password
- Security audit
- Review access controls
- Update documentation
- Penetration test (if required)
Incident Response
Security Breach Detected
-
Isolate: Take system offline immediately
docker compose down -
Assess: Review audit logs
docker compose logs > incident_$(date +%Y%m%d).log -
Contain: Reset compromised credentials
- Rotate JWT secret
- Reset database password
- Force all users to re-login
-
Recover: Restore from clean backup if needed
-
Learn: Document incident, update procedures
Malware Detected
-
Identify: Check ClamAV logs for filename/share
docker compose logs nexoshare | grep -i virus -
Quarantine: File is automatically deleted by ClamAV
-
Notify: Contact share owner if known
-
Investigate: Check if malware was downloaded
docker compose logs nexoshare | grep "download" | grep "{share-id}" -
Update: Ensure virus definitions are current
Responsible Disclosure
Found a security vulnerability?
Do:
- Email security details privately
- Provide reproduction steps
- Wait for acknowledgment before public disclosure
Don’t:
- Post publicly on GitHub issues
- Exploit in production systems
- Share with others before fix is available
Contact: Create private security advisory on GitHub or email project maintainer.
Response Time: Acknowledgment within 48 hours, fix within 7-14 days depending on severity.
Security Resources
- OWASP Top 10: https://owasp.org/www-project-top-ten/
- Docker Security: https://docs.docker.com/engine/security/
- PostgreSQL Security: https://www.postgresql.org/docs/current/security.html
- WebAuthn Guide: https://webauthn.guide/
- Content Security Policy: https://content-security-policy.com/
Compliance Considerations
While Nexo Share is not certified for specific compliance frameworks, it includes features that help meet common requirements:
GDPR:
- Data minimization
- Right to deletion (user can delete account)
- Audit logging
- Encryption in transit
HIPAA/HITECH (requires additional measures):
- Encryption at rest (enable filesystem encryption)
- Access controls
- Audit logging
- Automatic session timeout
SOC 2:
- Access controls
- Audit logging
- Encryption
- Availability monitoring
Note: Compliance requires organizational policies and procedures beyond technical controls. Consult with compliance professionals for your specific requirements.