Skip to content

fix(wp-plugin): DB init bug + local-signing audit (no redesign yet)#2

Merged
jt55401 merged 3 commits into
mainfrom
fix/wp-plugin-init-and-audit
May 13, 2026
Merged

fix(wp-plugin): DB init bug + local-signing audit (no redesign yet)#2
jt55401 merged 3 commits into
mainfrom
fix/wp-plugin-init-and-audit

Conversation

@jt55401
Copy link
Copy Markdown
Contributor

@jt55401 jt55401 commented Apr 29, 2026

Summary

  • Fix DB init-order bug that crashed wp plugin activate. ContentSigning_Plugin::init_components() ran synchronously at plugin load and called $db->get_default_server(), querying wp_content_signing_servers before the activator had created it. Now deferred to the WP init action, with an idempotent maybe_install_schema() safety net that re-runs the activator if the schema version option is missing (covers manual installs, site clones, mu-plugin setups).
  • Make the activator self-document its idempotency and record content_signing_db_version so the schema guard knows what's installed.
  • Add wordpress/docs/local-signing-audit.md -- a written analysis of the gap between the current trust-server-side signing model and the local-signing model the amended spec (2026-04-10, §2.2 + §3.1) actually requires. Proposes a 4-phase rollout: CLI signer -> server-key -> WebAuthn -> deprecate trust-server endpoint. No signing code changes in this PR; the redesign is deferred pending sign-off on the rollout plan.

Test plan

  • wp plugin activate content-signing succeeds on a fresh WP install (will be exercised by the companion chore/wp-reenable-in-e2e change in htmltrust-e2e).
  • Reactivating an already-activated plugin remains a no-op (idempotency check).
  • Existing functionality unchanged: signing on publish, scheduling, AJAX handlers, admin pages all still work.
  • php -l on modified files (could not run locally; PHP is not installed on the dev box -- relying on the WP container in e2e).
  • Audit doc reviewed; rollout phases approved or amended before any phase-1 work begins.

Notes

  • The content_signing_db_version option is new; existing installs will get it written on next page load via maybe_install_schema(). No migration script needed.
  • Hook registration moved from run() directly to inside init_components (so it happens after components exist). All hooks the plugin attaches to fire at or after init, so timing is preserved.

jt55401 and others added 3 commits April 10, 2026 20:03
…hor-profiles.php

The render_page() method was missing its closing sequence (a ?>, </div>,
<?php, and }) which caused the parser to read the next method's docblock
as part of render_page's inline HTML. This made every subsequent
PHP file that depended on this class fail to parse.

Separately, a displaced stray '?> </div> <?php }' fragment appeared
after handle_create_api_author()'s proper closing brace and has been
removed.

Verified: php -l passes, and 'wp plugin activate content-signing'
succeeds. A runtime 'table doesn't exist' error fires on activation
but is a separate init-order issue out of scope for this fix.
Updates the HTML signature protocol documentation to match the
amended paper specification:

- Canonicalization section: add explicit text-only scoping, enumerate
  the semantic attacks this leaves open (element rewrapping, link swap,
  surrounding media manipulation), and document the layered response
  (domain binding alerts readers at unexpected origins; research and
  reputation path traces signed content back to canonical origin and
  flags imposter copies).
- Signature data format: replace old {contentHash}:{domain}:{authorId}
  binding with new {content-hash}:{claims-hash}:{domain}:{signed-at}.
  Drop authorId (redundant with keyid resolution), add claims-hash for
  tamper-evident metadata, add signed-at timestamp.
- Hash encoding: switch to unpadded Base64 and note the open feedback
  invitation on encoding alternatives (hex, Base32).
- Verification flow: restructure into two layers -- cryptographic
  verification (local, deterministic) and trust decision (client
  policy). Add detail on keyid resolution methods (DID, direct URL,
  trust directory reference). Add note that optional directory queries
  enrich trust decision but are never required for verification.

Tracks the 2026-04-10 design decisions committed in the paper at
bb3dc5a, 1187b2d, 6d0511c, 271a455, ca8cc3b.
…edesign

The plugin called ContentSigning_Plugin::init_components() synchronously at
plugin load time, which queried wp_content_signing_servers via
$db->get_default_server(). On a fresh install the activator hasn't yet
created that table when this query fires, so `wp plugin activate` (and
the subsequent admin page load) crashed with "table doesn't exist".

Fix: defer init_components() to the WP 'init' action and add a
maybe_install_schema() guard that re-runs the (idempotent) activator
if the db_version option is missing. The activator was already
idempotent (dbDelta + add_option) but is now self-documenting and also
records content_signing_db_version so the schema guard knows what's
installed.

Also adds wordpress/docs/local-signing-audit.md, a written analysis of
the spec gap (amended 2026-04-10) between the current trust-server-side
signing model and the local-signing model the spec actually requires
(§2.2, §3.1). The audit doc proposes a 4-phase rollout (CLI signer ->
server-key -> WebAuthn -> deprecate trust-server endpoint) but
deliberately makes no code change toward that redesign in this commit;
that's gated on Jason's approval of the rollout plan.

Note: php is not installed locally so `php -l` could not be run on the
modified files. Relying on next-layer testing (e2e activation in the
chore/wp-reenable-in-e2e branch).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jt55401 jt55401 merged commit 77219b2 into main May 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant