09.01 The Encryption Extra Overview
The Encryption Extra (also called the Encrypted Database Extra) protects sensitive SimpleRisk fields from database exfiltration by encrypting them at rest with AES-256-CBC plus HMAC-SHA256 authentication. A single per-install master key (stored in extras/encryption/includes/init.php) encrypts roughly 30 sensitive fields across risks, assets, frameworks, mitigations, audits, and custom data.
Requires: Encryption Extra
Encryption-at-rest for SimpleRisk's sensitive fields is added by the Encryption Extra at
simplerisk/extras/encryption/. The Extra is also labeled "Encrypted Database Extra" in some surfaces; both names refer to the same Extra.
Why this matters
A database with sensitive content (risk descriptions naming specific systems, audit findings citing unmitigated vulnerabilities, control test results detailing security gaps) is a high-value exfiltration target. A backup file copied to a thumb drive, a SQL injection that dumps a table, a misconfigured database that's exposed to the internet, a forensic image taken during an incident: all produce a database file in someone else's hands. Without encryption-at-rest, that file is plaintext; with encryption-at-rest, it's an opaque blob.
The Encryption Extra applies AES-256-CBC encryption to the most sensitive fields in the SimpleRisk schema. Roughly 30 fields across the risk register, asset inventory, framework definitions, mitigation plans, audit logs, and custom data become ciphertext at rest. The application transparently encrypts on write and decrypts on read; users and the UI experience the data normally.
The honest scope to know up front: this protects against database exfiltration; it doesn't protect against active runtime attack. An attacker who gains code execution on the SimpleRisk server (via a vulnerability in the application, an OS-level compromise, a malicious admin) reads the master key from disk and decrypts data in memory just like the application does. Encryption-at-rest raises the bar against database-only attacks; it doesn't raise the bar against full-server compromise.
The other thing worth knowing: the master key is a single per-install secret stored on the file system. It's at simplerisk/extras/encryption/includes/init.php after activation. Lose this file and your encrypted data is unrecoverable — there's no recovery service, no Anthropic-side key escrow, no backdoor. Backup discipline for this file is non-negotiable; treat it like the most-important credential in your environment.
The third thing: activation isn't reversible without effort, and only forward. Once you encrypt, the data lives encrypted. You can deactivate the Extra (which decrypts everything in place — see the deactivation flow below), but the activation step takes time on large installs and can't be partially undone mid-migration. Plan the activation as a maintenance event with a tested rollback path.
How frameworks describe this
Encryption-at-rest is specifically called out by every major security framework as a control for protecting sensitive data:
- NIST SP 800-53 SC-28 (Protection of Information at Rest) requires the system to protect the confidentiality and integrity of information at rest with appropriate cryptographic mechanisms. The Encryption Extra implements this for SimpleRisk's sensitive fields.
- NIST CSF v2.0 under Protect.DS (Data Security) treats data-at-rest protection as a default expectation; lack of it is a gap that auditors flag.
- ISO/IEC 27001 Annex A
A.8.24(Use of cryptography) covers the policy and implementation expectations; encryption-at-rest for sensitive data is the canonical implementation. - PCI DSS v4.0 Requirement 3.5 mandates encryption of stored cardholder data; while SimpleRisk doesn't store cardholder data directly, programs in PCI-relevant environments often extend the requirement to other sensitive data classes.
- HIPAA Security Rule §164.312(a)(2)(iv) (Encryption and Decryption) identifies encryption as an addressable specification for ePHI; healthcare programs running SimpleRisk for HIPAA-related GRC typically activate encryption.
The takeaway: encryption-at-rest is an expected baseline for any program holding sensitive content, and the Encryption Extra is SimpleRisk's implementation.
How SimpleRisk implements this
The cryptographic primitives
- Algorithm: AES-256-CBC (Advanced Encryption Standard, 256-bit key, Cipher Block Chaining mode).
- Authentication: HMAC-SHA256. Each ciphertext is HMAC'd to detect tampering on read; modified ciphertext fails the HMAC check and produces an error rather than silent garbage.
- Library: OpenSSL via PHP's
openssl_*functions (with a fallback to the legacymcryptextension on older installs; mcrypt is deprecated in PHP 7.2+ and the OpenSSL path is the default). - Per-record IV: each ciphertext has its own random initialization vector, prepended to the stored ciphertext. Two identical plaintexts produce different ciphertexts because they use different IVs.
This is a defensible, contemporary cryptographic configuration. Nothing fancy; nothing weak.
The key model
A single 256-bit master key per install:
- Generated at activation time using
openssl_random_pseudo_bytes(32)— 32 bytes from the OpenSSL CSPRNG. - Base64-encoded for storage.
- Stored in
simplerisk/extras/encryption/includes/init.phpas a PHPdefine('ENCODED_KEY', 'line.'); - Loaded into PHP at runtime when the encryption functions are called.
Implications:
- One key encrypts all encrypted data. There's no per-user key, no per-record key, no key escrow.
- The key file's filesystem permissions are the security boundary. Anyone with read access to the file has the key. The file should be readable by the web server's PHP process and nothing else.
- The key isn't password-derived. User password changes don't affect the encryption; the key persists across user activity.
What gets encrypted
Roughly 30 fields across the SimpleRisk schema, including:
- Risks: subject, notes, assessment, mitigation_percent, current_solution, security_recommendations, security_requirements.
- Assets: name, ip, details, additional fields.
- Frameworks: name, description.
- Framework controls: short_name, long_name, description.
- Mitigations: planning, current_solution, security_recommendations.
- Audit logs: message field.
- Comments: comment text.
- Custom data: values stored via the Customization Extra (when the field's
encryptionflag is on).
The exact list depends on the install's version and active Extras. The encrypted_fields table tracks which fields are actually encrypted.
What does not get encrypted:
- Foreign keys and lookup IDs (you can still see which user owns which risk, even without the key).
- Numeric scoring fields (impact, likelihood, calculated_risk).
- Configuration settings (the
settingstable). - User credentials (handled separately via bcrypt — see Local Authentication and Password Policies).
The selective encryption keeps performance reasonable while protecting the substantive content.
The activation backup
When you activate the Extra, it creates an unencrypted backup of the database before encrypting:
- Filename pattern:
simplerisk-unencrypted_backup-YYYY-MM-DD--HH-MM-SS.sql. - Location: the system temp directory (typically
/tmp/on Linux). - Purpose: rollback if activation fails or the operator wants to revert.
This backup is plaintext — treat it as sensitive. Delete it after a successful activation when you're confident the rollback path isn't needed.
Activation, deactivation, and runtime
- Activation: encrypts existing plaintext data in place; writes the master key file; flips the Extra-active flag. Time-consuming on large installs.
- Runtime: encryption and decryption happen transparently in
simplerisk/extras/encryption/includes/encryption.php(or equivalent). Theencrypt()anddecrypt()functions are called wherever encrypted columns are written or read. - Deactivation: decrypts all encrypted fields in place; reverts the schema; removes the Extra's active flag. Time-consuming and irreversible without re-activation.
For multi-server deployments (load-balanced SimpleRisk behind multiple web servers): the init.php master key file must be present on every server. Deploy it to each app server during initial setup; treat it as configuration, not as application code.
Common pitfalls
A handful of patterns recur with the Encryption Extra.
-
Activating without backing up the master key file. The file at
simplerisk/extras/encryption/includes/init.phpis the only copy of the key. Server failure, file system corruption, accidental deletion — without an off-server backup, the encrypted database is permanently inaccessible. Back up immediately after activation. -
Treating encryption as protection against runtime attack. It isn't. Compromise of the SimpleRisk server gives the attacker the key. Encryption-at-rest is one defense layer; runtime defenses (web server hardening, application security, OS security) are separate.
-
Skipping the backup file cleanup after activation. The unencrypted backup left in
/tmp/is sensitive. Delete it once you're confident the activation succeeded. -
Activating on a production install without testing the workflow on a non-production instance. Activation is time-consuming and the rollback path is "deactivate" or "restore from the backup file." Test in non-production first.
-
Deploying multi-server SimpleRisk without copying the key file to each node. The non-keyed nodes can't decrypt; users hitting those nodes see broken pages or errors. Confirm the key file is on every app server.
-
Storing the key file in source control. Don't. The file contains the master key; checking it into Git puts the key in everyone's checkout, every backup of every clone, every CI pipeline log. Manage the key file as a deployment-time secret.
-
Confusing the encryption-at-rest layer with TLS. TLS protects data in transit (network). The Encryption Extra protects data at rest (database). Both are needed; neither substitutes for the other.
-
Assuming all SimpleRisk data is encrypted after activation. Selective encryption (only ~30 fields) means most of the schema is plaintext. Reports that pull lookup IDs, status counts, etc., still work without the key. This is operationally useful (reports don't break when the key is wrong); it also means database access still leaks structural information.
-
Not coordinating activation with the program team. Activation is a maintenance event. Communicate the planned time; expect application unavailability during the migration.
-
Treating the activation backup as the long-term backup strategy. It's a one-time rollback file, not a recurring backup. Standard backup procedures (see Database Backup and Restore) cover the ongoing backups; the activation backup is just the rollback option for the activation itself.
Related
- Enabling Encryption
- Key Management and Rotation
- Securing the Database
- Securing the Web Server
- Local Authentication and Password Policies (for the password hashing used for user credentials, separate from the encryption-at-rest covered here)
- Database Backup and Restore
- Installing Extras