You've already forked openaccounting-server
forked from cybercinch/openaccounting-server
feat: implement secure file upload system with JWT authentication
- Add JWT-based secure file access for local storage with 1-hour expiry - Implement GORM repository methods for attachment CRUD operations - Add secure file serving endpoint with token validation - Update storage interface to support user context in URL generation - Add comprehensive security features including path traversal protection - Update documentation with security model and configuration examples - Add utility functions for hex/byte conversion and UUID validation - Configure secure file permissions (0600) for uploaded files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
53
STORAGE.md
53
STORAGE.md
@@ -14,7 +14,8 @@ Perfect for self-hosted deployments or development environments.
|
||||
"backend": "local",
|
||||
"local": {
|
||||
"root_dir": "./uploads",
|
||||
"base_url": "https://yourapp.com/files"
|
||||
"base_url": "https://yourapp.com/files",
|
||||
"signing_key": "your-secret-jwt-signing-key"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,8 +26,16 @@ Perfect for self-hosted deployments or development environments.
|
||||
OA_STORAGE_BACKEND=local
|
||||
OA_STORAGE_LOCAL_ROOT_DIR=./uploads
|
||||
OA_STORAGE_LOCAL_BASE_URL=https://yourapp.com/files
|
||||
OA_STORAGE_LOCAL_SIGNINGKEY=your-secret-jwt-signing-key
|
||||
```
|
||||
|
||||
**Security Features:**
|
||||
- **JWT Token Access**: Files are served through secure JWT tokens with 1-hour expiry
|
||||
- **Secure File Permissions**: Files created with 0600 permissions (owner read/write only)
|
||||
- **Time-Limited URLs**: All file access URLs expire automatically
|
||||
- **Path Traversal Protection**: Comprehensive validation prevents directory traversal attacks
|
||||
- **No Direct File Access**: Files cannot be accessed without valid authentication tokens
|
||||
|
||||
### 2. Amazon S3 Storage
|
||||
Reliable cloud storage for production deployments.
|
||||
|
||||
@@ -137,7 +146,9 @@ The original transaction-scoped endpoints remain available for backward compatib
|
||||
- **File size limits** - Configurable maximum file size (default 10MB)
|
||||
- **Path traversal protection** - Prevents directory traversal attacks
|
||||
- **Access control** - Files are linked to users and organizations
|
||||
- **Presigned URLs** - Time-limited access for cloud storage
|
||||
- **Time-limited access** - JWT tokens for local storage, presigned URLs for cloud storage
|
||||
- **Secure file permissions** - Local files created with restricted permissions (0600)
|
||||
- **Cryptographic security** - HMAC-SHA256 signed JWT tokens prevent tampering
|
||||
|
||||
## File Organization
|
||||
|
||||
@@ -161,7 +172,8 @@ uploads/
|
||||
"storage": {
|
||||
"backend": "local",
|
||||
"local": {
|
||||
"root_dir": "./dev-uploads"
|
||||
"root_dir": "./dev-uploads",
|
||||
"signing_key": "dev-secret-key-change-in-production"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,6 +207,41 @@ uploads/
|
||||
}
|
||||
```
|
||||
|
||||
## Local Storage Security (JWT Tokens)
|
||||
|
||||
Local storage now implements JWT-based security matching the security model of S3 presigned URLs:
|
||||
|
||||
### How It Works
|
||||
1. **File Upload**: Files are stored with secure permissions (0600) in date-organized directories
|
||||
2. **URL Generation**: When requesting file access, the server generates a JWT token containing:
|
||||
- File path
|
||||
- User ID and Organization ID (for audit trails)
|
||||
- Expiry time (default 1 hour)
|
||||
- Cryptographic signature (HMAC-SHA256)
|
||||
3. **File Access**: Files are served through `/secure-files?token=...` endpoint with token validation
|
||||
4. **Security**: Tokens expire automatically and cannot be tampered with
|
||||
|
||||
### JWT Token Example
|
||||
```
|
||||
/secure-files?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
### Security Benefits
|
||||
- **Time-Limited Access**: URLs expire after 1 hour by default
|
||||
- **Tamper-Proof**: HMAC-SHA256 signatures prevent token modification
|
||||
- **Audit Trail**: Tokens include user and organization context
|
||||
- **No Direct Access**: Files cannot be accessed without valid tokens
|
||||
- **Secure Permissions**: Files created with 0600 permissions (owner only)
|
||||
|
||||
### Signing Key Configuration
|
||||
The signing key should be:
|
||||
- **Unique per deployment** to prevent cross-deployment token reuse
|
||||
- **Kept secret** and not committed to version control
|
||||
- **At least 32 characters** for security (recommended)
|
||||
- **Set via environment variable** `OA_STORAGE_LOCAL_SIGNINGKEY`
|
||||
|
||||
If no signing key is provided, the server will auto-generate one (but tokens won't persist across restarts).
|
||||
|
||||
## Migration Between Storage Backends
|
||||
|
||||
When changing storage backends, existing attachments will remain in the old storage location. The database records contain the storage path, so files can be accessed until migrated.
|
||||
|
||||
Reference in New Issue
Block a user