| 开发者 | kwistech |
|---|---|
| 更新时间 | 2026年8月27日 02:06 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
/wp-login.php. Tests the new address before saving it
and provides a break-glass constant, because the obvious way to implement this is also the
obvious way to lock yourself out.X-Powered-By.?author=1 scans, the REST user list, the user sitemap
and oEmbed author fields all stop answering anonymous callers. Author archives at their own
address keep working, and so does everything a signed-in editor needs. The control also
reports when an account's display name is its username, because when that is true the
byline gives the game away regardless.X-Content-Type-Options, X-Frame-Options,
Referrer-Policy and X-Permitted-Cross-Domain-Policies, and never overwriting one your
server or CDN already sends. Deliberately no CSP: any policy that leaves wp-admin usable
needs unsafe-inline, which does not stop the attack CSP exists to stop.unfiltered_html restricted — via a capability filter rather than the all-or-nothing
constant, so administrators keep the workflows they need.Two controls can, and both are built to make that hard. The custom sign-in address makes a
real request to the new address before saving it, and refuses to save if it does not answer;
if the check cannot run, you must tick an acknowledgement, and that choice is recorded.
Two-factor enforcement cannot be switched on until at least one administrator has enrolled,
because requiring codes before anyone has an authenticator locks out everybody at once.
If you are locked out anyway, add define( 'KWISTECH_SECURE_DISABLE_LOGIN_SLUG', true ); to
wp-config.php and /wp-login.php works again immediately.
It detects other two-factor plugins and steps aside rather than running a second implementation. For firewall and scanning plugins there is no overlap — this one does neither. Switch off any individual control that duplicates something you already have.
The hardening controls are filters and capability checks with no database work on a normal page load. Nothing runs on the front end except the header changes.
The code paths exist and have never been run on a real network. Treat multisite as unsupported rather than broken.
Deleting the plugin removes its options, both database tables, the scheduled job, and every
user meta key it set, including two-factor secrets and recovery codes. Deactivating changes
nothing. Constants you added to wp-config.php by hand are left alone, because this plugin
never edits that file.
Yes, deliberately. No minified files, no bundled dependencies, no build step, no obfuscation. A security plugin you cannot read is a security plugin you cannot check.
kws_ prefix to kwistech_secure_. Three characters is below the four-character
minimum the plugin directory asks of a prefix, and it was the one part of the plugin still
using the short form. Your data is migrated automatically the first time an administrator
loads a wp-admin page after upgrading: settings, audit log, login history, two-factor
enrolment and recovery codes all carry across. Tables are renamed rather than copied, so no
audit entry is lost.kws_settings is now kwistech_secure_settings, the
audit table is now {prefix}kwistech_secure_audit_log, and the daily job is now
kwistech_secure_daily_maintenance.kwistech_secure_show_addon_notice filter.?author=N scans, /wp-json/wp/v2/users, the user
sitemap and oEmbed author fields to anonymous visitors. This was a known gap, recorded in
the threat model as accepted residual R-5. Refusing to confirm usernames at the sign-in
form while handing the list out over REST was never a coherent position.kwistech-secure; if you installed 1.2.0 by hand, delete the old
kwistech-wp-secure folder after upgrading or WordPress will run both copies at once.
Settings, audit log and login history are untouched -- they are keyed independently of the
folder name and carry across.kws_dashboard_cards,
kws_settings_panels, kws_admin_notices and kws_admin_notice_messages become
kwistech_secure_*. The opt-out constant KWS_DISABLE_LOGIN_SLUG becomes
KWISTECH_SECURE_DISABLE_LOGIN_SLUG. Update the add-on to 1.1.0 at the same time.$wpdb->prepare() as %i identifier placeholders rather than
interpolated into the SQL string. The old form was safe -- the names were built from
$wpdb->prefix plus a literal -- but "safe because you can read the surrounding code"
is weaker than "cannot be otherwise", and it needed a static-analysis suppression on every
query to say so. %i arrived in WordPress 6.2.