Closed (fixed)
Project:
SSH Key
Version:
4.x-dev
Component:
Code
Priority:
Major
Category:
Bug report
Assigned:
Reporter:
Created:
14 May 2026 at 15:25 UTC
Updated:
29 May 2026 at 01:40 UTC
Jump to comment: Most recent
Here are some findings from Claude Code's Opus 4.7's pre-beta audit of the 4.x branch. Each item below should land as its own commit referencing this issue so the upgrade story stays bisectable and reviewable. Severity tags reflect impact, not effort.
NameFormatter::viewElements() — the user-suppliedname is rendered as #markup and not escaped. Switch to #plain_texthook_entity_field_access() and no access handler. Either wire them up or remove the fileSshKeyItem::onChange(); existing@todo in code). MD5 collisions are practical. Switch to the already-implementedUtils::getFingerprintSha256() and provide an update hook for existing rows.text/big. Reject anything past a sane ceiling (e.g. 16 KB — covers RSA up to 16384-bit with aSshKeyConstraintValidator or via a Length constraint in propertyDefinitions().foo infield.storage_settings.sshkey_default (config/schema/sshkey.schema.yml).sshkey_theme() + theme_sshkey_fingerprint() — currentlySshKeyItem::setValue() — left over fromEntityReferenceItem.@todo commentsSshKeyItem lines 18, 96; Utils line 37).Utils::getFingerprintSha256() from production code or remove it (relatessshkey.info.yml description: "to collect a ssh public keys" →fingerprint property's setRequired(TRUE) with the storage'not null' => FALSE.generateSampleValue() with a real wire-format SSH key so devel-generate-stylephpseclib3\Crypt\PublicKeyLoader::load() can verify parseability for any algorithm — extend
Comments
Comment #2
colanWorking in !8...
Comment #18
colanMR !8 covers all thirteen audit items, in 13 logical commits plus three small CI fixups (cspell wordlist tweaks, a phpcs line-length, and one test fixture that needed sharper teeth — phpseclib parsed the original "garbage" payload as e=0, n=0). CI is green; the SHA-256 migration hook was also verified locally against real data.
Security-tagged items addressed: the unescaped
#markupXSS inNameFormatter::viewElements(), the absent length cap on the raw key (16 KB ceiling now lives as a Length constraint on thevalueproperty), the unenforcedsshkey.permissions.yml(removed — access already flows through the host entity's field-access logic), and the MD5 fingerprint (now OpenSSH-canonicalSHA256:<base64>, withsshkey_update_10001that recomputes existing rows in batched chunks and tightens the column to NOT NULL when everything parses). Structural validation now routes throughphpseclib3\Crypt\PublicKeyLoaderfor every algorithm, so curve-invalid ed25519 and malformed RSA payloads fail even when the prefix check would have passed.Cleanup-tagged items: info.yml grammar, the misleading
EntityReferenceItem-leftover comment inSshKeyItem::setValue(), thefooplaceholder infield.storage_settings.sshkey_default, the deadsshkey_theme()+theme_sshkey_fingerprint()(the .module file is gone entirely — the formatter renders directly), the three trailing@todo/@DCGmarkers,generateSampleValue()now returns a wire-format key that passes the validator (so devel-generate fixtures actually exercise downstream paths), and the README has been rewritten to match what 4.x actually ships. New unit/Kernel test coverage was added alongside each behavior change. Ready for review/merge.Comment #35
colanMerged!