Plugin Directory

Changeset 3459867


Ignore:
Timestamp:
02/12/2026 11:37:13 AM (3 weeks ago)
Author:
shift8
Message:

Malware signatures offload to API interaction to avoid being flagged as malware by 3rd party scanners

Location:
atomic-edge-security/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • atomic-edge-security/trunk/atomicedge.php

    r3459845 r3459867  
    44 * Plugin URI: https://atomicedge.io/wordpress
    55 * Description: Connect your WordPress site to Atomic Edge WAF/CDN for advanced security protection, analytics, and access control management.
    6  * Version: 2.2.1
     6 * Version: 2.2.2
    77 * Requires at least: 5.8
    88 * Requires PHP: 7.4
     
    2626
    2727// Plugin constants.
    28 define( 'ATOMICEDGE_VERSION', '2.2.1' );
     28define( 'ATOMICEDGE_VERSION', '2.2.2' );
    2929define( 'ATOMICEDGE_PLUGIN_FILE', __FILE__ );
    3030define( 'ATOMICEDGE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
  • atomic-edge-security/trunk/includes/class-atomicedge-api.php

    r3454914 r3459867  
    803803        return (bool) filter_var( $ip, FILTER_VALIDATE_IP );
    804804    }
     805
     806    /**
     807     * Get malware detection signatures from the Atomic Edge API.
     808     *
     809     * Signatures are cached locally to avoid repeated API calls.
     810     * The cache is refreshed every 24 hours or when manually cleared.
     811     *
     812     * @param bool $force_refresh Force a refresh from the API.
     813     * @return array|false Signature data or false on error.
     814     */
     815    public function get_malware_signatures( $force_refresh = false ) {
     816        $cache_key = 'atomicedge_malware_signatures';
     817
     818        // Check for cached signatures unless force refresh.
     819        if ( ! $force_refresh ) {
     820            $cached = get_transient( $cache_key );
     821            if ( false !== $cached && is_array( $cached ) && ! empty( $cached['patterns'] ) ) {
     822                return $cached;
     823            }
     824        }
     825
     826        // Fetch from API.
     827        $response = $this->request( 'GET', '/wp/malware-signatures' );
     828
     829        if ( ! $response['success'] || empty( $response['data'] ) ) {
     830            // On API failure, try to use stale cache.
     831            $stale = get_option( 'atomicedge_malware_signatures_backup' );
     832            if ( ! empty( $stale ) && is_array( $stale ) ) {
     833                AtomicEdge::log( 'Using stale malware signature cache due to API failure' );
     834                return $stale;
     835            }
     836
     837            AtomicEdge::log( 'Failed to fetch malware signatures', $response );
     838            return false;
     839        }
     840
     841        $signatures = $response['data'];
     842
     843        // Cache for 24 hours.
     844        $cache_duration = apply_filters( 'atomicedge_malware_signatures_cache_duration', DAY_IN_SECONDS );
     845        set_transient( $cache_key, $signatures, $cache_duration );
     846
     847        // Also save as backup for API failures.
     848        update_option( 'atomicedge_malware_signatures_backup', $signatures, false );
     849
     850        AtomicEdge::log( 'Malware signatures updated', array( 'version' => $signatures['version'] ?? 'unknown' ) );
     851
     852        return $signatures;
     853    }
     854
     855    /**
     856     * Clear malware signature cache.
     857     *
     858     * @return void
     859     */
     860    public function clear_malware_signature_cache() {
     861        delete_transient( 'atomicedge_malware_signatures' );
     862    }
    805863}
  • atomic-edge-security/trunk/includes/class-atomicedge-scanner.php

    r3452356 r3459867  
    44 *
    55 * File integrity checking and malware scanning functionality.
     6 * Malware signatures are fetched from the Atomic Edge API to prevent
     7 * the plugin from being flagged by hosting provider security scanners.
    68 *
    79 * @package AtomicEdge
     
    4042     */
    4143    private const INTEGRITY_MANIFEST_REL_PATH = 'admin/assets/integrity/atomicedge-manifest.json';
     44
     45    /**
     46     * API instance for fetching signatures.
     47     *
     48     * @var AtomicEdge_API|null
     49     */
     50    private $api = null;
    4251
    4352    /**
     
    173182
    174183    /**
    175      * Quick rejection indicators - if none present, skip expensive regex.
    176      *
    177      * IMPORTANT: These must be UNCOMMON in legitimate code to be effective.
    178      * Avoid common PHP functions like include(), require(), file_get_contents().
    179      * Focus on:
    180      * - Obfuscation techniques (base64_decode+eval combos, hex encoding)
    181      * - Known shell signatures
    182      * - Malware-specific strings
    183      * - Dangerous function+superglobal combos
     184     * Quick rejection indicators fetched from API.
     185     * These are fast string checks to skip expensive regex matching.
     186     *
     187     * @var array|null
     188     */
     189    private $quick_rejection_indicators = null;
     190
     191    /**
     192     * Signature data fetched from API.
     193     *
     194     * @var array|null
     195     */
     196    private $api_signatures = null;
     197
     198    /**
     199     * Diagnostics collected during the most recent scan.
    184200     *
    185201     * @var array
    186202     */
    187     private $quick_rejection_indicators = array(
    188         // Code execution with dynamic input (the dangerous combo).
    189         'eval(',
    190         'assert(',
    191         'create_function(',
    192         // Shell execution functions.
    193         'shell_exec(',
    194         'passthru(',
    195         'proc_open(',
    196         'popen(',
    197         'pcntl_exec(',
    198         // Obfuscation patterns.
    199         'base64_decode(',
    200         'gzinflate(',
    201         'gzuncompress(',
    202         'str_rot13(',
    203         'convert_uudecode(',
    204         'edoced_46esab',  // Reversed base64_decode.
    205         // Hex-encoded strings (5+ consecutive \xNN patterns).
    206         '\\x',
    207         // Known webshell signatures.
    208         'c99shell',
    209         'r57shell',
    210         'b374k',
    211         'filesman',
    212         'wso shell',
    213         'weevely',
    214         'phpspy',
    215         // WordPress-specific malware.
    216         'wp-vcd',
    217         'tmpcontentx',
    218         'wp_temp_setupx',
    219         'derna.top',
    220         '@noupdate',
    221         'class.theme-modules',
    222         'class.plugin-modules',
    223         // Dangerous superglobal access patterns.
    224         '$_get[',
    225         '$_post[',
    226         '$_request[',
    227         '$_cookie[',
    228         // Defacement/hack signatures.
    229         'hacked by',
    230         'owned by',
    231         'backdoor',
    232         'rootkit',
    233         'webshell',
    234         // System file access.
    235         '/etc/passwd',
    236         '/etc/shadow',
    237         // Base64-encoded dangerous keywords.
    238         'ZXZhbCg',      // eval(
    239         'YXNzZXJ0',     // assert
    240         'c3lzdGVt',     // system
    241         'c2hlbGxfZXhlYw', // shell_exec
    242     );
    243 
    244     /**
    245      * Diagnostics collected during the most recent scan.
     203    private $scan_diagnostics = array();
     204
     205    /**
     206     * IDs of queue items to mark as done in batch at end of step.
    246207     *
    247208     * @var array
    248209     */
    249     private $scan_diagnostics = array();
    250 
    251     /**
    252      * IDs of queue items to mark as done in batch at end of step.
    253      *
    254      * @var array
    255      */
    256210    private $pending_done_ids = array();
    257211
    258212    /**
    259213     * Constructor.
    260      */
    261     public function __construct() {
    262         // Scanner doesn't need hooks - it's called on demand.
     214     *
     215     * @param AtomicEdge_API|null $api Optional API instance for fetching signatures.
     216     */
     217    public function __construct( $api = null ) {
     218        $this->api = $api;
     219    }
     220
     221    /**
     222     * Set the API instance.
     223     *
     224     * @param AtomicEdge_API $api API instance.
     225     * @return void
     226     */
     227    public function set_api( $api ) {
     228        $this->api = $api;
    263229    }
    264230
     
    29932959        $content_lower = strtolower( $content );
    29942960        $has_indicator = false;
    2995         foreach ( $this->quick_rejection_indicators as $indicator ) {
     2961        $indicators = $this->get_quick_rejection_indicators();
     2962        foreach ( $indicators as $indicator ) {
    29962963            if ( false !== strpos( $content_lower, $indicator ) ) {
    29972964                $has_indicator = true;
     
    32383205     * Get comprehensive malware detection patterns.
    32393206     *
    3240      * Patterns are organized by category for better reporting.
    3241      * Based on community research and known malware signatures.
     3207     * Patterns are fetched from the Atomic Edge API to prevent the plugin
     3208     * from being flagged as malware by hosting provider security scanners.
    32423209     *
    32433210     * @return array Associative array of pattern groups.
     
    32483215        }
    32493216
    3250         $this->patterns_cache = array(
    3251             // Critical: Direct code execution patterns.
    3252             'code_execution'       => array(
    3253                 'eval\s*\('                                                          => __( 'Eval function (code execution)', 'atomic-edge-security' ),
    3254                 'assert\s*\('                                                        => __( 'Assert function (potential code execution)', 'atomic-edge-security' ),
    3255                 'create_function\s*\('                                               => __( 'Create function (dynamic code creation)', 'atomic-edge-security' ),
    3256                 'call_user_func\s*\('                                                => __( 'Call user func (dynamic function call)', 'atomic-edge-security' ),
    3257                 'call_user_func_array\s*\('                                          => __( 'Call user func array (dynamic function call)', 'atomic-edge-security' ),
    3258                 'preg_replace\s*\([^,]+["\'].*\/e["\']'                               => __( 'Preg replace with eval modifier', 'atomic-edge-security' ),
    3259                 'preg_replace_callback\s*\('                                         => __( 'Preg replace callback (potential code execution)', 'atomic-edge-security' ),
    3260             ),
    3261 
    3262             // Critical: Shell/system execution.
    3263             'shell_execution'      => array(
    3264                 '\bsystem\s*\('                                                      => __( 'System command execution', 'atomic-edge-security' ),
    3265                 '\bexec\s*\('                                                        => __( 'Exec command execution', 'atomic-edge-security' ),
    3266                 '\bshell_exec\s*\('                                                  => __( 'Shell exec command', 'atomic-edge-security' ),
    3267                 '\bpassthru\s*\('                                                    => __( 'Passthru command execution', 'atomic-edge-security' ),
    3268                 '\bpopen\s*\('                                                       => __( 'Popen command execution', 'atomic-edge-security' ),
    3269                 '\bproc_open\s*\('                                                   => __( 'Proc open command execution', 'atomic-edge-security' ),
    3270                 '\bpcntl_exec\s*\('                                                  => __( 'PCNTL exec', 'atomic-edge-security' ),
    3271                 '`[^`]+`'                                                            => __( 'Backtick command execution', 'atomic-edge-security' ),
    3272             ),
    3273 
    3274             // Critical: Backdoor patterns.
    3275             'backdoor_patterns'    => array(
    3276                 '@eval\s*\(\s*\$_(?:GET|POST|REQUEST|COOKIE)'                        => __( 'Backdoor: eval with user input', 'atomic-edge-security' ),
    3277                 '@eval\s*\(\s*base64_decode'                                         => __( 'Backdoor: eval with base64', 'atomic-edge-security' ),
    3278                 '\$_(?:GET|POST|REQUEST|COOKIE)\s*\[[^\]]+\]\s*\('                   => __( 'Direct superglobal execution', 'atomic-edge-security' ),
    3279                 'extract\s*\(\s*\$_(?:GET|POST|REQUEST)'                             => __( 'Dangerous extract from user input', 'atomic-edge-security' ),
    3280                 'include\s*\(\s*\$_(?:GET|POST|REQUEST)'                             => __( 'Remote file inclusion via user input', 'atomic-edge-security' ),
    3281                 'require\s*\(\s*\$_(?:GET|POST|REQUEST)'                             => __( 'Remote file inclusion via user input', 'atomic-edge-security' ),
    3282                 'file_put_contents\s*\([^,]+,\s*\$_(?:GET|POST|REQUEST)'             => __( 'File write from user input', 'atomic-edge-security' ),
    3283                 'fwrite\s*\([^,]+,\s*\$_(?:GET|POST|REQUEST)'                        => __( 'File write from user input', 'atomic-edge-security' ),
    3284             ),
    3285 
    3286             // High: Obfuscation techniques.
    3287             'obfuscation'          => array(
    3288                 'base64_decode\s*\('                                                 => __( 'Base64 decoding (potential obfuscation)', 'atomic-edge-security' ),
    3289                 'gzinflate\s*\('                                                     => __( 'Gzip inflate (potential obfuscation)', 'atomic-edge-security' ),
    3290                 'gzuncompress\s*\('                                                  => __( 'Gzip uncompress (potential obfuscation)', 'atomic-edge-security' ),
    3291                 'str_rot13\s*\('                                                     => __( 'ROT13 encoding (potential obfuscation)', 'atomic-edge-security' ),
    3292                 'convert_uudecode\s*\('                                              => __( 'UUdecode (potential obfuscation)', 'atomic-edge-security' ),
    3293                 '\\\\x[0-9a-fA-F]{2}(\\\\x[0-9a-fA-F]{2}){5,}'                        => __( 'Hex encoded strings', 'atomic-edge-security' ),
    3294                 'chr\s*\(\s*\d+\s*\)\s*\.\s*chr\s*\(\s*\d+\s*\)(\s*\.\s*chr\s*\(\s*\d+\s*\)){3,}' => __( 'Chr() string building', 'atomic-edge-security' ),
    3295                 'edoced_46esab'                                                      => __( 'Reversed base64_decode', 'atomic-edge-security' ),
    3296                 'strrev\s*\(["\'][^"\']+["\']\)'                                      => __( 'String reversal (obfuscation)', 'atomic-edge-security' ),
    3297             ),
    3298 
    3299             // High: Known webshell signatures.
    3300             'webshells'            => array(
    3301                 'c99shell'                                                           => __( 'C99 shell signature', 'atomic-edge-security' ),
    3302                 'r57shell'                                                           => __( 'R57 shell signature', 'atomic-edge-security' ),
    3303                 'b374k'                                                              => __( 'B374K shell signature', 'atomic-edge-security' ),
    3304                 'FilesMan'                                                           => __( 'FilesMan shell signature', 'atomic-edge-security' ),
    3305                 'WSO\s+[\d\.]+'                                                      => __( 'WSO shell signature', 'atomic-edge-security' ),
    3306                 'Weevely'                                                            => __( 'Weevely shell signature', 'atomic-edge-security' ),
    3307                 'php\s*spy'                                                          => __( 'PHPSpy shell signature', 'atomic-edge-security' ),
    3308                 'PHANTOMJS'                                                          => __( 'PhantomJS shell signature', 'atomic-edge-security' ),
    3309                 'Mister Spy'                                                         => __( 'Mister Spy shell signature', 'atomic-edge-security' ),
    3310                 'Afghan Shell'                                                       => __( 'Afghan Shell signature', 'atomic-edge-security' ),
    3311                 'Shell by'                                                           => __( 'Generic shell signature', 'atomic-edge-security' ),
    3312                 'SHELL_PASSWORD'                                                     => __( 'Shell password variable', 'atomic-edge-security' ),
    3313                 '0day'                                                               => __( '0day exploit reference', 'atomic-edge-security' ),
    3314             ),
    3315 
    3316             // High: WordPress-specific malware.
    3317             'wordpress_malware'    => array(
    3318                 'wp-vcd'                                                             => __( 'WP-VCD malware', 'atomic-edge-security' ),
    3319                 'class\.theme-modules\.php'                                          => __( 'WP-VCD theme modules', 'atomic-edge-security' ),
    3320                 'class\.plugin-modules\.php'                                         => __( 'WP-VCD plugin modules', 'atomic-edge-security' ),
    3321                 'wp-tmp\.php'                                                        => __( 'WP-VCD temp file', 'atomic-edge-security' ),
    3322                 'tmpcontentx'                                                        => __( 'WP-VCD content injection', 'atomic-edge-security' ),
    3323                 'wp_temp_setupx'                                                     => __( 'WP-VCD setup function', 'atomic-edge-security' ),
    3324                 'derna\.top'                                                         => __( 'Known malware domain', 'atomic-edge-security' ),
    3325                 '/\*\s*@noupdate\s*\*/'                                              => __( 'Plugin update suppression', 'atomic-edge-security' ),
    3326             ),
    3327 
    3328             // Medium: Suspicious file operations.
    3329             'file_operations'      => array(
    3330                 'file_get_contents\s*\(["\']https?://'                               => __( 'Remote file fetch', 'atomic-edge-security' ),
    3331                 'file_get_contents\s*\(["\']php://input'                             => __( 'Raw POST data read', 'atomic-edge-security' ),
    3332                 'curl_exec\s*\('                                                     => __( 'cURL execution', 'atomic-edge-security' ),
    3333                 'fsockopen\s*\('                                                     => __( 'Socket connection', 'atomic-edge-security' ),
    3334                 'stream_socket_client\s*\('                                          => __( 'Stream socket client', 'atomic-edge-security' ),
    3335             ),
    3336 
    3337             // Medium: Base64 encoded suspicious keywords.
    3338             'base64_keywords'      => array(
    3339                 'ZXZhbCg'                                                            => __( 'Base64: eval(', 'atomic-edge-security' ),
    3340                 'YXNzZXJ0'                                                           => __( 'Base64: assert', 'atomic-edge-security' ),
    3341                 'c3lzdGVt'                                                           => __( 'Base64: system', 'atomic-edge-security' ),
    3342                 'ZXhlYyg'                                                            => __( 'Base64: exec(', 'atomic-edge-security' ),
    3343                 'c2hlbGxfZXhlYw'                                                     => __( 'Base64: shell_exec', 'atomic-edge-security' ),
    3344                 'cGFzc3RocnU'                                                        => __( 'Base64: passthru', 'atomic-edge-security' ),
    3345                 'JF9HRV'                                                             => __( 'Base64: $_GET', 'atomic-edge-security' ),
    3346                 'JF9QT1NU'                                                           => __( 'Base64: $_POST', 'atomic-edge-security' ),
    3347                 'JF9SRVFVRVNU'                                                       => __( 'Base64: $_REQUEST', 'atomic-edge-security' ),
    3348                 'JF9DT09LSUU'                                                        => __( 'Base64: $_COOKIE', 'atomic-edge-security' ),
    3349                 'SFRUUF9VU0VSX0FHRU5U'                                               => __( 'Base64: HTTP_USER_AGENT', 'atomic-edge-security' ),
    3350                 'R0xPQkFMU'                                                          => __( 'Base64: GLOBALS', 'atomic-edge-security' ),
    3351             ),
    3352 
    3353             // Medium: Suspicious strings and indicators.
    3354             'suspicious_strings'   => array(
    3355                 '/etc/passwd'                                                            => __( 'Password file access', 'atomic-edge-security' ),
    3356                 '/etc/shadow'                                                            => __( 'Shadow file access', 'atomic-edge-security' ),
    3357                 'HACKED BY'                                                          => __( 'Defacement signature', 'atomic-edge-security' ),
    3358                 'owned by'                                                           => __( 'Defacement signature', 'atomic-edge-security' ),
    3359                 'backdoor'                                                           => __( 'Backdoor keyword', 'atomic-edge-security' ),
    3360                 'rootkit'                                                            => __( 'Rootkit keyword', 'atomic-edge-security' ),
    3361                 'c999sh'                                                             => __( 'Shell variant', 'atomic-edge-security' ),
    3362                 'r57sh'                                                              => __( 'Shell variant', 'atomic-edge-security' ),
    3363                 'webshell'                                                           => __( 'Webshell keyword', 'atomic-edge-security' ),
    3364                 'cmd\.exe'                                                           => __( 'Windows command execution', 'atomic-edge-security' ),
    3365                 'powershell\.exe'                                                    => __( 'PowerShell execution', 'atomic-edge-security' ),
    3366                 'uname\s+-a'                                                         => __( 'System information gathering', 'atomic-edge-security' ),
    3367                 'whoami'                                                             => __( 'User identification command', 'atomic-edge-security' ),
    3368             ),
    3369 
    3370             // Medium: Network indicators.
    3371             'network_indicators'   => array(
    3372 'fsockopen\s*\(["\']udp://'                                              => __( 'UDP socket (potential DDoS)', 'atomic-edge-security' ),
    3373                 'socket_create\s*\(\s*AF_INET'                                       => __( 'Raw socket creation', 'atomic-edge-security' ),
    3374                 'curl_setopt[^;]+CURLOPT_FOLLOWLOCATION'                             => __( 'cURL with redirect following', 'atomic-edge-security' ),
    3375             ),
    3376 
    3377             // Low: Potentially dangerous functions (context-dependent).
    3378             'potentially_dangerous' => array(
    3379                 'unserialize\s*\(\s*\$_(?:GET|POST|REQUEST|COOKIE)'                  => __( 'Unserialize user input (object injection)', 'atomic-edge-security' ),
    3380                 'serialize\s*\([^)]+\)\s*\.'                                         => __( 'Serialized data concatenation', 'atomic-edge-security' ),
    3381                 'ini_set\s*\(["\'](?:allow_url_fopen|allow_url_include)'             => __( 'INI override for remote includes', 'atomic-edge-security' ),
    3382                 'ini_set\s*\(["\']disable_functions'                                 => __( 'Attempt to modify disabled functions', 'atomic-edge-security' ),
    3383                 'error_reporting\s*\(\s*0\s*\)'                                      => __( 'Error reporting disabled', 'atomic-edge-security' ),
    3384                 'set_error_handler\s*\(\s*null'                                      => __( 'Error handler nullified', 'atomic-edge-security' ),
    3385             ),
    3386         );
    3387 
     3217        // Try to fetch from API.
     3218        $api_patterns = $this->get_api_signatures();
     3219
     3220        if ( ! empty( $api_patterns['patterns'] ) ) {
     3221            $this->patterns_cache = $api_patterns['patterns'];
     3222            return $this->patterns_cache;
     3223        }
     3224
     3225        // Fallback: Return empty patterns if API unavailable.
     3226        // This ensures the scanner doesn't crash, but it will not detect malware.
     3227        AtomicEdge::log( 'Scanner running without malware signatures - API unavailable' );
     3228        $this->patterns_cache = array();
    33883229        return $this->patterns_cache;
     3230    }
     3231
     3232    /**
     3233     * Get quick rejection indicators.
     3234     *
     3235     * These are fast string checks to skip expensive regex matching.
     3236     *
     3237     * @return array List of quick rejection strings.
     3238     */
     3239    private function get_quick_rejection_indicators() {
     3240        if ( is_array( $this->quick_rejection_indicators ) ) {
     3241            return $this->quick_rejection_indicators;
     3242        }
     3243
     3244        $api_signatures = $this->get_api_signatures();
     3245
     3246        if ( ! empty( $api_signatures['quick_indicators'] ) ) {
     3247            $this->quick_rejection_indicators = $api_signatures['quick_indicators'];
     3248            return $this->quick_rejection_indicators;
     3249        }
     3250
     3251        // Fallback: Empty array.
     3252        $this->quick_rejection_indicators = array();
     3253        return $this->quick_rejection_indicators;
     3254    }
     3255
     3256    /**
     3257     * Get API signatures (cached).
     3258     *
     3259     * @return array Signature data from API.
     3260     */
     3261    private function get_api_signatures() {
     3262        if ( is_array( $this->api_signatures ) ) {
     3263            return $this->api_signatures;
     3264        }
     3265
     3266        // Try to get API instance.
     3267        $api = $this->api;
     3268        if ( null === $api ) {
     3269            // Try to get global API instance.
     3270            if ( class_exists( 'AtomicEdge' ) && method_exists( 'AtomicEdge', 'get_instance' ) ) {
     3271                $instance = AtomicEdge::get_instance();
     3272                if ( method_exists( $instance, 'get_api' ) ) {
     3273                    $api = $instance->get_api();
     3274                }
     3275            }
     3276        }
     3277
     3278        if ( null === $api || ! method_exists( $api, 'get_malware_signatures' ) ) {
     3279            $this->api_signatures = array();
     3280            return $this->api_signatures;
     3281        }
     3282
     3283        $signatures = $api->get_malware_signatures();
     3284
     3285        if ( false === $signatures || ! is_array( $signatures ) ) {
     3286            $this->api_signatures = array();
     3287            return $this->api_signatures;
     3288        }
     3289
     3290        $this->api_signatures = $signatures;
     3291        return $this->api_signatures;
     3292    }
     3293
     3294    /**
     3295     * Check if the scanner has signatures loaded.
     3296     *
     3297     * @return bool True if signatures are available.
     3298     */
     3299    public function has_signatures() {
     3300        $signatures = $this->get_api_signatures();
     3301        return ! empty( $signatures['patterns'] );
     3302    }
     3303
     3304    /**
     3305     * Get signature version.
     3306     *
     3307     * @return string|null Version string or null if not available.
     3308     */
     3309    public function get_signature_version() {
     3310        $signatures = $this->get_api_signatures();
     3311        return isset( $signatures['version'] ) ? $signatures['version'] : null;
    33893312    }
    33903313
     
    33963319     */
    33973320    private function get_pattern_severity( $category ) {
    3398         $severity_map = array(
    3399             'code_execution'        => 'critical',
    3400             'shell_execution'       => 'critical',
    3401             'backdoor_patterns'     => 'critical',
    3402             'webshells'             => 'critical',
    3403             'wordpress_malware'     => 'critical',
    3404             'obfuscation'           => 'high',
    3405             'file_operations'       => 'medium',
    3406             'base64_keywords'       => 'medium',
    3407             'suspicious_strings'    => 'medium',
    3408             'network_indicators'    => 'medium',
    3409             'potentially_dangerous' => 'low',
    3410         );
    3411 
    3412         return isset( $severity_map[ $category ] ) ? $severity_map[ $category ] : 'medium';
     3321        // Try to get from API signatures.
     3322        $signatures = $this->get_api_signatures();
     3323
     3324        if ( ! empty( $signatures['severity_map'][ $category ] ) ) {
     3325            return $signatures['severity_map'][ $category ];
     3326        }
     3327
     3328        // Default fallback.
     3329        return 'medium';
    34133330    }
    34143331
  • atomic-edge-security/trunk/readme.txt

    r3459845 r3459867  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.2.1
     7Stable tag: 2.2.2
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    110110
    111111== Changelog ==
     112
     113= 2.2.2 =
     114* FIX: Malware scanner signatures moved to remote API to prevent hosting providers from flagging the plugin as malware
     115* Signatures are now fetched from the Atomic Edge API and cached locally for 24 hours
     116* This resolves false positives from security scanners detecting plaintext malware patterns in the plugin source code
    112117
    113118= 2.2.1 =
Note: See TracChangeset for help on using the changeset viewer.