Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.8.0 - 2026-08-28 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 - 2026-08-18 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-feed.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ class WebDecoy_Actor_Feed
public const CRON_HOOK = 'webdecoy_sync_actor_feed';

/** Shared actor feed endpoint (Bearer API key; same auth as entitlements). */
private const FEED_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/actor-feed';
private const FEED_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/actor-feed';

/** Option persisting the delta cursor (`since`) between syncs. */
private const CURSOR_OPTION = 'webdecoy_actor_feed_cursor';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-actor-intel.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@
class WebDecoy_Actor_Intel
{
/** Batched intel endpoint (Bearer API key). */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/detections/intel';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/detections/intel';

/** Per-IP transient cache prefix. */
private const CACHE_PREFIX = 'webdecoy_intel_';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-cloud-connect.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ class WebDecoy_Cloud_Connect
* {@see WebDecoy_Violation_Reporter} authenticates the violations batch:
* an `Authorization: Bearer <api_key>` header against the ingest service.
*/
private const ENTITLEMENTS_ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/entitlements';
private const ENTITLEMENTS_ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/entitlements';

/** Where the generic "Upgrade" link points once connected. */
private const BILLING_URL = 'https://app.webdecoy.com/billing';
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-ip-enrichment.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
*/
class WebDecoy_IP_Enrichment
{
private const ENDPOINT_BASE = 'https://ingest.webdecoy.com/api/v1/sdk/ip/';
private const ENDPOINT_BASE = 'https://in.webdecoy.com/api/v1/sdk/ip/';

/** Cache TTL — 1 hour, matching node's ttlMs default. */
private const TTL = HOUR_IN_SECONDS;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-violation-reporter.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@
class WebDecoy_Violation_Reporter
{
/** Ingest batch endpoint. */
private const ENDPOINT = 'https://ingest.webdecoy.com/api/v1/sdk/violations/batch';
private const ENDPOINT = 'https://in.webdecoy.com/api/v1/sdk/violations/batch';

/** Max events per POST body, matching node's batch size. */
private const BATCH_SIZE = 100;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-webdecoy-woocommerce.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -459,7 +459,7 @@ private function forward_to_webdecoy(string $ip, string $source, int $score, arr
}

$ingest_url = rtrim($this->options['api_url'] ?? 'https://api.webdecoy.com', '/');
$ingest_url = str_replace('api.webdecoy.com', 'ingest.webdecoy.com', $ingest_url);
$ingest_url = str_replace('api.webdecoy.com', 'in.webdecoy.com', $ingest_url);
$ingest_url .= '/api/v1/detect';

$collector = new \WebDecoy\SignalCollector();
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ Donate link: https://webdecoy.com
Tags: bot detection, security, spam protection, woocommerce, ai bots
Requires at least: 6.1
Tested up to: 7.0
Stable tag: 2.7.1
Stable tag: 2.8.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand DownExpand Up@@ -284,6 +284,9 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f

== Changelog ==

= 2.8.0 =
* Changed: the plugin's cloud calls now go to in.webdecoy.com, WebDecoy's DDoS-protected ingest address. Same service, sturdier front door. If your firewall allows outbound requests by hostname, allow in.webdecoy.com. Sites that set a custom API URL are unaffected.

= 2.7.1 =
* Removed: the canary trip email introduced in 2.7.0. The canary link sits on every public page, so busy sites would receive an email every hour, forever. Detections belong on the Detections page, not in your inbox. Everything else from 2.7.0 stays: the canary URL in settings, the trip-it-yourself prompt, and the Detections page recording every hit.

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/Client.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
class Client
{
private const DEFAULT_BASE_URL = 'https://api.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://ingest.webdecoy.com';
private const DEFAULT_INGEST_URL = 'https://in.webdecoy.com';
private const DEFAULT_TIMEOUT = 10;

/**
Expand DownExpand Up@@ -43,7 +43,7 @@ private static function userAgent(): string
* - api_key: (required) Your WebDecoy API key
* - organization_id: (optional) Your organization UUID - will be auto-fetched if not provided
* - base_url: (optional) API base URL, defaults to https://api.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://ingest.webdecoy.com
* - ingest_url: (optional) Ingest service URL, defaults to https://in.webdecoy.com
* - timeout: (optional) Request timeout in seconds, defaults to 10
* - verify_ssl: (optional) Verify SSL certificates, defaults to true
* @throws WebDecoyException If required configuration is missing
Expand Down
8 changes: 4 additions & 4 deletions webdecoy.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
* Plugin Name: WebDecoy Bot Detection
* Plugin URI: https://webdecoy.com/wordpress
* Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection.
* Version: 2.7.1
* Version: 2.8.0
* Requires at least: 6.1
* Requires PHP: 7.4
* Author: WebDecoy
Expand DownExpand Up@@ -41,7 +41,7 @@
}

// Plugin constants
define('WEBDECOY_VERSION', '2.7.1');
define('WEBDECOY_VERSION', '2.8.0');
define('WEBDECOY_PLUGIN_FILE', __FILE__);
define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__));
Expand DownExpand Up@@ -1684,7 +1684,7 @@
],
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1687 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -1729,7 +1729,7 @@
),
];

$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1732 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $violation->ip,
'user_agent' => $violation->userAgent ?? '',
'score' => $confidence,
Expand DownExpand Up@@ -1879,7 +1879,7 @@
'metadata' => $result->getMetadata(),
];

$wpdb->insert($table, [

Check warning on line 1882 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -1960,7 +1960,7 @@
// Local log, inlined rather than via log_detection(): that path also
// queues the critical-moment alert for CRITICAL rows, and a test must
// not page anyone.
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 1963 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => $result->getScore(),
Expand DownExpand Up@@ -2054,7 +2054,7 @@
$ip = $this->get_client_ip();

global $wpdb;
$wpdb->insert($wpdb->prefix . 'webdecoy_detections', [

Check warning on line 2057 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
'score' => 100,
Expand DownExpand Up@@ -2662,7 +2662,7 @@
'user_agent' => $user_agent,
];

wp_remote_post('https://ingest.webdecoy.com/api/v1/page-serve', [
wp_remote_post('https://in.webdecoy.com/api/v1/page-serve', [
'timeout' => 1,
'blocking' => false,
'headers' => [
Expand DownExpand Up@@ -2790,7 +2790,7 @@
$threat_level = 'LOW';
}

$wpdb->insert($table, [

Check warning on line 2793 in webdecoy.php

View workflow job for this annotation

GitHub Actions/ PHP Coding Standards

Use of a direct database call is discouraged.
'ip_address' => $ip,
'user_agent' => $user_agent,
'score' => $score,
Expand All@@ -2811,7 +2811,7 @@
*/
private function forward_to_ingest(array $detection, string $ip): void
{
$ingest_url = 'https://ingest.webdecoy.com/api/v1/detect';
$ingest_url = 'https://in.webdecoy.com/api/v1/detect';

// Get API key (decrypt if needed)
$api_key = $this->options['api_key'];
Expand Down
Loading