Soft security guards: raw-meta-key warning + TTY publish confirm (v3.8.1)#10
Conversation
…3.8.1) Non-breaking follow-up to the audit hardening. seo_meta warns on non-allowlisted raw keys (WP_REQUIRE_ALLOWLIST=1 to refuse); create_post/ update_post confirm before --status publish on a TTY (--yes bypass, non-interactive unchanged). Lazy-imports requests so _map_meta_keys is testable without the optional dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6bcc4ae556
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| warn_insecure_wp_url(a.url) | ||
| if should_confirm_publish(a.status, a.yes, sys.stdin.isatty()): | ||
| print("About to PUBLISH live content to %s. Type 'PUBLISH' to confirm:" % a.url, file=sys.stderr) | ||
| if input("> ").strip() != "PUBLISH": |
There was a problem hiding this comment.
Keep publish prompt off JSON stdout
When stdin is a TTY but stdout is being consumed by another tool or redirected (for example, running this interactively with > result.json), input("> ") writes the prompt to stdout before the JSON response. These scripts otherwise reserve stdout for machine-readable JSON, so confirming a publish can corrupt the caller's output; the same pattern was added in update_post.py, and the prompt should be emitted on stderr while reading from stdin.
Useful? React with 👍 / 👎.
Non-breaking follow-up to the audit hardening. Adds the soft variants of the two findings we skipped as hard gates.
Changes
seo_meta.pynow warns (stderr) when writing a non-allowlisted postmeta key — still writes it. SetWP_REQUIRE_ALLOWLIST=1to refuse instead. ACF/JetEngine untouched — arbitrary custom keys are their intended API. Refactored key-mapping into a pure_map_meta_keys()helper (testable without HTTP).requestsis now lazy-imported inside the three network functions so the helper is importable in stdlib-only test environments.create_post.py/update_post.pyprompt before--status publishonly on a TTY;--yes/-ybypasses. Non-interactive/agent runs are byte-for-byte unchanged → no break.Non-breaking guarantee
should_confirm_publish("publish", False, False)→False. Agent/CI runs proceed without any prompt.Test approach
Used approach (a): extracted
_map_meta_keys(meta_dict, plugin, env)as a pure helper inseo_meta.py. Tests call it directly — no HTTP, norequestsneeded. Coverage: allowlisted key → silent mapping; raw key → warning entry + still in payload;WP_REQUIRE_ALLOWLIST=1→ValueError.🤖 Generated with Claude Code