{"record":{"id":"5268f0859a865fde","repo":"kovidgoyal/kitty","slug":"ignoring-encrypted-rc-command-without-a-public-key","errorCode":null,"errorMessage":"Ignoring encrypted rc command without a public key","messagePattern":"Ignoring encrypted rc command without a public key","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kitty/remote_control.py","lineNumber":64,"sourceCode":"def parse_cmd(serialized_cmd: memoryview, encryption_key: EllipticCurveKey) -> dict[str, Any]:\n    # See https://github.com/python/cpython/issues/74379 for why we cant use\n    # memoryview directly :((\n    try:\n        pcmd = json.loads(bytes(serialized_cmd))\n    except Exception:\n        log_error('Failed to parse JSON payload of remote command, ignoring it')\n        return {}\n    if not isinstance(pcmd, dict) or 'version' not in pcmd:\n        log_error('JSON payload of remote command is invalid, must be an object with a version field')\n        return {}\n    pcmd.pop('password', None)\n    if 'encrypted' in pcmd:\n        if pcmd.get('enc_proto', '1') != RC_ENCRYPTION_PROTOCOL_VERSION:\n            log_error(f'Ignoring encrypted rc command with unsupported protocol: {pcmd.get(\"enc_proto\")}')\n            return {}\n        pubkey = pcmd.get('pubkey', '')\n        if not pubkey:\n            log_error('Ignoring encrypted rc command without a public key')\n        d = AES256GCMDecrypt(encryption_key.derive_secret(base64.b85decode(pubkey)), base64.b85decode(pcmd['iv']), base64.b85decode(pcmd['tag']))\n        data = d.add_data_to_be_decrypted(base64.b85decode(pcmd['encrypted']), True)\n        pcmd = json.loads(data)\n        if not isinstance(pcmd, dict) or 'version' not in pcmd:\n            return {}\n        delta = time_ns() - pcmd.pop('timestamp')\n        if abs(delta) > 5 * 60 * 1e9:\n            log_error(\n                f'Ignoring encrypted rc command with timestamp {delta / 1e9:.1f} seconds from now.'\n                ' Could be an attempt at a replay attack or an incorrect clock on a remote machine.'\n            )\n            return {}\n    return pcmd\n\n\nclass CMDChecker:\n    def __call__(self, pcmd: dict[str, Any], window: Optional['Window'], from_socket: bool, extra_data: dict[str, Any]) -> bool | None:\n        return False","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/remote_control.py#L46-L82","documentation":"An encrypted remote-control command lacks the 'pubkey' field, so kitty cannot derive the shared secret to decrypt it. Note the code logs and continues (which will then fail on b85decode of the empty pubkey) — the message signals a malformed encrypted payload.","triggerScenarios":"pcmd contains 'encrypted': true but no 'pubkey' key, hitting the `if not pubkey` branch in parse_cmd.","commonSituations":"Hand-built encrypted RC payloads missing fields, or a buggy/older client that omits pubkey.","solutions":["Include the base85-encoded ephemeral public key in the 'pubkey' field","Prefer using kitten's built-in ECDH handshake instead of constructing encrypted commands manually"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"assert pcmd.get('encrypted') is True and pcmd.get('pubkey'), 'encrypted payload needs pubkey'","typeGuard":"def is_complete_encrypted_cmd(p: dict) -> bool:\n    return all(k in p for k in ('pubkey', 'iv', 'tag', 'encrypted'))","tryCatchPattern":null,"preventionTips":["Let kitten perform the ECDH handshake rather than building encrypted payloads manually"],"tags":["kitty","remote-control","encryption","missing-key"],"backgroundTag":"missing-public-key","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}