| 开发者 | dpknauss |
|---|---|
| 更新时间 | 2026年9月5日 02:37 |
| 捐献地址: | 去捐款 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPL-2.0-or-later |
| 版权网址: | 版权信息 |
get_comments() and there is nothing to hand back. The same care runs through the rest: closing the REST API also removes the link advertising it, and disabling comments also stops the comment feed from answering requests.
Site Health shows you the whole posture, read-only: every default and its current state on one screen, so you can see what the site is actually doing without clicking through tabs. It also reports when another plugin is controlling the same settings, which otherwise fails silently.
Outgoing email stops at the edge of production. An unsanitized database copied down from production carries real customer addresses and whatever mail service production was using, so a cron run or a bulk action can email real people from a staging site or a laptop. Keel suppresses outgoing mail on any environment that is not production by default. It does nothing on production, and Keel says so in an admin notice so no admin is left wondering why a password reset never arrived.
Keel works the same on a Multisite network. Activated across multisite, Keel seeds every existing site and every site created afterwards, so a later change to a default cannot apply to some sites and not others. A Super Admin can see and change any setting for the whole network under Network Admin → Settings → Network Policy. Sub-sites on the network see those settings as locked, with their own saved values untouched underneath, so lifting a policy returns each site to exactly what it had.
wp-content/plugins/, or upload the built zip through Plugins → Add New → Upload Plugin.X-Frame-Options header of SAMEORIGIN, so other sites cannot embed yours in an iframe. If something else is meant to display your site inside a frame — an intranet dashboard, a screenshot or visual-review service, a kiosk or signage screen — set Frame options to "Leave unchanged" under Security and Attack Surface. A blocked frame usually fails silently, as a blank box, but Keel's rule is to call everything out.
Deactivating stops every default at once; stored settings are kept so reactivating restores the same configuration. Uninstalling removes them.Sixteen of the thirty-nine defaults are on out of the box, and nine more settings that are not simple switches apply a starting value. Nothing is written to your content and nothing is deleted; every one of them is a switch on Settings → Site Defaults you can turn off, and turning it off puts WordPress back exactly as it shipped.
Most of it is quiet. Users stop being listed to anonymous REST requests, new passwords have to be long and must not appear in a known breach, raw HTML and JavaScript are limited to Administrators, baseline security headers are sent, AI provider connectors are switched off, translations keep auto-updating, uploads get lowercase filenames, attachment screens show which image sizes were generated, and the site warns you if its own email looks misconfigured.
Three are visible straight away and are the ones to know about. Comments, trackbacks and pingbacks are switched off everywhere, including for existing posts — nothing is deleted, and turning the setting off brings every comment back. Author archives stop resolving, so /author/name/ no longer returns a page. And X-Frame-Options: SAMEORIGIN is sent, which stops other sites displaying yours in an iframe; if something is meant to embed this site, set Frame options to "Leave unchanged".
Two more change things you may not see immediately: attachment pages redirect to the parent post, and self-pingbacks and the emoji detection script are gone.
The starting values are conservative. Core auto-updates are set to minor — maintenance and security releases install themselves, major versions do not — ten post revisions are kept, logins last two days or fourteen with "Remember me", and subscribers are exempt from the password rules. The admin menu width, the front-end admin bar and the login logo are all left as WordPress has them until you choose otherwise.
One default is on but does nothing on a live site: outgoing email is blocked on any environment that is not production, so a database copied to staging or a laptop cannot email real people. On production it never acts.
In that case, WordPress.org has offered the same-line security patch only as an automatic-update offer. get_core_updates(), which builds the Updates screen, skips every automatic-update offer. On a 6.9.5 site the patch is 6.9.7 and the screen offers 7.1, which is a major update, not a patch. A same-line patch can also be the current manual release, so Keel asks core what the screen is actually showing rather than assuming it is absent.
Keel names the patch for your release line and tells you what that screen is actually offering, so you can see the difference. If minor auto-updates are switched on and nothing is blocking the updater, the patch installs itself on a scheduled check. If something is blocking it, Keel names the specific constant, filter or condition responsible, because each one needs a different fix.
Keel can install it for you, from the same panel. The target is recomputed on the server and can only ever be the patched release on your own line, so it cannot cross a release line or move you backwards. It checks the release's PHP and MySQL requirements first, refuses if the filesystem is not writable, and then hands the offer to WordPress's own upgrader with rollback enabled — the same machinery core uses for its own automatic updates.
The defaults that are on out of the box are low-risk, with one exception worth naming: X-Frame-Options: SAMEORIGIN is sent by default, and it stops other sites embedding yours in an iframe. Set Frame options to "Leave unchanged" if the site is meant to be embedded, because a blocked frame fails silently as a blank box.
Everything else that can break something is off and opt-in, and each says on the settings screen what it will cost you — for example that blocking the XML-RPC endpoint also stops apps and services that publish through it. Requiring authentication for REST is the one place Keel spends a little of that strictness back: oembed/1.0 stays reachable, so other sites can still embed your posts when every other route is closed.
One thing, and only when the strong-password default is on: the first five characters of a password's SHA-1 hash, to check it against known breaches. Never the password, never the full hash, no personal data. See External services above for the full description and how to switch it off.
Because Keel switched it off, deliberately, and there is an admin notice on the site saying so. The Non-Production Email default suppresses outgoing mail on any environment that is not production, so a database copied down from production cannot email real customers from a staging site or a laptop.
It does nothing on production, so it cannot be left on by mistake. To send from a non-production site anyway, turn the default off under Settings → Site Defaults, define KEEL_ALLOW_NONPRODUCTION_MAIL in wp-config.php, or use the keel_suppress_nonproduction_mail filter. A mail catcher can still record what would have been sent by hooking keel_outgoing_mail_suppressed.
The environment is read the same way the admin-bar environment indicator reads it: WP_ENVIRONMENT_TYPE, whether set as a constant or an environment variable, and a host-name fallback for local development tools when neither is set.
No. Disabling comments hides them and closes the forms; nothing is removed from the database, and turning the default off brings every comment back. The same holds for the other content defaults.
Yes. Every default reads its value through the plugin's own option, and the behaviours are filterable — keel_weak_roles, keel_disable_hibp, keel_comment_blocks, keel_allowed_comment_types and others. A wp-config.php constant always wins over the settings screen where one applies; the screen says so when it is being overridden.
The setting is stored per site; the effect is not. WordPress keeps one user table for the whole network, so a password is checked against whichever site it is being set on — and once set, it is that person's password everywhere. Exempting a role on one subsite decides what happens when a password is changed there; it does not exempt those accounts from another site's policy. In practice the strictest site on the network sets the floor for anyone who changes their password on it. Keel can now govern it as well as document it. Under Network Admin → Settings → Network Policy, a Super Admin can decide any setting for the whole network; sites see it as locked and cannot change it. Tick the password rules there and the network has one policy instead of a floor set by whichever site is strictest. Nothing is written into your sites. A network value is applied when a setting is read, so a site's own saved settings are untouched — untick a setting later and every site returns to exactly the value it had. Settings left unticked stay each site's own business.
You can, but you probably should not, and Keel will tell you when it matters.
Some settings are applied through WordPress filters that transform a value in priority order — session length is the clearest example. Another callback on the same filter does not prove a conflict: two plugins may reach the same outcome or govern different parts of a structured result.
Keel reports a structural overlap only when it is registered on an authoritative policy hook and a callback attributable to another active plugin is registered there too. It never executes the other plugin's callback to diagnose the overlap. The notice appears on the Plugins screen, on Settings → Site Defaults, and on the dashboard, where it can be dismissed until the overlap changes. The full details are explained under Tools → Site Health.
That evidence confirms shared ownership of a hook, not that the plugins' configured outcomes disagree. Keel asks you to compare their settings and never recommends deactivation from callback presence alone. Mail, authentication, comment-query, capability, and unattributable overlaps stay unconfirmed and informational.
There is a limit worth knowing. WordPress ships tiny helper callbacks such as __return_false; the callback belongs to WordPress, not the plugin that registered it. Keel labels that limitation unconfirmed instead of guessing from source code or naming a plugin without evidence.
Keel also stays out of the fight where it has nothing to say: when a setting is still at the value WordPress itself uses, Keel does not register the filter at all, so it cannot override a deliberate choice another plugin has made — and it will not report a conflict on a setting it is not itself setting.
WordPress ships one, but it is JavaScript: it advises the person typing and cannot refuse anything, so a password set over the REST API, WP-CLI, or a form with scripts disabled never meets it. Keel enforces length, breach screening, a blocklist and a personal-context check server-side instead, where they cannot be bypassed. See the Help tab on the settings screen.
get_core_updates(), which discards every offer flagged for automatic installation — and a same-line security patch is only ever offered that way. So the screen has always listed the newest release and never mentioned the patch. Keel adds it back, directly below the automatic-update settings that decide which release the site would take.null from WordPress's upgrader was reported as a successful install. Core documents a version string on success, so null establishes nothing./?author=N still disclosed the author nicename, and attachment pages still rendered, on sites with those defaults enabled. Both redirects registered on template_redirect at the default priority, where core has already registered redirect_canonical during load — so they lost the tie on registration order every time. Both now run at priority 9./wp/v2/comments/123. The filter covering every comment listing does not cover the single-item REST route, which reads its row without building a query.tests/hook-precedence.php and tests/route-coverage.php, which check that a registration wins its hook and covers its routes rather than merely existing. The first two fixes above were invisible to the previous suite.get_core_updates() omits those offers, so following that button installed the newest release instead. Keel now asks core what that screen is showing, and distinguishes listed, hidden behind Show hidden updates, absent, and not yet known.WP_ENVIRONMENT_TYPE constant and wp_get_environment_type() reports the result, not the other way round.https://wordpress.org/ appended, which goes nowhere. Affected every site with any of those three behaviours set.wp-config.php already had, for the same reason: the form has no business speaking for a control it did not draw.-1 means unlimited, and 0 disables future revisions. Numeric or false WP_POST_REVISIONS policy locks both site and network controls.keel-defaults rather than keel, and the text domain moved with it. WordPress.org serves translations as {slug}-{locale}.mo, so a text domain that is not the slug means no translation ever loads — silently, with nothing to search for.unfiltered_html away, and almost none of them touch that capability; only the ones that do are reported.<link rel>, the Link: header and the RSD entry all go — and oEmbed stays reachable through the gate so other sites embedding yours do not silently degrade to a bare link.author_name and author_url, and the users sitemap provider is removed.WP_ENVIRONMENT_TYPE through an environment variable rather than the constant.admin, support, info and 70 others, which is a reasonable policy for a managed fleet and a presumptuous one for a general-purpose defaults plugin — the list is long, opinionated, and includes names an ordinary site legitimately uses (manager, marketing, sales, office, client). Existing accounts were never affected and still are not. A stored setting is ignored and drops out of the option on the next save; no migration is needed. To keep the behaviour, WordPress's own filter does it in one call: add_filter( 'illegal_user_logins', function ( $logins ) { return array_merge( $logins, array( 'admin', 'administrator', 'root' ) ); } );