PluginProbe
Atomic Edge Security – Firewall, Malware Scan and Login Security / 2.2.2
Atomic Edge Security – Firewall, Malware Scan and Login Security v2.2.2
trunk 2.0.0 2.1.0 2.2.0 2.2.1 2.2.2 2.3.0 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 All 29 releases
atomic-edge-security / admin / views / scanner.php

scanner.php in Atomic Edge Security – Firewall, Malware Scan and Login Security 2.2.2, at admin/views/scanner.php

415 lines 21.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Malware Scanner Page View
4 *
5 * @package AtomicEdge
6 */
7
8 // Prevent direct access.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 $atomicedge_scanner = AtomicEdge::get_instance()->scanner;
14 $atomicedge_last_scan = $atomicedge_scanner->get_last_scan_time();
15 $atomicedge_last_results = $atomicedge_scanner->get_last_results();
16 ?>
17 <div class="wrap atomicedge-wrap">
18 <h1><img src="<?php echo esc_url( ATOMICEDGE_PLUGIN_URL . 'admin/images/logo.svg' ); ?>" alt="<?php esc_attr_e( 'Atomic Edge', 'atomic-edge-security' ); ?>" class="atomicedge-logo" /></h1>
19
20 <div class="atomicedge-scanner">
21 <!-- Scanner Controls -->
22 <div class="atomicedge-scanner-controls">
23 <div class="atomicedge-scanner-info">
24 <?php if ( $atomicedge_last_scan ) : ?>
25 <p>
26 <?php
27 printf(
28 /* translators: %s: last scan time */
29 esc_html__( 'Last scan: %s', 'atomic-edge-security' ),
30 esc_html( $atomicedge_last_scan )
31 );
32 ?>
33 </p>
34 <?php else : ?>
35 <p><?php esc_html_e( 'No scans have been run yet.', 'atomic-edge-security' ); ?></p>
36 <?php endif; ?>
37 </div>
38
39 <div class="atomicedge-scanner-actions">
40 <div class="atomicedge-scan-controls" style="display: flex; align-items: flex-start; gap: 12px;">
41 <div class="atomicedge-scan-controls-left" style="display: flex; flex-direction: column;">
42 <label for="atomicedge-scan-mode" class="screen-reader-text"><?php esc_html_e( 'Scan mode', 'atomic-edge-security' ); ?></label>
43 <select id="atomicedge-scan-mode" class="atomicedge-scan-mode">
44 <option value="php" selected><?php esc_html_e( 'Quick scan (PHP only)', 'atomic-edge-security' ); ?></option>
45 <option value="all"><?php esc_html_e( 'Thorough scan (all files)', 'atomic-edge-security' ); ?></option>
46 </select>
47
48 <label for="atomicedge-verify-integrity" style="margin-top: 8px;">
49 <input type="checkbox" id="atomicedge-verify-integrity" value="1" />
50 <?php esc_html_e( 'Verify AtomicEdge plugin integrity', 'atomic-edge-security' ); ?>
51 </label>
52 </div>
53
54 <div class="atomicedge-scan-controls-right">
55 <button type="button" id="atomicedge-run-scan" class="button button-primary button-hero">
56 <span class="dashicons dashicons-search"></span>
57 <?php esc_html_e( 'Run Scan', 'atomic-edge-security' ); ?>
58 </button>
59
60 <button type="button" id="atomicedge-cancel-scan" class="button button-hero atomicedge-secondary-button">
61 <span class="dashicons dashicons-no-alt"></span>
62 <?php esc_html_e( 'Cancel Scan', 'atomic-edge-security' ); ?>
63 </button>
64
65 <button type="button" id="atomicedge-reset-scan" class="button button-hero atomicedge-secondary-button">
66 <span class="dashicons dashicons-trash"></span>
67 <?php esc_html_e( 'Reset Scan', 'atomic-edge-security' ); ?>
68 </button>
69
70 <?php if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) : ?>
71 <button type="button" id="atomicedge-debug-test" class="button button-hero" style="background: #9b59b6; border-color: #8e44ad; color: #fff;">
72 <span class="dashicons dashicons-performance"></span>
73 <?php esc_html_e( 'Debug Test (500 files)', 'atomic-edge-security' ); ?>
74 </button>
75 <?php endif; ?>
76 </div>
77 </div>
78 </div>
79 </div>
80
81 <!-- Debug Test Results (only shown in WP_DEBUG mode) -->
82 <?php if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) : ?>
83 <div id="atomicedge-debug-results" class="atomicedge-results-section" style="display: none; background: #f9f3ff; border: 2px solid #9b59b6; padding: 15px; margin-bottom: 20px;">
84 <h3 style="color: #8e44ad; margin-top: 0;"><?php esc_html_e( 'Debug Test Results', 'atomic-edge-security' ); ?></h3>
85 <pre id="atomicedge-debug-output" style="background: #fff; padding: 10px; overflow: auto; max-height: 400px;"></pre>
86 </div>
87 <?php endif; ?>
88
89 <!-- Scan Progress -->
90 <div id="atomicedge-scan-progress" class="atomicedge-scan-progress" style="display: none;">
91 <div class="atomicedge-progress-bar">
92 <div class="atomicedge-progress-fill"></div>
93 </div>
94 <p class="atomicedge-progress-text"><?php esc_html_e( 'Scanning files...', 'atomic-edge-security' ); ?></p>
95 </div>
96
97 <!-- Live Scan Log -->
98 <div id="atomicedge-scan-log" class="atomicedge-results-section" style="display: none;">
99 <h3><?php esc_html_e( 'Live Scan Activity', 'atomic-edge-security' ); ?></h3>
100 <p class="description"><?php esc_html_e( 'Shows what the scanner is working on right now. If progress stalls, this should still update as files are processed.', 'atomic-edge-security' ); ?></p>
101 <div class="atomicedge-scan-log" style="max-height: 240px; overflow: auto; background: #fff; border: 1px solid #ccd0d4; padding: 10px;">
102 <pre class="atomicedge-scan-log-lines" style="margin: 0; white-space: pre-wrap;"></pre>
103 </div>
104 </div>
105
106 <!-- Scan Results -->
107 <div id="atomicedge-scan-results" class="atomicedge-scan-results">
108 <?php if ( ! empty( $atomicedge_last_results ) ) : ?>
109 <!-- Summary -->
110 <div class="atomicedge-results-summary">
111 <h2><?php esc_html_e( 'Scan Results', 'atomic-edge-security' ); ?></h2>
112
113 <div class="atomicedge-summary-grid">
114 <div class="atomicedge-summary-item <?php echo empty( $atomicedge_last_results['core_files'] ) ? 'atomicedge-ok' : 'atomicedge-warning'; ?>">
115 <span class="dashicons <?php echo empty( $atomicedge_last_results['core_files'] ) ? 'dashicons-yes-alt' : 'dashicons-warning'; ?>"></span>
116 <span class="atomicedge-summary-count"><?php echo esc_html( count( $atomicedge_last_results['core_files'] ?? array() ) ); ?></span>
117 <span class="atomicedge-summary-label"><?php esc_html_e( 'Modified Core Files', 'atomic-edge-security' ); ?></span>
118 </div>
119 <div class="atomicedge-summary-item <?php echo empty( $atomicedge_last_results['suspicious'] ) ? 'atomicedge-ok' : 'atomicedge-critical'; ?>">
120 <span class="dashicons <?php echo empty( $atomicedge_last_results['suspicious'] ) ? 'dashicons-yes-alt' : 'dashicons-dismiss'; ?>"></span>
121 <span class="atomicedge-summary-count"><?php echo esc_html( count( $atomicedge_last_results['suspicious'] ?? array() ) ); ?></span>
122 <span class="atomicedge-summary-label"><?php esc_html_e( 'Suspicious Files', 'atomic-edge-security' ); ?></span>
123 </div>
124 <?php if ( array_key_exists( 'integrity_issues', $atomicedge_last_results ) ) : ?>
125 <?php $atomicedge_integrity_issues = is_array( $atomicedge_last_results['integrity_issues'] ?? null ) ? $atomicedge_last_results['integrity_issues'] : array(); ?>
126 <div class="atomicedge-summary-item <?php echo empty( $atomicedge_integrity_issues ) ? 'atomicedge-ok' : 'atomicedge-warning'; ?>">
127 <span class="dashicons <?php echo empty( $atomicedge_integrity_issues ) ? 'dashicons-yes-alt' : 'dashicons-warning'; ?>"></span>
128 <span class="atomicedge-summary-count"><?php echo esc_html( count( $atomicedge_integrity_issues ) ); ?></span>
129 <span class="atomicedge-summary-label"><?php esc_html_e( 'Integrity Issues', 'atomic-edge-security' ); ?></span>
130 </div>
131 <?php endif; ?>
132 </div>
133 </div>
134
135 <?php
136 $atomicedge_scan_diagnostics = isset( $atomicedge_last_results['scan_diagnostics'] ) && is_array( $atomicedge_last_results['scan_diagnostics'] ) ? $atomicedge_last_results['scan_diagnostics'] : array();
137 $atomicedge_diag_warnings = isset( $atomicedge_scan_diagnostics['warnings'] ) && is_array( $atomicedge_scan_diagnostics['warnings'] ) ? $atomicedge_scan_diagnostics['warnings'] : array();
138 $atomicedge_diag_counts = isset( $atomicedge_scan_diagnostics['counts'] ) && is_array( $atomicedge_scan_diagnostics['counts'] ) ? $atomicedge_scan_diagnostics['counts'] : array();
139 $atomicedge_diag_samples = isset( $atomicedge_scan_diagnostics['samples'] ) && is_array( $atomicedge_scan_diagnostics['samples'] ) ? $atomicedge_scan_diagnostics['samples'] : array();
140 $atomicedge_diag_areas = isset( $atomicedge_scan_diagnostics['areas'] ) && is_array( $atomicedge_scan_diagnostics['areas'] ) ? $atomicedge_scan_diagnostics['areas'] : array();
141 ?>
142
143 <?php if ( ! empty( $atomicedge_scan_diagnostics ) ) : ?>
144 <div class="atomicedge-results-section">
145 <h3><?php esc_html_e( 'Scan Coverage & Warnings', 'atomic-edge-security' ); ?></h3>
146
147 <?php
148 $atomicedge_stopped_early = ! empty( $atomicedge_scan_diagnostics['stopped_early'] );
149 $atomicedge_stopped_early_reason = isset( $atomicedge_scan_diagnostics['stopped_early_reason'] ) ? (string) $atomicedge_scan_diagnostics['stopped_early_reason'] : '';
150 $atomicedge_stopped_early_reason_label = '';
151 switch ( $atomicedge_stopped_early_reason ) {
152 case 'memory_limit':
153 $atomicedge_stopped_early_reason_label = __( 'Memory limit reached', 'atomic-edge-security' );
154 break;
155 case 'timeout':
156 $atomicedge_stopped_early_reason_label = __( 'Execution time limit reached', 'atomic-edge-security' );
157 break;
158 default:
159 $atomicedge_stopped_early_reason_label = '';
160 break;
161 }
162 ?>
163
164 <?php if ( $atomicedge_stopped_early ) : ?>
165 <p><strong><?php esc_html_e( 'Stopped early:', 'atomic-edge-security' ); ?></strong> <?php echo esc_html( $atomicedge_stopped_early_reason_label ? $atomicedge_stopped_early_reason_label : __( 'Scan did not complete', 'atomic-edge-security' ) ); ?><?php echo esc_html( $atomicedge_stopped_early_reason ? ' (' . $atomicedge_stopped_early_reason . ')' : '' ); ?></p>
166 <?php endif; ?>
167
168 <?php if ( ! empty( $atomicedge_diag_warnings ) ) : ?>
169 <div class="notice notice-warning inline">
170 <p><strong><?php esc_html_e( 'This scan may be incomplete.', 'atomic-edge-security' ); ?></strong></p>
171 <ul>
172 <?php foreach ( array_slice( $atomicedge_diag_warnings, 0, 10 ) as $atomicedge_warning ) : ?>
173 <li><?php echo esc_html( $atomicedge_warning ); ?></li>
174 <?php endforeach; ?>
175 </ul>
176 </div>
177 <?php endif; ?>
178
179 <?php
180 $atomicedge_counts_line = array();
181 if ( ! empty( $atomicedge_diag_counts['dirs_unreadable'] ) ) {
182 /* translators: %d: number of unreadable directories */
183 $atomicedge_counts_line[] = sprintf( __( 'Unreadable dirs: %d', 'atomic-edge-security' ), (int) $atomicedge_diag_counts['dirs_unreadable'] );
184 }
185 if ( ! empty( $atomicedge_diag_counts['dirs_missing'] ) ) {
186 /* translators: %d: number of missing directories */
187 $atomicedge_counts_line[] = sprintf( __( 'Missing dirs: %d', 'atomic-edge-security' ), (int) $atomicedge_diag_counts['dirs_missing'] );
188 }
189 if ( ! empty( $atomicedge_diag_counts['files_read_failed'] ) ) {
190 /* translators: %d: number of file read failures */
191 $atomicedge_counts_line[] = sprintf( __( 'Read failures: %d', 'atomic-edge-security' ), (int) $atomicedge_diag_counts['files_read_failed'] );
192 }
193 if ( ! empty( $atomicedge_diag_counts['files_partially_scanned'] ) ) {
194 /* translators: %d: number of oversized files partially scanned */
195 $atomicedge_counts_line[] = sprintf( __( 'Oversized partially scanned: %d', 'atomic-edge-security' ), (int) $atomicedge_diag_counts['files_partially_scanned'] );
196 }
197 if ( ! empty( $atomicedge_diag_counts['files_skipped_whitelist'] ) ) {
198 /* translators: %d: number of whitelisted files skipped */
199 $atomicedge_counts_line[] = sprintf( __( 'Whitelisted skipped: %d', 'atomic-edge-security' ), (int) $atomicedge_diag_counts['files_skipped_whitelist'] );
200 }
201 ?>
202
203 <?php if ( ! empty( $atomicedge_counts_line ) ) : ?>
204 <p><?php echo esc_html( implode( ' · ', $atomicedge_counts_line ) ); ?></p>
205 <?php endif; ?>
206
207 <?php if ( ! empty( $atomicedge_diag_areas ) ) : ?>
208 <table class="wp-list-table widefat fixed striped">
209 <thead>
210 <tr>
211 <th><?php esc_html_e( 'Area', 'atomic-edge-security' ); ?></th>
212 <th><?php esc_html_e( 'PHP found', 'atomic-edge-security' ); ?></th>
213 <th><?php esc_html_e( 'PHP scanned', 'atomic-edge-security' ); ?></th>
214 </tr>
215 </thead>
216 <tbody>
217 <?php foreach ( $atomicedge_diag_areas as $atomicedge_area_key => $atomicedge_area_stats ) : ?>
218 <tr>
219 <td><?php echo esc_html( (string) $atomicedge_area_key ); ?></td>
220 <td><?php echo esc_html( isset( $atomicedge_area_stats['php_files_found'] ) ? (string) (int) $atomicedge_area_stats['php_files_found'] : '0' ); ?></td>
221 <td><?php echo esc_html( isset( $atomicedge_area_stats['php_files_scanned'] ) ? (string) (int) $atomicedge_area_stats['php_files_scanned'] : '0' ); ?></td>
222 </tr>
223 <?php endforeach; ?>
224 </tbody>
225 </table>
226 <?php endif; ?>
227
228 <?php if ( ! empty( $atomicedge_diag_samples['unreadable_dirs'] ) || ! empty( $atomicedge_diag_samples['read_failed_files'] ) || ! empty( $atomicedge_diag_samples['oversized_files'] ) ) : ?>
229 <p class="description"><em><?php esc_html_e( 'Examples (first 5):', 'atomic-edge-security' ); ?></em></p>
230 <ul>
231 <?php if ( ! empty( $atomicedge_diag_samples['unreadable_dirs'] ) ) : ?>
232 <li><?php echo esc_html__( 'Unreadable dirs:', 'atomic-edge-security' ) . ' ' . esc_html( implode( ', ', $atomicedge_diag_samples['unreadable_dirs'] ) ); ?></li>
233 <?php endif; ?>
234 <?php if ( ! empty( $atomicedge_diag_samples['read_failed_files'] ) ) : ?>
235 <li><?php echo esc_html__( 'Read failures:', 'atomic-edge-security' ) . ' ' . esc_html( implode( ', ', $atomicedge_diag_samples['read_failed_files'] ) ); ?></li>
236 <?php endif; ?>
237 <?php if ( ! empty( $atomicedge_diag_samples['oversized_files'] ) ) : ?>
238 <li><?php echo esc_html__( 'Oversized partially scanned:', 'atomic-edge-security' ) . ' ' . esc_html( implode( ', ', $atomicedge_diag_samples['oversized_files'] ) ); ?></li>
239 <?php endif; ?>
240 </ul>
241 <?php endif; ?>
242 </div>
243 <?php endif; ?>
244
245 <?php if ( ! empty( $atomicedge_last_results['integrity_issues'] ) && is_array( $atomicedge_last_results['integrity_issues'] ) ) : ?>
246 <div class="atomicedge-results-section" data-paginate="true" data-per-page="10">
247 <h3>
248 <?php esc_html_e( 'AtomicEdge Plugin Integrity Issues', 'atomic-edge-security' ); ?>
249 <span class="atomicedge-results-count">(<?php echo esc_html( count( $atomicedge_last_results['integrity_issues'] ) ); ?>)</span>
250 </h3>
251 <p class="description"><?php esc_html_e( 'These files did not match the expected release manifest. This can indicate tampering or a partial/failed update.', 'atomic-edge-security' ); ?></p>
252 <table class="wp-list-table widefat fixed striped">
253 <thead>
254 <tr>
255 <th><?php esc_html_e( 'File', 'atomic-edge-security' ); ?></th>
256 <th><?php esc_html_e( 'Issue', 'atomic-edge-security' ); ?></th>
257 </tr>
258 </thead>
259 <tbody>
260 <?php foreach ( $atomicedge_last_results['integrity_issues'] as $atomicedge_issue ) : ?>
261 <tr>
262 <td><code><?php echo esc_html( $atomicedge_issue['file'] ?? '' ); ?></code></td>
263 <td><?php echo esc_html( $atomicedge_issue['reason'] ?? ( $atomicedge_issue['type'] ?? '' ) ); ?></td>
264 </tr>
265 <?php endforeach; ?>
266 </tbody>
267 </table>
268 <div class="atomicedge-pagination"></div>
269 </div>
270 <?php endif; ?>
271
272 <!-- Modified Core Files -->
273 <?php if ( ! empty( $atomicedge_last_results['core_files'] ) ) : ?>
274 <div class="atomicedge-results-section" data-paginate="true" data-per-page="10">
275 <h3>
276 <?php esc_html_e( 'Modified Core Files', 'atomic-edge-security' ); ?>
277 <span class="atomicedge-results-count">(<?php echo esc_html( count( $atomicedge_last_results['core_files'] ) ); ?>)</span>
278 </h3>
279 <p class="description"><?php esc_html_e( 'These WordPress core files have been modified from their original versions.', 'atomic-edge-security' ); ?></p>
280 <table class="wp-list-table widefat fixed striped atomicedge-paginated-table">
281 <thead>
282 <tr>
283 <th><?php esc_html_e( 'File', 'atomic-edge-security' ); ?></th>
284 <th><?php esc_html_e( 'Severity', 'atomic-edge-security' ); ?></th>
285 </tr>
286 </thead>
287 <tbody>
288 <?php foreach ( $atomicedge_last_results['core_files'] as $atomicedge_issue ) : ?>
289 <tr>
290 <td><code><?php echo esc_html( $atomicedge_issue['file_path'] ?? $atomicedge_issue['file'] ); ?></code></td>
291 <td>
292 <span class="atomicedge-severity atomicedge-severity-<?php echo esc_attr( $atomicedge_issue['severity'] ); ?>">
293 <?php echo esc_html( ucfirst( $atomicedge_issue['severity'] ) ); ?>
294 </span>
295 </td>
296 </tr>
297 <?php endforeach; ?>
298 </tbody>
299 </table>
300 <div class="atomicedge-pagination"></div>
301 </div>
302 <?php endif; ?>
303
304 <!-- Suspicious Files -->
305 <?php if ( ! empty( $atomicedge_last_results['suspicious'] ) ) : ?>
306 <div class="atomicedge-results-section" data-paginate="true" data-per-page="10">
307 <h3>
308 <?php esc_html_e( 'Suspicious Files', 'atomic-edge-security' ); ?>
309 <span class="atomicedge-results-count">(<?php echo esc_html( count( $atomicedge_last_results['suspicious'] ) ); ?>)</span>
310 </h3>
311 <p class="description"><?php esc_html_e( 'These files contain potentially malicious code patterns.', 'atomic-edge-security' ); ?></p>
312 <table class="wp-list-table widefat fixed striped atomicedge-paginated-table">
313 <thead>
314 <tr>
315 <th><?php esc_html_e( 'File', 'atomic-edge-security' ); ?></th>
316 <th><?php esc_html_e( 'Issue', 'atomic-edge-security' ); ?></th>
317 <th><?php esc_html_e( 'Severity', 'atomic-edge-security' ); ?></th>
318 </tr>
319 </thead>
320 <tbody>
321 <?php foreach ( $atomicedge_last_results['suspicious'] as $atomicedge_issue ) : ?>
322 <tr>
323 <td><code><?php echo esc_html( $atomicedge_issue['file_path'] ?? $atomicedge_issue['file'] ); ?></code></td>
324 <td>
325 <?php
326 if ( isset( $atomicedge_issue['pattern'] ) ) {
327 echo esc_html( $atomicedge_issue['pattern'] );
328 } elseif ( isset( $atomicedge_issue['reason'] ) ) {
329 echo esc_html( $atomicedge_issue['reason'] );
330 }
331 ?>
332 </td>
333 <td>
334 <span class="atomicedge-severity atomicedge-severity-<?php echo esc_attr( $atomicedge_issue['severity'] ); ?>">
335 <?php echo esc_html( ucfirst( $atomicedge_issue['severity'] ) ); ?>
336 </span>
337 </td>
338 </tr>
339 <?php endforeach; ?>
340 </tbody>
341 </table>
342 <div class="atomicedge-pagination"></div>
343 </div>
344 <?php endif; ?>
345
346 <!-- All Clear -->
347 <?php if ( empty( $atomicedge_last_results['core_files'] ) && empty( $atomicedge_last_results['suspicious'] ) ) : ?>
348 <div class="atomicedge-all-clear">
349 <span class="dashicons dashicons-yes-alt"></span>
350 <h3><?php esc_html_e( 'All Clear!', 'atomic-edge-security' ); ?></h3>
351 <p><?php esc_html_e( 'No security issues were found in the last scan.', 'atomic-edge-security' ); ?></p>
352 </div>
353 <?php endif; ?>
354
355 <?php else : ?>
356 <div class="atomicedge-no-results">
357 <span class="dashicons dashicons-search"></span>
358 <h3><?php esc_html_e( 'No Scan Results', 'atomic-edge-security' ); ?></h3>
359 <p><?php esc_html_e( 'Run a scan to check your WordPress files for security issues.', 'atomic-edge-security' ); ?></p>
360 </div>
361 <?php endif; ?>
362 </div>
363
364 <!-- What We Check -->
365 <div class="atomicedge-scanner-info-box">
366 <h3><?php esc_html_e( 'What We Check', 'atomic-edge-security' ); ?></h3>
367 <ul>
368 <li>
369 <span class="dashicons dashicons-yes"></span>
370 <?php esc_html_e( 'WordPress core files against official checksums', 'atomic-edge-security' ); ?>
371 </li>
372 <li>
373 <span class="dashicons dashicons-yes"></span>
374 <?php esc_html_e( 'WordPress root directory for unknown PHP files', 'atomic-edge-security' ); ?>
375 </li>
376 <li>
377 <span class="dashicons dashicons-yes"></span>
378 <?php esc_html_e( 'wp-admin and wp-includes for malware patterns', 'atomic-edge-security' ); ?>
379 </li>
380 <li>
381 <span class="dashicons dashicons-yes"></span>
382 <?php esc_html_e( 'PHP files in uploads directory (should not exist)', 'atomic-edge-security' ); ?>
383 </li>
384 <li>
385 <span class="dashicons dashicons-yes"></span>
386 <?php esc_html_e( 'Suspicious code patterns (eval, base64_decode, etc.)', 'atomic-edge-security' ); ?>
387 </li>
388 <li>
389 <span class="dashicons dashicons-yes"></span>
390 <?php esc_html_e( 'Obfuscated code and known webshell signatures', 'atomic-edge-security' ); ?>
391 </li>
392 </ul>
393 </div>
394
395 <!-- PHP Environment Info -->
396 <div class="atomicedge-scanner-info-box atomicedge-environment-info">
397 <h3><?php esc_html_e( 'Environment', 'atomic-edge-security' ); ?></h3>
398 <ul>
399 <li>
400 <strong><?php esc_html_e( 'Memory Limit:', 'atomic-edge-security' ); ?></strong>
401 <?php echo esc_html( ini_get( 'memory_limit' ) ); ?>
402 </li>
403 <li>
404 <strong><?php esc_html_e( 'Max Execution Time:', 'atomic-edge-security' ); ?></strong>
405 <?php echo esc_html( ini_get( 'max_execution_time' ) ); ?>s
406 </li>
407 <li>
408 <strong><?php esc_html_e( 'PHP Version:', 'atomic-edge-security' ); ?></strong>
409 <?php echo esc_html( PHP_VERSION ); ?>
410 </li>
411 </ul>
412 </div>
413 </div>
414 </div>
415