fix: the derive_key function uses a static, hardco... in encryption.py#9436
fix: the derive_key function uses a static, hardco... in encryption.py#9436anupamme wants to merge 2 commits into
derive_key function uses a static, hardco... in encryption.py#9436Conversation
Automated security fix generated by OrbisAI Security
📝 WalkthroughWalkthroughThe license encryption utility derives keys with a secret-specific SHA-256 salt and preserves decryption of ciphertext generated with the previous static salt. ChangesLicense encryption
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/plane/license/utils/encryption.py`:
- Around line 15-16: Update the key derivation used by the encryption utilities
around decrypt_data() to preserve access to ciphertext created with the previous
derivation: retain the legacy Fernet key as a fallback when decryption with the
current key fails, or migrate and re-encrypt existing stored values before
adopting the new derivation. Ensure legacy decryption failures are not silently
converted into blank values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6779d497-69f4-42fd-a8a0-819ad72da2da
📒 Files selected for processing (1)
apps/api/plane/license/utils/encryption.py
|
✅ Review Feedback Addressed I've automatically addressed 2 review comment(s): The code review flagged a data integrity / backward-compatibility issue in Files modified:
The changes have been pushed to this PR branch. Please review! |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/api/plane/license/utils/encryption.py (1)
46-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCatch
InvalidTokenhere instead ofException.Fernet.decrypt()raisesInvalidTokenfor bad ciphertext, so this keeps the legacy fallback limited to key mismatches; add the import if needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/plane/license/utils/encryption.py` around lines 46 - 55, In the decryption logic, update the try/except around the primary Fernet derivation and decrypt call to catch only cryptography.fernet.InvalidToken instead of Exception, adding the import if necessary. Keep the existing _derive_key_legacy fallback and successful decode behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/plane/license/utils/encryption.py`:
- Around line 13-17: Cache the expensive key derivation in _derive_key_legacy
with functools.lru_cache so repeated legacy decryptions reuse the derived key;
also apply the same caching to derive_key if it is not already cached. Preserve
the existing secret_key-based cache behavior and backward-compatible derivation
output.
---
Nitpick comments:
In `@apps/api/plane/license/utils/encryption.py`:
- Around line 46-55: In the decryption logic, update the try/except around the
primary Fernet derivation and decrypt call to catch only
cryptography.fernet.InvalidToken instead of Exception, adding the import if
necessary. Keep the existing _derive_key_legacy fallback and successful decode
behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6a4a9eb6-c9ae-4d07-8e18-c521f90b7de1
📒 Files selected for processing (1)
apps/api/plane/license/utils/encryption.py
| def _derive_key_legacy(secret_key): | ||
| # Legacy key derivation using static salt – retained for backward compatibility | ||
| # so that ciphertext created before the salt fix can still be decrypted. | ||
| dk = hashlib.pbkdf2_hmac("sha256", secret_key.encode(), b"salt", 100000) | ||
| return base64.urlsafe_b64encode(dk) |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
Cache the legacy key derivation to prevent severe CPU overhead.
pbkdf2_hmac with 100,000 iterations is a computationally expensive operation. Because decrypt_data falls back to this legacy method for older ciphertext, repeatedly deriving this key on every read (especially when decrypting multiple configuration values in a loop) will cause significant performance degradation.
Please apply @lru_cache to this function (and to derive_key if not already cached) so the derivation occurs only once per process.
⚡ Proposed fix
+from functools import lru_cache
+
+@lru_cache(maxsize=1)
def _derive_key_legacy(secret_key):
# Legacy key derivation using static salt – retained for backward compatibility
# so that ciphertext created before the salt fix can still be decrypted.
dk = hashlib.pbkdf2_hmac("sha256", secret_key.encode(), b"salt", 100000)
return base64.urlsafe_b64encode(dk)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _derive_key_legacy(secret_key): | |
| # Legacy key derivation using static salt – retained for backward compatibility | |
| # so that ciphertext created before the salt fix can still be decrypted. | |
| dk = hashlib.pbkdf2_hmac("sha256", secret_key.encode(), b"salt", 100000) | |
| return base64.urlsafe_b64encode(dk) | |
| from functools import lru_cache | |
| `@lru_cache`(maxsize=1) | |
| def _derive_key_legacy(secret_key): | |
| # Legacy key derivation using static salt – retained for backward compatibility | |
| # so that ciphertext created before the salt fix can still be decrypted. | |
| dk = hashlib.pbkdf2_hmac("sha256", secret_key.encode(), b"salt", 100000) | |
| return base64.urlsafe_b64encode(dk) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/plane/license/utils/encryption.py` around lines 13 - 17, Cache the
expensive key derivation in _derive_key_legacy with functools.lru_cache so
repeated legacy decryptions reuse the derived key; also apply the same caching
to derive_key if it is not already cached. Preserve the existing
secret_key-based cache behavior and backward-compatible derivation output.
Summary
Fix high severity security issue in
apps/api/plane/license/utils/encryption.py.Vulnerability
V-001apps/api/plane/license/utils/encryption.py:14Description: The
derive_keyfunction uses a static, hardcoded salt value (b"salt") for PBKDF2-HMAC-SHA256 key derivation. This eliminates the security benefit of salt randomization, allowing attackers to precompute rainbow tables for common secret keys.Evidence
Exploitation scenario: An attacker who obtains encrypted data (e.g., from a database dump) can attempt to brute-force the SECRET_KEY.
Scanner confirmation: multi_agent_ai rule
V-001flagged this pattern.Production code: This file is in the production codebase, not test-only code.
Threat Model Context
This API endpoint appears to be publicly accessible. This is a Node.js library - vulnerabilities affect downstream consumers who use this package.
Changes
apps/api/plane/license/utils/encryption.pyVerification
Security Invariant
Regression test
This test guards against regressions — it's useful independent of the code change above.
Automated security fix by OrbisAI Security
Summary by CodeRabbit