We actively support security updates for the following versions:
| Component | Supported Versions |
|---|---|
| synkronus | Latest release and previous major version |
| formulus | Latest release and previous major version |
| formulus-formplayer | Latest release and previous major version |
| synkronus-cli | Latest release and previous major version |
| synkronus-portal | Latest release and previous major version |
Security updates are provided for the latest release and the immediately preceding major version. We recommend keeping all components up to date.
We take security vulnerabilities seriously. If you discover a security vulnerability, please report it responsibly.
Please do NOT report security vulnerabilities through public GitHub issues.
Instead, please report them via one of the following methods:
-
Email: Send details to
security@opendataensemble.orgFor encrypted communication, you can use our PGP public key (see below).
-
GitHub Security Advisory: Use GitHub's private vulnerability reporting feature
For encrypted email communication, use our PGP public key:
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
l0uurTOA9d+hIJbzDg/AIM4=
=zyVP
-----END PGP PUBLIC KEY BLOCK-----
Key ID: 5DD7CEA7D609F145
Email: security@opendataensemble.org
To send an encrypted security report, follow these steps:
- macOS:
brew install gnupgor download from GPG Suite - Linux: Usually pre-installed, or install with
sudo apt install gnupg(Debian/Ubuntu) orsudo yum install gnupg(RHEL/CentOS) - Windows: Download from Gpg4win
- Save the public key block above to a file (e.g.,
ode-public-key.asc) - Import it into your GPG keyring:
gpg --import ode-public-key.asc
- Verify the key was imported:
gpg --list-keys security@opendataensemble.org
Option A: Encrypt a text file
# Create your report file
echo "Your security report details here..." > report.txt
# Encrypt it
gpg --encrypt --armor --recipient security@opendataensemble.org report.txtThis creates report.txt.asc - copy the contents of this file into your email.
Option B: Encrypt directly from command line
echo "Your security report details here..." | gpg --encrypt --armor --recipient security@opendataensemble.org > encrypted_report.ascOption C: Using your email client
Many email clients (Thunderbird with Enigmail, Mail.app with GPG Suite, etc.) can encrypt emails automatically once you have the recipient's public key imported.
- Copy the entire encrypted message block (including
-----BEGIN PGP MESSAGE-----and-----END PGP MESSAGE-----) - Paste it into the body of your email to
security@opendataensemble.org - Send the email (the subject line can remain unencrypted)
# 1. Import the key
gpg --import ode-public-key.asc
# 2. Encrypt your message
echo "Security vulnerability details..." | gpg --encrypt --armor -r security@opendataensemble.org > message.asc
# 3. Copy the contents of message.asc and paste into your email
cat message.asc- "No public key" error: Make sure you imported the key correctly with
gpg --import - "Key not found" error: Try using the email address:
gpg --encrypt --armor -r security@opendataensemble.org - Need help?: If you're having trouble with GPG, you can send an unencrypted email, but we strongly recommend using encryption for sensitive security reports.
When reporting a vulnerability, please include:
- Description: A clear description of the vulnerability
- Component: Which component(s) are affected (synkronus, formulus, formulus-formplayer, etc.)
- Severity: Your assessment of the severity (Critical, High, Medium, Low)
- Steps to Reproduce: Detailed steps to reproduce the issue
- Impact: Potential impact of the vulnerability
- Suggested Fix: If you have ideas for how to fix it (optional but appreciated)
- Acknowledgment: We will acknowledge receipt of your report within 48 hours
- Initial Assessment: We will provide an initial assessment within 7 days
- Updates: We will keep you informed of our progress
- Resolution: We will work to resolve critical vulnerabilities as quickly as possible
- Credit: With your permission, we will credit you in security advisories
- We follow responsible disclosure practices
- We will work with you to coordinate public disclosure after a fix is available
- We aim to provide fixes within 90 days for critical vulnerabilities
- Public disclosure will be made through GitHub Security Advisories
- Strong Secrets: Always use strong, randomly generated JWT secrets
openssl rand -base64 32
- Token Expiration: Tokens expire after 24 hours by default
- Refresh Tokens: Refresh tokens expire after 7 days
- HTTPS Only: Always use HTTPS in production to protect tokens in transit
- Secure Storage: Store tokens securely on clients (e.g., React Native Keychain)
- Roles: The system supports
admin,read-write, andread-onlyroles - Principle of Least Privilege: Grant users only the minimum permissions they need
- Default Admin: Change the default admin password immediately after deployment
- Strong Passwords: Use strong, unique passwords for all accounts
- Password Hashing: Passwords are hashed using bcrypt
- No Default Passwords: Never use default passwords in production
- HTTPS/TLS: All API communications must use HTTPS
- TLS Configuration: Use TLS 1.2 or higher
- Certificate Management: Use Let's Encrypt or similar for automatic certificate management
- Reverse Proxy: Use nginx or similar reverse proxy for TLS termination
- Database Encryption: PostgreSQL encryption at rest depends on the underlying storage layer
- File Storage: Attachments are stored on the filesystem; consider encrypting the filesystem
- Backup Encryption: Encrypt database backups before storing them
- Local-First: The Formulus mobile app stores data locally and only syncs to user-configured servers
- No Third-Party Data Collection: Formulus does not collect or transmit data to third parties
- User Control: Users control their own sync endpoints and data
- Path Traversal Protection: Attachment IDs are validated to prevent directory traversal attacks
- File Size Limits: Multipart form parsing is limited to 32MB by default
- Immutable Attachments: Once uploaded, attachments cannot be modified (new uploads create new files)
- Authentication Required: All attachment endpoints require authentication
- File Type Validation: Consider implementing file type validation (currently not enforced)
- Malware Scanning: Consider implementing malware scanning for uploaded files
- File Type Restrictions: Validate file types and MIME types on upload
- Size Limits: Configure appropriate size limits based on your use case
- Storage Quotas: Implement storage quotas per user or organization
- Secrets Management: Never commit secrets to version control
- Environment Files:
.envfiles are excluded from git (see.gitignore) - Production Secrets: Use secure secret management systems in production (e.g., Docker secrets, Kubernetes secrets, AWS Secrets Manager)
- Rotation: Regularly rotate secrets, especially JWT secrets
The following secrets must be configured securely:
JWT_SECRET: Secret key for JWT token signing (generate withopenssl rand -base64 32)DB_CONNECTION: PostgreSQL connection string (includes password)ADMIN_PASSWORD: Initial admin password (change after first login)- Android signing keys: Keystore files and passwords (stored securely, never committed)
- Never use defaults in production: Default values are for development only
- Change admin credentials: Always change default admin username and password
- Generate strong secrets: Use cryptographically secure random generators
- Image Sources: Use official images from trusted sources (ghcr.io, Docker Hub official images)
- Image Scanning: Scan Docker images for vulnerabilities
- Non-Root Users: Containers run as non-root users where possible
- Minimal Images: Use minimal base images (Alpine Linux) to reduce attack surface
- Secrets Management: Use Docker secrets or environment variables for sensitive data
- Firewall Configuration: Configure firewalls to allow only necessary ports
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable - Internal Networks: Use Docker internal networks for service communication
- Reverse Proxy: Use nginx or similar reverse proxy for TLS termination and rate limiting
- Cloudflare Tunnel: Consider using Cloudflare Tunnel for secure, zero-trust access
- Connection Security: Use SSL/TLS for database connections in production
- Strong Passwords: Use strong, unique passwords for database users
- Access Control: Limit database access to only necessary services
- Backup Security: Encrypt and securely store database backups
- Regular Updates: Keep PostgreSQL updated with security patches
- Secrets Management: Use GitHub Secrets for sensitive CI/CD data
- Build Attestation: Build provenance is generated for Docker images
- Dependency Scanning: Regularly update dependencies and scan for vulnerabilities
- Signed Builds: Android APKs are signed with release keys (stored securely)
- APK Signing: Release builds are signed with secure keystores
- Keystore Protection: Keystore files and passwords are stored securely and never committed
- ProGuard/R8: Code obfuscation and minification for release builds
- Permissions: Request only necessary permissions
- Code Signing: Apps are signed with Apple certificates
- Keychain Storage: Sensitive data (tokens) stored in iOS Keychain
- App Transport Security: Enforces HTTPS connections
- Local Storage: Data stored locally using secure storage mechanisms
- Token Storage: Authentication tokens stored in secure keychain/keystore
- Offline-First: App works offline; data syncs only to user-configured servers
- Schema Validation: All API inputs are validated against OpenAPI schemas
- SQL Injection Prevention: Use parameterized queries (handled by Go database drivers)
- Path Traversal: Attachment paths are validated and sanitized
- Size Limits: Request size limits are enforced
- Recommendation: Implement rate limiting at the reverse proxy level (nginx)
- Authentication Endpoints: Consider stricter rate limiting for login endpoints
- API Endpoints: Implement rate limiting to prevent abuse
- Origin Validation: Configure CORS appropriately for web clients
- Credentials: Handle credentials securely in CORS configuration
- Dependency Scanning: Regularly scan dependencies for known vulnerabilities
- Automated Updates: Use tools like Dependabot or Renovate for automated updates
- Security Advisories: Monitor security advisories for all dependencies
- Reporting: Report dependency vulnerabilities through the same process as code vulnerabilities
- Patching: Critical dependency vulnerabilities are patched as quickly as possible
- Authentication Events: Log authentication successes and failures
- Authorization Failures: Log authorization failures
- Suspicious Activity: Monitor for suspicious patterns
- Error Handling: Avoid logging sensitive information (passwords, tokens, etc.)
- Sensitive Data: Never log passwords, tokens, or other sensitive data
- Log Retention: Implement appropriate log retention policies
- Log Access: Restrict access to logs containing sensitive information
Before deploying to production, ensure:
- All default passwords have been changed
- Strong JWT secret has been generated and configured
- HTTPS/TLS is enabled and properly configured
- Database connection uses SSL/TLS
- Firewall is configured appropriately
- Secrets are stored securely (not in version control)
- Regular backups are configured and tested
- Monitoring and logging are configured
- Dependencies are up to date
- Security updates are applied to the operating system
- Reverse proxy is configured with rate limiting
- File upload limits are configured appropriately
- Admin account password has been changed from default
- Critical Vulnerabilities: Patched within 7 days when possible
- High Severity: Patched within 30 days
- Medium Severity: Patched within 90 days
- Low Severity: Addressed in regular release cycles
- GitHub Security Advisories: Subscribe to GitHub Security Advisories for this repository
- Release Notes: Check release notes for security-related updates
- Changelog: Review changelogs for security fixes
We appreciate security research that helps make ODE more secure. If you're conducting security research:
- Follow Responsible Disclosure: Report vulnerabilities through our reporting process
- Do Not Exploit: Do not exploit vulnerabilities beyond what's necessary to demonstrate them
- Respect Privacy: Do not access or modify user data without permission
- Stay in Scope: Focus on the ODE codebase and infrastructure
For security-related questions or concerns:
-
Security Email:
security@opendataensemble.org -
Website: https://opendataensemble.org
We thank all security researchers and contributors who help keep ODE secure. Security researchers who responsibly disclose vulnerabilities will be credited (with permission) in security advisories.
Last Updated: 2025-01-14
Note: This security policy is a living document and will be updated as the project evolves. Please check back periodically for updates.