Plugin Directory

Changeset 3488330


Ignore:
Timestamp:
03/22/2026 05:30:36 PM (7 days ago)
Author:
freelancebo
Message:

v2.3.0: Database spam detection, homepage HTML output scanning, improved hidden content detection, gambling/SEO spam signatures

Location:
freelancebo-sentra-control/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • freelancebo-sentra-control/trunk/freelancebo-sentra-control.php

    r3487530 r3488330  
    44 * Plugin URI: https://freelancebo.it
    55 * Description: WordPress security agent - connects to FreelanceBo Sentra Control central console for WAF, malware scanning, brute force protection, and file integrity monitoring.
    6  * Version: 2.2.5
     6 * Version: 2.3.0
    77 * Author: Freelancebo
    88 * License: GPL-2.0-or-later
     
    1212if (!defined('ABSPATH')) exit;
    1313
    14 define("SENTRA_VERSION", "2.2.5");
     14define("SENTRA_VERSION", "2.3.0");
    1515define('SENTRA_PLUGIN_DIR', plugin_dir_path(__FILE__));
    1616define('SENTRA_PLUGIN_URL', plugin_dir_url(__FILE__));
  • freelancebo-sentra-control/trunk/includes/modules/class-sentra-malware-scanner.php

    r3486674 r3488330  
    3131        'inet_pton.*cidr|cidr.*inet_pton' => ['name' => 'IP Range Check (Cloaking)', 'severity' => 'high'],
    3232
    33         // === Hidden content injection ===
    34         'position:\s*absolute[^"]*?left:\s*-[5-9]\d{3,}px' => ['name' => 'Hidden Content Injection (off-screen)', 'severity' => 'high'],
     33        // === Hidden content injection (file-level) ===
     34        'position:\s*(?:absolute|fixed)[^"]*?(?:left|top):\s*-[5-9]\d{3,}px' => ['name' => 'Hidden Content Injection (off-screen)', 'severity' => 'high'],
    3535        'opacity:\s*0\.00[1-9].*?z-index:\s*-1' => ['name' => 'Hidden Content Injection (invisible)', 'severity' => 'high'],
     36
     37        // === Gambling / SEO spam link patterns in PHP files ===
     38        'href.*(?:casino|slots\.org|betting|lottoland|justcasino|merkurslots|amazonslots)' => ['name' => 'Gambling/SEO Spam Link in PHP', 'severity' => 'critical'],
     39        'display:\s*none[^"]*?(?:casino|slots|betting|gambling|roulette|poker)' => ['name' => 'Hidden Gambling Content in PHP', 'severity' => 'critical'],
    3640
    3741        // === Admin post hiding (SEO spam) ===
     
    202206        }
    203207
     208        // Include database spam scan
     209        $db_findings = $this->scan_database_spam();
     210        $findings = array_merge($findings, $db_findings);
     211
     212        // Include homepage HTML output scan
     213        $html_findings = $this->scan_homepage_output();
     214        $findings = array_merge($findings, $html_findings);
     215
    204216        return $findings;
    205217    }
     218
     219    /**
     220     * Scan WordPress database for SEO spam injection.
     221     * Checks wp_options and wp_posts for gambling/casino link patterns.
     222     */
     223    public function scan_database_spam() {
     224        global $wpdb;
     225        $findings = [];
     226
     227        $spam_patterns = [
     228            'amazonslots', 'merkurslots', 'lottoland', 'justcasino',
     229            'casino-online', 'betting-site', 'poker-room', 'slot-machine',
     230        ];
     231
     232        // Check wp_options (widgets, theme settings, custom blocks)
     233        foreach ($spam_patterns as $pattern) {
     234            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
     235            $results = $wpdb->get_results($wpdb->prepare(
     236                "SELECT option_name, LENGTH(option_value) as val_len FROM {$wpdb->options} WHERE option_value LIKE %s LIMIT 5",
     237                '%' . $wpdb->esc_like($pattern) . '%'
     238            ));
     239            foreach ($results as $row) {
     240                $findings[] = [
     241                    'file'      => "database:wp_options:{$row->option_name}",
     242                    'signature' => 'SEO Spam in Database (wp_options)',
     243                    'severity'  => 'critical',
     244                    'size'      => (int) $row->val_len,
     245                    'modified'  => current_time('Y-m-d H:i:s'),
     246                    'detail'    => "Pattern: {$pattern}",
     247                ];
     248            }
     249        }
     250
     251        // Check wp_posts for spam links in content
     252        $link_patterns = ['casino', 'slots.org', 'betting', 'lottoland', 'justcasino', 'amazonslots', 'merkurslots'];
     253        foreach ($link_patterns as $pattern) {
     254            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
     255            $posts = $wpdb->get_results($wpdb->prepare(
     256                "SELECT ID, post_title, post_type FROM {$wpdb->posts} WHERE (post_content LIKE %s OR post_excerpt LIKE %s) AND post_status != %s LIMIT 5",
     257                '%' . $wpdb->esc_like($pattern) . '%',
     258                '%' . $wpdb->esc_like($pattern) . '%',
     259                'trash'
     260            ));
     261            foreach ($posts as $post) {
     262                $findings[] = [
     263                    'file'      => "database:wp_posts:ID={$post->ID}",
     264                    'signature' => 'SEO Spam in Post Content',
     265                    'severity'  => 'critical',
     266                    'size'      => 0,
     267                    'modified'  => current_time('Y-m-d H:i:s'),
     268                    'detail'    => "Post: {$post->post_title} (type: {$post->post_type}), pattern: {$pattern}",
     269                ];
     270            }
     271        }
     272
     273        // Check wp_postmeta for spam in custom fields
     274        $meta_patterns = ['casino', 'slots.org', 'betting', 'gambling'];
     275        foreach ($meta_patterns as $pattern) {
     276            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
     277            $metas = $wpdb->get_results($wpdb->prepare(
     278                "SELECT post_id, meta_key FROM {$wpdb->postmeta} WHERE meta_value LIKE %s LIMIT 5",
     279                '%' . $wpdb->esc_like($pattern) . '%'
     280            ));
     281            foreach ($metas as $meta) {
     282                $findings[] = [
     283                    'file'      => "database:wp_postmeta:post_id={$meta->post_id}",
     284                    'signature' => 'SEO Spam in Post Meta',
     285                    'severity'  => 'high',
     286                    'size'      => 0,
     287                    'modified'  => current_time('Y-m-d H:i:s'),
     288                    'detail'    => "Meta key: {$meta->meta_key}, pattern: {$pattern}",
     289                ];
     290            }
     291        }
     292
     293        return $findings;
     294    }
     295
     296    /**
     297     * Scan the site homepage HTML output for hidden spam injection.
     298     * Detects spam that lives in the database or is injected via hooks,
     299     * not visible in PHP source files.
     300     */
     301    public function scan_homepage_output() {
     302        $findings = [];
     303
     304        $home_url = get_home_url();
     305        $response = wp_remote_get($home_url, [
     306            'timeout'    => 15,
     307            'sslverify'  => false,
     308            'user-agent' => 'Sentra Security Scanner',
     309        ]);
     310
     311        if (is_wp_error($response)) {
     312            return $findings;
     313        }
     314
     315        $html = wp_remote_retrieve_body($response);
     316        if (empty($html)) {
     317            return $findings;
     318        }
     319
     320        // 1. Check for hidden divs with off-screen positioning (common spam injection)
     321        if (preg_match_all('/position:\s*(?:absolute|fixed)[^"\']*?(?:left|top):\s*-\d{4,}px/i', $html, $matches)) {
     322            $findings[] = [
     323                'file'      => 'homepage_html_output',
     324                'signature' => 'Hidden Content Injection (off-screen div in HTML output)',
     325                'severity'  => 'critical',
     326                'size'      => strlen($html),
     327                'modified'  => current_time('Y-m-d H:i:s'),
     328                'detail'    => 'Detected ' . count($matches[0]) . ' hidden off-screen element(s) in homepage HTML',
     329            ];
     330        }
     331
     332        // 2. Check for gambling/casino spam links in rendered HTML
     333        $spam_link_pattern = '/href\s*=\s*["\']https?:\/\/[^"\']*(?:casino|slots\.org|betting|gambling|lottoland|justcasino|merkurslots|amazonslots)[^"\']*["\']/i';
     334        if (preg_match_all($spam_link_pattern, $html, $link_matches)) {
     335            $unique_links = array_unique($link_matches[0]);
     336            $findings[] = [
     337                'file'      => 'homepage_html_output',
     338                'signature' => 'Gambling/Casino Spam Links in HTML Output',
     339                'severity'  => 'critical',
     340                'size'      => strlen($html),
     341                'modified'  => current_time('Y-m-d H:i:s'),
     342                'detail'    => 'Found ' . count($unique_links) . ' gambling spam link(s): ' . implode(', ', array_slice($unique_links, 0, 5)),
     343            ];
     344        }
     345
     346        // 3. Generic spam keyword detection in hidden elements
     347        if (preg_match('/<div[^>]*style=[^>]*(?:display:\s*none|visibility:\s*hidden|position:\s*(?:absolute|fixed)[^"\']*-\d{3,})[^>]*>.*?(?:casino|slots|betting|gambling|roulette|poker)/is', $html)) {
     348            $findings[] = [
     349                'file'      => 'homepage_html_output',
     350                'signature' => 'SEO Spam in Hidden HTML Element',
     351                'severity'  => 'critical',
     352                'size'      => strlen($html),
     353                'modified'  => current_time('Y-m-d H:i:s'),
     354            ];
     355        }
     356
     357        return $findings;
     358    }
    206359}
  • freelancebo-sentra-control/trunk/readme.txt

    r3487530 r3488330  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.2.5
     7Stable tag: 2.3.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    7474
    7575== Changelog ==
     76
     77= 2.3.0 =
     78* NEW: Database spam detection - scans wp_options, wp_posts, wp_postmeta for SEO spam injection
     79* NEW: Homepage HTML output scanning - detects hidden gambling/casino link injection
     80* Improved hidden content detection: now catches position:fixed off-screen elements (not just absolute)
     81* Added gambling/SEO spam link signatures for PHP file scanning
     82* Detects common spam patterns: amazonslots, merkurslots, lottoland, justcasino, etc.
    7683
    7784= 2.2.5 =
     
    197204== Upgrade Notice ==
    198205
     206= 2.3.0 =
     207Major malware scanner upgrade: detects SEO spam injected in database and hidden gambling links in HTML output. Recommended for all users.
     208
    199209= 2.2.2 =
    200210New auto-patching system: automatically fix security vulnerabilities, quarantine malware, and patch abandoned plugins.
Note: See TracChangeset for help on using the changeset viewer.