T09 · Insecure Skill Coding Practices
Error
- Location
- python/koan_sdk.py:177
- Finding
- Private Keys Stored in Plaintext on Linux and Other Unsupported Platforms<![CDATA[ ## Vulnerability Details **File Location**: - `python/koan_sdk.py:177-203` - `node/koan-sdk.mjs:152-173` **Vulnerability Type**: Plaintext storage of cryptographic private keys **Risk Level**: High ### Vulnerable Code Python implementation: ```python signing_private_key = base64.b64encode( self._signing_key.private_bytes( serialization.Encoding.DER, serialization.PrivateFormat.PKCS8, serialization.NoEncryption(), ) ).decode() encryption_private_key = base64.b64encode( self._encryption_key.private_bytes( serialization.Encoding.DER, serialization.PrivateFormat.PKCS8, serialization.NoEncryption(), ) ).decode() data = { 'koanId': self.koan_id, 'signingPublicKey': self.signing_public_key_b64, 'encryptionPublicKey': self.encryption_public_key_b64, } private_blob = json.dumps({ 'signingPrivateKey': signing_private_key, 'encryptionPrivateKey': encryption_private_key, }) if sys.platform.startswith('win'): data['privateKeyStorage'] = {'scheme': 'windows-dpapi'} data['protectedPrivateKeys'] = _dpapi_protect_text(private_blob) elif sys.platform == 'darwin': account = _macos_keychain_account(self.signing_public_key_b64) _macos_keychain_set(account, private_blob) data['privateKeyStorage'] = { 'scheme': 'macos-keychain', 'service': KEYCHAIN_SERVICE, 'account': account, } else: data['privateKeyStorage'] = {'scheme': 'plaintext'} data['signingPrivateKey'] = signing_private_key data['encryptionPrivateKey'] = encryption_private_key IDENTITY_FILE.write_text(json.dumps(data, indent=2), encoding='utf-8') try: os.chmod(IDENTITY_FILE, 0o600) except Exception: pass ``` Node.js implementation: ```javascript const signingPrivateKey = this._signingPrivateKey.export({ type: 'pkcs8', format: 'der' }).toString('base64'); const encryptionPrivateKey = this._encryptionPrivateKey.export({ type: 'pkcs8', format: 'der' }).t ...[truncated 3216 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not silently fall back to plaintext private-key storage. 2. Integrate with a supported OS credential store on Linux, such as Secret Service through an established keyring library. 3. Where no credential store is available, encrypt PKCS#8 private keys using a user-supplied passphrase and a modern password-based key derivation function. 4. Prefer hardware-backed or vault-backed signing so the private signing key is non-exportable. 5. Fail closed or require explicit, prominently displayed approval before using plaintext storage. 6. Retain restrictive permissions, but treat them as defense in depth rather than encryption. 7. Document key rotation and revocation procedures for previously generated plaintext identities. 8. Avoid retaining decoded private-key strings longer than necessary and clear temporary buffers where the runtime permits. ]]>
