Vulnity Security

ವಿವರಣೆ

Vulnity Security brings enterprise-grade threat detection to WordPress. It connects your site to Vulnity’s SIEM platform, correlates events, and alerts you before issues become incidents.

Features

  • Real-time security event collection and forwarding to Vulnity SIEM.
  • Dashboard widgets that highlight critical findings and remediation steps.
  • Scheduled security scans for core files, plugins, and themes.
  • Centralized logging compatible with major SOC workflows.

Integration Requirements

To receive alerts, configure an API token and endpoint URL provided by your Vulnity SIEM account. Detailed configuration instructions are displayed after activating the plugin under Vulnity > Settings.

WordPress Multisite is not supported in Vulnity Security 1.4.0. Network activation and subsite activation are blocked to avoid mixing configuration, firewall storage, cron jobs, or uninstall cleanup between subsites.

Vulnity Security 1.4.0 requires WordPress 6.2 or newer. Older WordPress versions are blocked fail-safe so the plugin stays inactive instead of registering security, firewall, cron, REST, or SIEM behavior on an unsupported runtime.

External Services

This plugin connects to Vulnity’s external API hosted on Supabase Edge Functions (domain: euxnoekqasvzwfcbybkg.supabase.co, base URL https://euxnoekqasvzwfcbybkg.supabase.co/functions/v1) to power SIEM alerts, inventory sync, and mitigation updates.

  • What the service is and what it is used for:
    • Vulnity SIEM API for pairing/unpairing, heartbeat checks, sending alerts, testing connectivity, syncing inventory, and receiving mitigation policies.
  • Endpoints used:
    • /pair-plugin, /unpair-plugin (pairing and disconnecting the site).
    • /heartbeat (periodic health check).
    • /connection-test (manual connection test).
    • /scan-site-info (inventory sync).
    • /generic-alert, /brute-force-alert, /file-security-alert, /manage-user, /user-management-alert, /permission-change-alert, /file-editor-alert, /plugin-change-alert, /theme-change-alert, /core-update-alert, /suspicious-query-alert, /scanner-detected-alert (security alerts).
    • /mitigation-config, /mitigation-update (mitigation policy sync and block/unblock updates).
    • /delegated-login-callback (audit confirmation of a delegated wp-admin login, signed with the reinforced v2 scheme).
  • Assisted connection (linking token):
    • From the Vulnity panel you can start an assisted connection instead of copying a Site ID and Pairing Code. The panel issues a single-use, short-lived (15 minute) linking token and hands it to this site with a server-side POST to wp-admin; the plugin stores it in a transient tied to your user account and renders a confirmation card that names the organization and the registered domain. The bearer is never placed in the URL, the fragment, the DOM, the page HTML or any browser JavaScript. Confirming requires a valid nonce and re-authentication with your current WordPress password; only then does the plugin exchange the token for the site credentials against /pair-plugin over HTTPS, server-side. The exchange only succeeds when this site’s URL matches the domain registered in the panel, the pending token is discarded after three failed confirmations, and redirects are never followed for these requests.
  • What data is sent and when:
    • Pairing/unpairing: site ID and pair code (manual mode) or the single-use linking token (assisted mode), the site URL and home URL, plugin/WordPress/PHP versions, and timestamp when pairing or disconnecting occurs.
    • Heartbeat: site ID, URLs, site metadata (name, language, timezone, theme), and runtime info (plugin/WordPress/PHP versions, latency) on a scheduled interval.
    • Alerts: site ID, alert type/severity, timestamps, and event details (such as IP address, user/action metadata, or file change context) whenever a security event is detected.
    • Inventory sync: site inventory details (installed plugins/themes/core metadata) when inventory sync runs.
    • Mitigation: site ID, block/unblock actions, IP address, reason, duration, and rule metadata when mitigation rules are synced or enforcement actions occur.
  • Why the data is sent:
    • To associate the site with your Vulnity account, deliver security alerts to the SIEM, validate connectivity, synchronize inventory and mitigation policies, and keep firewall enforcement consistent.
  • Policies: See the Vulnity Terms of Service and Privacy Policy for details on how data is handled.

License

This plugin is licensed under the GNU General Public License v2.0 or later. You are free to redistribute and/or modify it under the terms of the GPL as published by the Free Software Foundation. The complete license text is included in the bundled license.txt file and is also available online at https://www.gnu.org/licenses/gpl-2.0.html.

ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳು

ಸ್ಥಾಪನೆ

  1. Upload the plugin files to the /wp-content/plugins/vulnity directory or install from the WordPress plugin repository.
  2. Activate the plugin through the Plugins screen in WordPress.
  3. Navigate to Vulnity > Settings, enter your Vulnity SIEM credentials, and save.
  4. (Optional) Enable scheduled scans on the Monitoring tab to receive weekly reports.

FAQ

Do I need a Vulnity SIEM subscription?

Yes. The plugin requires an active Vulnity SIEM account to collect and analyze events.

Will the plugin slow down my site?

No. Event collection runs asynchronously and offloads processing to the Vulnity cloud platform.

Can I disable certain alerts?

Absolutely. Use the Alert Policies section within the plugin settings to mute or reclassify events.

How does delegated login decide a request really came over HTTPS? (trust model)

The /sso gate and the plugin’s HTTPS shim only believe forwarded headers (X-Forwarded-Proto, X-Forwarded-SSL) when the immediate network hop (REMOTE_ADDR) is a trusted proxy. Trusted means: an entry you configured in the vulnity_trusted_proxies option (IPs or CIDRs — recommended, keep it to the minimal real ranges of your proxy/CDN), or a private/reserved address, which is auto-trusted by default for compatibility with same-host reverse proxies. X-Forwarded-Proto is authoritative and fail-closed: any non-https segment rejects the request and X-Forwarded-SSL: on cannot override it. If a client could reach your origin directly from the private network, disable the automatic trust by returning false from the vulnity_trust_private_proxies filter (e.g. in a mu-plugin) and declare your proxies explicitly. Direct internet connections must satisfy is_ssl().

What is the HTTPS proxy shim and how do I disable it?

When TLS terminates at a trusted proxy and the origin receives plain HTTP, WordPress’ is_ssl() is false, and session cookies would be written (and later read) with the wrong scheme. On load, the plugin applies the standard WordPress reverse-proxy shim — setting $_SERVER['HTTPS'] — but only after the same fail-closed validation as the SSO gate (trusted hop + all-https forwarded chain; never from an untrusted direct client). This keeps is_ssl() consistent site-wide so delegated-login cookies always carry the Secure attribute and remain readable in wp-admin. To disable it, set the option vulnity_https_proxy_shim to 0 or return false from the vulnity_https_proxy_shim filter; the canonical X-Forwarded-Proto shim in wp-config.php remains a valid alternative. Deliberate fail-closed: with the shim disabled and TLS only at the proxy, /sso answers 400 rather than ever issuing a non-Secure admin cookie.

One-time note: on a site behind a TLS-terminating proxy that did not already have an is_ssl() shim, activating or updating to this version flips is_ssl() to true, so WordPress starts using the secure auth cookie. Any admin sessions established before the update are invalidated once and those users are asked to log in again — a single expected re-login, not a recurring one. If you already run the X-Forwarded-Proto shim in wp-config.php, nothing changes.

How do I disable delegated login on my site? (kill switch)

Set the option vulnity_delegated_login_enabled to 0, or return false from the vulnity_delegated_login_enabled filter from code you control (a mu-plugin or your theme). The filter is the last-resort guarantee: it works locally even if the central panel were compromised, so it will never be removed. While disabled, /sso answers 403 and no session can be created.

How is the /sso rate limit enforced?

Each redemption attempt atomically reserves one slot for the real client identity (resolved through the trusted proxy chain; IPv6 grouped by /64, IPv4 per host) in a fixed 300-second window, with a hard cap of 10 admitted attempts per identity and window — a concurrent burst cannot exceed it. A successful login refunds its slot, so only failures consume budget. The number of live rate-limit rows in wp_options is capped (oldest buckets are evicted deterministically, never merged into a shared bucket), and closed windows are swept hourly.

‍ವಿಮರ್ಶೆಗಳು‍

ಈ ಪ್ಲಗಿನ್‌ಗೆ ಯಾವುದೇ ವಿಮರ್ಶೆಗಳಿಲ್ಲ.

ಕೊಡುಗೆದಾರರು & ಡೆವಲಪರ್‌ಗಳು

“Vulnity Security” ಓಪನ್ ಸೋರ್ಸ್ ಸಾಫ್ಟ್‌ವೇರ್ ಆಗಿದೆ. ಕೆಳಗಿನ ಜನರು ಈ ಪ್ಲಗಿನ್‌ಗೆ ಕೊಡುಗೆ ನೀಡಿದ್ದಾರೆ.

ಕೊಡುಗೆದಾರರು

“Vulnity Security” ಅನ್ನು ನಿಮ್ಮ ಭಾಷೆಗೆ ಅನುವಾದಿಸಿ.

ಅಭಿವೃದ್ಧಿಯಲ್ಲಿ ಆಸಕ್ತಿ ಇದೆಯೇ?

ಕೋಡ್ ಬ್ರೌಸ್ ಮಾಡಿ, SVN ರೆಪೊಸಿಟರಿ ಪರಿಶೀಲಿಸಿ, ಅಥವಾ ಅಭಿವೃದ್ಧಿ ಲಾಗ್ ಗೆ RSS ಚಂದಾದಾರರಾಗಿ.

Changelog

1.4.0

  • Added assisted connection (“Connect automatically”) from the Vulnity panel: a single-use, 15-minute linking token is exchanged for the site credentials, so connecting a site no longer requires copying a Site ID and Pairing Code by hand. The manual pairing form remains available as a fallback and is unchanged.
  • The linking token never reaches the browser: the panel hands it to WordPress with a server-side POST, the plugin keeps it in a transient tied to the logged-in operator, and the exchange runs entirely server-side, so the bearer never appears in the URL, the fragment, the DOM, the page HTML or any browser JavaScript. Confirming the connection requires a valid nonce and re-authentication with your current WordPress password, and the pending token is discarded after three failed confirmations. The confirmation card names the organization and registered domain (fetched from the panel), and the exchange only succeeds when this site’s URL matches the registered domain — a link opened on a different site connects nothing.
  • Fixed the admin feedback for Test Connection, alert retries (single and bulk) and IP unblocking: the AJAX callbacks failed silently and left the screen with no result. They now show the outcome the server reports. Test Connection additionally reports a failed request instead of staying on “Testing…”, and no longer stays blank when it is run a second time.
  • The assisted exchange is idempotent: if the network response is lost after the token was already redeemed, the plugin can safely retry and recover the same credentials instead of failing with an “already used” error. The plugin also verifies that the pairing configuration actually persisted to the database (busting any object cache) before reporting success, and never follows HTTP redirects for pairing requests.
  • The assisted flow now sends both site_url and home_url, so WordPress installed in a subdirectory (where they differ) pairs correctly instead of being rejected.
  • Added per-site health telemetry surfaced in the Vulnity panel (storage mode, WP-Cron heartbeat health, and related warnings), plus self-healing of the WP-Cron heartbeat warning via a confirmatory runner.
  • Hardened the pairing endpoint contract: an ambiguous or mode-less request body returns a stable 400 instead of a 500.

1.3.9

  • Added delegated wp-admin login (SSO from the Vulnity panel) using one-time, single-use signed tokens. No WordPress password is stored or transmitted; the opaque token is consumed atomically and every access is audited in the SIEM.
  • Added three REST endpoints (/delegated-admins, /delegated-login, /sso) protected by a reinforced v2 signature (HMAC over method+route+timestamp+nonce+body, with anti-replay). The existing endpoints are unchanged.
  • The /sso endpoint returns a distinct status per token state: 404 unknown link, 409 already used (raising a high-severity replay alert in the SIEM), 410 expired. Consumed tokens leave a short-lived tombstone so reuse is always distinguishable from an invalid link, and every SSO response carries no-store cache headers.
  • The /sso HTTPS requirement only trusts X-Forwarded-Proto/X-Forwarded-SSL when the immediate network hop is a trusted proxy (configured vulnity_trusted_proxies entries or private/reserved ranges); direct internet connections must satisfy is_ssl(), and the post-login redirect is always issued over HTTPS.
  • The /sso rate limiter now keys on the real client IP resolved through the trusted proxy chain (IPv6 grouped per /64 so address rotation cannot evade the limit), counts only failed attempts, and increments atomically — bulk garbage requests behind a shared reverse proxy can no longer lock every visitor out of delegated login. Stale rate-limit buckets are swept by the hourly maintenance cron, not only on token registration, so a probed /sso cannot grow wp_options without bound.
  • An explicit X-Forwarded-Proto is authoritative for the /sso HTTPS gate: a proxy-declared http (or a mixed chain) is rejected fail-closed and cannot be overridden by a residual X-Forwarded-SSL: on. For the strongest posture behind a TLS-terminating proxy, configure vulnity_trusted_proxies with the proxy IP/CIDR (or add the standard X-Forwarded-Proto HTTPS shim to wp-config.php); without it, private/reserved immediate hops are auto-trusted for compatibility with common localhost reverse-proxy setups.
  • Delegated-login audit callbacks now require a 2xx response from the SIEM and are queued for retry (hourly, deduplicated server-side) when delivery fails. Each pending callback is stored as its own option row so a concurrent redemption during a retry pass can never drop an audit event.
  • Deactivating the plugin revokes pending delegated-login tokens, and expired or revoked tokens keep answering 410 instead of 404 — including when a redemption races the revoke/sweep, which no longer raises a false replay alert.
  • Admin session cookies created by delegated login always carry the Secure attribute (both the auth and the logged_in cookie). Behind a TLS-terminating trusted proxy the plugin applies a hardened, fail-closed HTTPS shim on load so is_ssl() is consistent when writing and reading the cookie (option/filter vulnity_https_proxy_shim to disable; with the shim off and TLS only at the proxy, /sso answers 400 rather than issuing a non-Secure cookie).
  • The audit callback queue is loss-proof under pressure: deduplication happens before any eviction (a duplicate can no longer cost an unrelated pending event), the cap evicts deterministically oldest-first with every eviction logged, retries claim rows via compare-and-swap so two cron workers cannot double-deliver or lose attempt counts, redirects are never followed (3xx counts as failure), and events without a correlation id get a stable generated identity instead of being dropped.
  • Revocation now covers every pending token (batched, not just the first 200), runs defensively on activation too, and a redemption that wins the delete race against an in-flight revocation re-checks the tombstone — a revoked token can never complete a login (410, no false replay alert).
  • The /sso rate limiter enforces a hard admission cap per identity and window (atomic reserve-then-refund: a concurrent burst cannot exceed the limit and successful logins refund their slot), and the number of live rate-limit rows in wp_options is bounded with deterministic oldest-first eviction — identity floods can no longer grow the table without limit.
  • New vulnity_trust_private_proxies filter to disable the automatic trust of private/reserved hops for forwarded headers and IP resolution (see the trust-model FAQ).

1.3.5

  • Added WP-Cron diagnostics in the WordPress admin when scheduled Vulnity heartbeats appear disabled, missing, stale, or only recover through site activity.
  • Added a throttled runtime heartbeat fallback from admin/site traffic for hosts where WP-Cron is disabled or unreliable.
  • Added a WP-Cron setup documentation link to guide users toward a stable external cron configuration when needed.

1.3.4

  • Hardened hidden login URL handling so direct unauthenticated access to wp-login.php and wp-admin returns 404 while the configured custom login slug remains usable.
  • Reduced malicious upload false positives so normal media such as PNG files do not trigger PHP upload alerts.

1.3.2

  • Added WP-CLI bulk pairing support for agency and VPS environments.
  • Added safe dry-run validation before connecting a site from the command line.
  • Added pairing-key support so new WordPress installs can connect to Vulnity without copying per-site pair codes manually.

1.3.1

  • Version bump to 1.3.1.
  • WordPress Multisite activation is blocked explicitly in 1.3.1 to avoid unsafe cross-blog configuration, storage, cron, or uninstall behavior.
  • Minimum supported WordPress version is now 6.2; older versions are blocked fail-safe during activation/runtime.

1.2.3

  • Fixed firewall bootstrap blocking wp-login.php, wp-cron.php, admin-ajax.php, and xmlrpc.php for blocked IPs — admins can now recover access.
  • Fixed firewall bootstrap returning HTML instead of JSON for REST API requests from blocked IPs.
  • Fixed uninstall leaving broken .htaccess when file is read-only — now creates safe stub to prevent HTTP 500.
  • Fixed early IP blocking (plugins_loaded:0) intercepting AJAX and REST requests, breaking admin panel functionality.
  • Reduced SIEM alert timeout from 10s to 3s to prevent page hangs during attacks.
  • Reduced inventory sync timeout from 30s to 8s to prevent random slow page loads via pseudo-cron.
  • Improved file detection in Protect Common Paths — now handles query strings, trailing slashes, and dotted directory names correctly.
  • Added PHP execution blocking rule for uploads directory in generated Nginx configuration snippet.
  • Expanded REST API public route whitelist: added WooCommerce v3, UpdraftPlus, BackWPup, Elementor, Forminator, FluentForms, SureCart, MailPoet, and block editor endpoints.
  • Added Options -Indexes to Protect Common Paths .htaccess rules as defense-in-depth measure.
  • Updated Stable tag from 1.2.2 to 1.2.3.

1.2.2

  • Fixed anti-collapse dedup system blocking subsequent auto-update state toggle events due to identical hash.
  • Fixed wrong authentication headers for /real-time-alerts endpoint (now uses HMAC-SHA256 signature instead of token).
  • Fixed missing remediation field in auto-update state events sent to the SIEM.
  • Fixed version_old not captured in auto-update events; now recorded via upgrader_pre_install hook before files are replaced.
  • Fixed auto-update trigger running on disable; updates now only fire for newly enabled component types.
  • Fixed auto-update event detection using instanceof WP_Automatic_Updater instead of wp_doing_cron() for broader compatibility.
  • Fixed single-file plugin slug resolving to . (e.g. hello-dolly) in update event payloads.
  • Added triggered_by field to update events: siem_manual, siem_auto_update, or wp_auto_updater.
  • Auto-update toggles in the admin panel are now read-only; changes must be made from the SIEM.
  • Replaced parse_url() with wp_parse_url() for WordPress coding standards compliance.

1.2.1

  • Plugin Check compatibility improvements for filesystem and nonce-related warnings.
  • Runtime validation improvements for scanner detection, file editor monitoring, and firewall state serialization.

1.2.0

  • Fixed login URL rename validation against existing pages/posts and reserved WordPress routes.
  • Fixed uninstall cron cleanup to use wp_unschedule_hook() for complete removal.
  • Fixed heartbeat, mitigation sync, and alert buffer crons not cancelled on plugin disconnect.

1.1.9

  • Send whitelist IPs (user public IP + localhost) to the SIEM during pairing so the whitelist persists after synchronization.

1.1.8

  • Fixed Nginx warning notice appearing repeatedly on every admin page load; it now displays only once.
  • Improved notice format: each protected path is shown on its own line for better readability.
  • Added link to solution documentation for Nginx .htaccess compatibility.

1.1.7

  • Fixed deactivation not clearing all cron jobs (4 missing hooks, plus events re-scheduled by late-firing alert hooks).
  • Added final_deactivation_cleanup at priority 9999 to ensure complete cron and .htaccess cleanup after all hooks fire.
  • Replaced wp_clear_scheduled_hook with wp_unschedule_hook to clear single events with arguments.
  • Added native PHP fallback for .htaccess marker removal when WP_Filesystem is unavailable.
  • Fixed Plugin Check error: replaced direct is_writable() with vulnity_path_is_writable() and WP_Filesystem_Direct.

1.1.5

  • Fix uninstall multisite cleanup query when sitemeta table is not available to prevent SQL warnings in debug.log.

1.1.4

  • Ensure uninstall removes Vulnity firewall/log folders recursively so no plugin-owned folders are left behind.

1.1.3

  • Ensure uninstall removes Vulnity firewall/log folders even when permissions are restrictive by attempting safe chmod before cleanup.

1.1.2

  • Added a dedicated Vulnity log with line-based rotation and safe fallbacks when uploads are not writable.
  • Added admin warning when firewall storage cannot be written, with clear remediation guidance.
  • Expanded uninstall cleanup to remove Vulnity log files and firewall artifacts across fallback paths.

1.1.1

  • Fixed deactivation cleanup so Vulnity hardening marker blocks are removed fully from .htaccess without modifying user-defined rules.
  • Improved deactivation safety in shared hosting environments with conservative, marker-only rollback behavior.

1.1.0

  • Improved admin UI consistency across Dashboard, Synchronization, Mitigation, Hardening, and Setup screens.
  • Hardened plugin lifecycle behavior for shared hosting compatibility and safer deactivation/uninstall flows.
  • Added conservative server integration safeguards to reduce side effects in Apache/Nginx environments.

1.0.5

  • Version bump to 1.0.5.

1.0.4

  • Version bump to 1.0.4.

1.0.3

  • Standardized admin asset enqueues and AJAX URL localization for compliant loading.
  • Hardened nonce and capability checks across alerts and admin handlers.
  • Improved path resolution using WordPress APIs for non-default installs.
  • Documented external Supabase services used for alerts and mitigation updates.

1.0.2

  • Initial release.