| 1 |
<?php |
| 2 |
defined('ABSPATH') or die('Unauthorized Access'); |
| 3 |
|
| 4 |
if (!Phpinfo_WP_License::is_valid()) { |
| 5 |
phpinfowp_render_feature_lock([ |
| 6 |
'feature' => 'Permissions Audit', |
| 7 |
'icon' => 'dashicons-shield', |
| 8 |
'tagline' => 'Scan critical files and directories for insecure permissions that could allow unauthorised access.', |
| 9 |
'previews' => [ |
| 10 |
'wp-config.php: <strong>—</strong>', |
| 11 |
'uploads/: <strong>—</strong>', |
| 12 |
'.htaccess: <strong>—</strong>', |
| 13 |
], |
| 14 |
]); |
| 15 |
return; |
| 16 |
} |
| 17 |
|
| 18 |
$scan_results = Phpinfo_WP_Permissions::scan(); |
| 19 |
if (empty($scan_results)) return; |
| 20 |
|
| 21 |
$wp_config = $scan_results['wp_config']; |
| 22 |
$dangerous = $scan_results['dangerous']; |
| 23 |
$mismatch = $scan_results['mismatch']; |
| 24 |
$scanned = $scan_results['scanned']; |
| 25 |
$php_user = $scan_results['php_user']; |
| 26 |
$php_uid = $scan_results['php_uid']; |
| 27 |
|
| 28 |
$has_issues = !empty($dangerous) || !empty($mismatch) || ($wp_config && $wp_config['is_dangerous']); |
| 29 |
?> |
| 30 |
|
| 31 |
<div class="phpinfowp-pro-page"> |
| 32 |
<div class="phpinfowp-page-header"> |
| 33 |
<div> |
| 34 |
<h1>Permissions & Ownership Auditor <span class="phpinfowp-pro-badge"><?php _e('PRO', 'phpinfo-wp'); ?></span></h1> |
| 35 |
<p class="phpinfowp-page-subtitle"><?php _e('Deep scan of core files, plugins, and themes to detect security risks and auto-update failures.', 'phpinfo-wp'); ?></p> |
| 36 |
</div> |
| 37 |
</div> |
| 38 |
|
| 39 |
<!-- Overview Card --> |
| 40 |
<div style="background:#fff; border:1px solid #ccd0d4; padding:24px; border-radius:4px; display:flex; gap:32px; box-shadow:0 1px 1px rgba(0,0,0,0.04); margin-bottom:32px;"> |
| 41 |
<div> |
| 42 |
<div style="font-size:12px; color:#666; text-transform:uppercase; font-weight:600; letter-spacing:0.5px;"><?php _e('PHP Execution User', 'phpinfo-wp'); ?></div> |
| 43 |
<div style="font-size:24px; font-weight:700; margin-top:4px;"><code><?php echo esc_html($php_user); ?></code></div> |
| 44 |
<div style="font-size:12px; color:#888; margin-top:4px;">UID: <?php echo esc_html($php_uid); ?></div> |
| 45 |
</div> |
| 46 |
<div style="border-left:1px solid #eee; padding-left:32px;"> |
| 47 |
<div style="font-size:12px; color:#666; text-transform:uppercase; font-weight:600; letter-spacing:0.5px;"><?php _e('Files Scanned', 'phpinfo-wp'); ?></div> |
| 48 |
<div style="font-size:24px; font-weight:700; margin-top:4px;"><?php echo number_format($scanned); ?></div> |
| 49 |
<div style="font-size:12px; color:#888; margin-top:4px;"><?php _e('Capped at 5,000 for safety', 'phpinfo-wp'); ?></div> |
| 50 |
</div> |
| 51 |
<div style="border-left:1px solid #eee; padding-left:32px;"> |
| 52 |
<div style="font-size:12px; color:#666; text-transform:uppercase; font-weight:600; letter-spacing:0.5px;"><?php _e('Status', 'phpinfo-wp'); ?></div> |
| 53 |
<?php if ($has_issues): ?> |
| 54 |
<div style="font-size:24px; font-weight:700; margin-top:4px; color:#d63638;"><?php _e('Action Required', 'phpinfo-wp'); ?></div> |
| 55 |
<?php else: ?> |
| 56 |
<div style="font-size:24px; font-weight:700; margin-top:4px; color:#00a32a;"><?php _e('Secure', 'phpinfo-wp'); ?></div> |
| 57 |
<?php endif; ?> |
| 58 |
</div> |
| 59 |
</div> |
| 60 |
|
| 61 |
<?php if (!$has_issues): ?> |
| 62 |
<div style="background:#e8f5e9; border:1px solid #c8e6c9; padding:24px; border-radius:4px; display:flex; align-items:center; gap:16px;"> |
| 63 |
<span class="dashicons dashicons-shield-alt" style="color:#00a32a; font-size:40px; width:40px; height:40px;"></span> |
| 64 |
<div> |
| 65 |
<strong style="color:#1b5e20; font-size:16px;"><?php _e('Filesystem is Secure', 'phpinfo-wp'); ?></strong> |
| 66 |
<p style="margin:4px 0 0; color:#2e7d32; font-size:14px;"><?php _e('No dangerous 777 permissions were found, and file ownership matches the PHP process (meaning native plugin updates will work perfectly).', 'phpinfo-wp'); ?></p> |
| 67 |
</div> |
| 68 |
</div> |
| 69 |
<?php else: ?> |
| 70 |
|
| 71 |
<!-- wp-config.php Check --> |
| 72 |
<h2 class="phpinfowp-section-heading" style="display:flex; align-items:center; gap:8px;"> |
| 73 |
<span class="dashicons dashicons-admin-generic" style="color:#2271b1;"></span> Core Configuration |
| 74 |
</h2> |
| 75 |
<?php if ($wp_config): ?> |
| 76 |
<table class="wp-list-table widefat striped" style="border:1px solid #ccd0d4; box-shadow:0 1px 1px rgba(0,0,0,0.04); margin-bottom:32px;"> |
| 77 |
<thead><tr><th><?php _e('File', 'phpinfo-wp'); ?></th><th><?php _e('Permissions', 'phpinfo-wp'); ?></th><th><?php _e('Owner', 'phpinfo-wp'); ?></th><th><?php _e('Status', 'phpinfo-wp'); ?></th></tr></thead> |
| 78 |
<tbody> |
| 79 |
<tr> |
| 80 |
<td><code><?php echo esc_html($wp_config['path']); ?></code></td> |
| 81 |
<td><code style="font-weight:700; color:<?php echo $wp_config['is_dangerous'] ? '#d63638' : '#00a32a'; ?>"><?php echo esc_html($wp_config['perms']); ?></code></td> |
| 82 |
<td><?php echo esc_html($wp_config['owner']); ?></td> |
| 83 |
<td> |
| 84 |
<?php if ($wp_config['is_dangerous']): ?> |
| 85 |
<span style="color:#d63638; font-weight:600;"><span class="dashicons dashicons-warning" style="font-size:16px; margin-top:2px;"></span> CRITICAL RISK</span> |
| 86 |
<?php else: ?> |
| 87 |
<span style="color:#00a32a; font-weight:600;"><span class="dashicons dashicons-yes" style="font-size:16px; margin-top:2px;"></span> SECURE</span> |
| 88 |
<?php endif; ?> |
| 89 |
</td> |
| 90 |
</tr> |
| 91 |
</tbody> |
| 92 |
</table> |
| 93 |
<?php else: ?> |
| 94 |
<p><code>wp-config.php</code> could not be located.</p> |
| 95 |
<?php endif; ?> |
| 96 |
|
| 97 |
<!-- Dangerous Permissions List --> |
| 98 |
<?php if (!empty($dangerous)): ?> |
| 99 |
<h2 class="phpinfowp-section-heading" style="display:flex; align-items:center; gap:8px;"> |
| 100 |
<span class="dashicons dashicons-unlock" style="color:#d63638;"></span> Dangerous Permissions Found |
| 101 |
</h2> |
| 102 |
<p class="description" style="margin-bottom:12px;"><?php _e('These files or folders are world-writable (777 or 666). Any other user on the server can modify them.', 'phpinfo-wp'); ?></p> |
| 103 |
<div style="background:#fff; border:1px solid #ccd0d4; border-radius:4px; max-height:400px; overflow-y:auto; margin-bottom:32px;"> |
| 104 |
<table class="wp-list-table widefat striped" style="border:none; margin:0;"> |
| 105 |
<thead><tr><th><?php _e('Path', 'phpinfo-wp'); ?></th><th><?php _e('Type', 'phpinfo-wp'); ?></th><th><?php _e('Permissions', 'phpinfo-wp'); ?></th></tr></thead> |
| 106 |
<tbody> |
| 107 |
<?php foreach ($dangerous as $item): ?> |
| 108 |
<tr> |
| 109 |
<td><code><?php echo esc_html(str_replace(ABSPATH, '', $item['path'])); ?></code></td> |
| 110 |
<td><?php echo $item['type'] === 'dir' ? 'Directory' : 'File'; ?></td> |
| 111 |
<td><code style="color:#d63638; font-weight:700;"><?php echo esc_html($item['perms']); ?></code></td> |
| 112 |
</tr> |
| 113 |
<?php endforeach; ?> |
| 114 |
</tbody> |
| 115 |
</table> |
| 116 |
</div> |
| 117 |
<?php endif; ?> |
| 118 |
|
| 119 |
<!-- Ownership Mismatches List --> |
| 120 |
<?php if (!empty($mismatch)): ?> |
| 121 |
<h2 class="phpinfowp-section-heading" style="display:flex; align-items:center; gap:8px;"> |
| 122 |
<span class="dashicons dashicons-admin-users" style="color:#dba617;"></span> Ownership Mismatches |
| 123 |
</h2> |
| 124 |
<p class="description" style="margin-bottom:12px;">These files are owned by a different user than the PHP process (<code><?php echo esc_html($php_user); ?></code>). This usually causes WordPress to ask for FTP credentials when installing plugins.</p> |
| 125 |
<div style="background:#fff; border:1px solid #ccd0d4; border-radius:4px; max-height:400px; overflow-y:auto; margin-bottom:32px;"> |
| 126 |
<table class="wp-list-table widefat striped" style="border:none; margin:0;"> |
| 127 |
<thead><tr><th><?php _e('Path', 'phpinfo-wp'); ?></th><th><?php _e('Current Owner', 'phpinfo-wp'); ?></th><th><?php _e('Required Owner', 'phpinfo-wp'); ?></th></tr></thead> |
| 128 |
<tbody> |
| 129 |
<?php foreach ($mismatch as $item): ?> |
| 130 |
<tr> |
| 131 |
<td><code><?php echo esc_html(str_replace(ABSPATH, '', $item['path'])); ?></code></td> |
| 132 |
<td><code style="color:#dba617;"><?php echo esc_html($item['owner']); ?></code></td> |
| 133 |
<td><code style="color:#00a32a;"><?php echo esc_html($php_user); ?></code></td> |
| 134 |
</tr> |
| 135 |
<?php endforeach; ?> |
| 136 |
</tbody> |
| 137 |
</table> |
| 138 |
<?php if (count($mismatch) >= 20): ?> |
| 139 |
<div style="padding:12px 16px; background:#f9f9f9; border-top:1px solid #ddd; font-size:12px; color:#666;"> |
| 140 |
<em><?php _e('Showing first 20 examples only. Fixing the root folder recursively will solve the rest.', 'phpinfo-wp'); ?></em> |
| 141 |
</div> |
| 142 |
<?php endif; ?> |
| 143 |
</div> |
| 144 |
<?php endif; ?> |
| 145 |
|
| 146 |
<!-- Fix Instructions --> |
| 147 |
<h2 class="phpinfowp-section-heading" style="margin-top:40px; display:flex; align-items:center; gap:8px;"> |
| 148 |
<span class="dashicons dashicons-editor-code" style="color:#2271b1;"></span> How to Fix (SSH Commands) |
| 149 |
</h2> |
| 150 |
<p class="description" style="margin-bottom:16px; max-width:800px;"><?php _e('Log into your server via SSH. Copy and paste the following bash commands to automatically set the correct, secure ownership and permissions for your entire WordPress installation.', 'phpinfo-wp'); ?></p> |
| 151 |
|
| 152 |
<div style="background:#1e1e1e; padding:20px; border-radius:6px; font-family:monospace; font-size:13px; line-height:1.6; color:#d4d4d4; overflow-x:auto;"> |
| 153 |
<div style="color:#6a9955; margin-bottom:8px;"># 1. Fix Ownership (Allow native WP updates)</div> |
| 154 |
<div><span style="color:#569cd6;"><?php _e('chown', 'phpinfo-wp'); ?></span> -R <?php echo esc_html($php_user . ':' . $php_user); ?> <?php echo esc_html(ABSPATH); ?></div> |
| 155 |
|
| 156 |
<div style="color:#6a9955; margin-top:16px; margin-bottom:8px;"># 2. Fix Directory Permissions (755)</div> |
| 157 |
<div><span style="color:#569cd6;"><?php _e('find', 'phpinfo-wp'); ?></span> <?php echo esc_html(ABSPATH); ?> -type d -exec <span style="color:#569cd6;"><?php _e('chmod', 'phpinfo-wp'); ?></span> 755 {} \;</div> |
| 158 |
|
| 159 |
<div style="color:#6a9955; margin-top:16px; margin-bottom:8px;"># 3. Fix File Permissions (644)</div> |
| 160 |
<div><span style="color:#569cd6;"><?php _e('find', 'phpinfo-wp'); ?></span> <?php echo esc_html(ABSPATH); ?> -type f -exec <span style="color:#569cd6;"><?php _e('chmod', 'phpinfo-wp'); ?></span> 644 {} \;</div> |
| 161 |
|
| 162 |
<?php if ($wp_config): ?> |
| 163 |
<div style="color:#6a9955; margin-top:16px; margin-bottom:8px;"># 4. Lock down wp-config.php (600)</div> |
| 164 |
<div><span style="color:#569cd6;"><?php _e('chmod', 'phpinfo-wp'); ?></span> 600 <?php echo esc_html($wp_config['path']); ?></div> |
| 165 |
<?php endif; ?> |
| 166 |
</div> |
| 167 |
<?php endif; ?> |
| 168 |
</div> |
| 169 |
|