fix: full IPs, top attacked form banner, Bearer token auth on /submit
server.js: - Remove maskIP() — store full IPs as submitted (sanitizeIP trims/truncates only) - Add requireToken() middleware with constant-time comparison (timingSafeEqual) using 128-byte padded buffers to prevent length-based timing leaks - API_TOKEN env var — if unset the endpoint stays open (dev mode); set it in prod - /api/v1/submit now requires Authorization: Bearer <token> docker-compose.yml / .env.example: - Expose API_TOKEN env var with clear comment index.html: - Add red-bordered 'MOST ATTACKED FORM (30D)' banner between stats and content grid showing form name, hit count, and % of all 30d blocks - Widen live feed IP column 90px → 130px to fit full IPv4 addresses - Remove 'ALL DATA IS ANONYMISED' from footer (IPs are full now) honeypot-fields.php: - SmartHoneypotAPIClient: add api_token to defaults + send Authorization header - save_api_settings: persist api_token field - Settings tab: add password input for API token with description
This commit is contained in:
@@ -162,6 +162,7 @@ class SmartHoneypotAPIClient {
|
||||
return [
|
||||
'enabled' => false,
|
||||
'api_url' => '',
|
||||
'api_token' => '',
|
||||
'last_sync' => 0,
|
||||
'sent_total' => 0,
|
||||
];
|
||||
@@ -199,12 +200,17 @@ class SmartHoneypotAPIClient {
|
||||
$batch = array_splice($queue, 0, self::BATCH_SIZE);
|
||||
$site_hash = hash('sha256', home_url());
|
||||
|
||||
$headers = ['Content-Type' => 'application/json'];
|
||||
if (!empty($s['api_token'])) {
|
||||
$headers['Authorization'] = 'Bearer ' . $s['api_token'];
|
||||
}
|
||||
|
||||
$response = wp_remote_post(
|
||||
trailingslashit(esc_url_raw($s['api_url'])) . 'api/v1/submit',
|
||||
[
|
||||
'timeout' => 15,
|
||||
'blocking' => true,
|
||||
'headers' => ['Content-Type' => 'application/json'],
|
||||
'headers' => $headers,
|
||||
'body' => wp_json_encode([
|
||||
'site_hash' => $site_hash,
|
||||
'blocks' => $batch,
|
||||
@@ -308,7 +314,8 @@ class SmartHoneypotAdmin {
|
||||
$current = SmartHoneypotAPIClient::settings();
|
||||
$new = [
|
||||
'enabled' => !empty($_POST['hp_api_enabled']),
|
||||
'api_url' => esc_url_raw(trim($_POST['hp_api_url'] ?? '')),
|
||||
'api_url' => esc_url_raw(trim($_POST['hp_api_url'] ?? '')),
|
||||
'api_token' => sanitize_text_field($_POST['hp_api_token'] ?? ''),
|
||||
'last_sync' => $current['last_sync'],
|
||||
'sent_total' => $current['sent_total'],
|
||||
];
|
||||
@@ -508,6 +515,17 @@ class SmartHoneypotAdmin {
|
||||
<p class="description">Base URL of your Honeypot API Docker container.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>API Token</th>
|
||||
<td>
|
||||
<input type="password" name="hp_api_token" value="<?= esc_attr($s['api_token']) ?>"
|
||||
class="regular-text" placeholder="Bearer token (matches API_TOKEN in docker-compose)">
|
||||
<p class="description">
|
||||
Must match the <code>API_TOKEN</code> set in your Docker container's environment.
|
||||
Leave empty only if the API is running without a token (not recommended).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php submit_button('Save Settings'); ?>
|
||||
|
||||
Reference in New Issue
Block a user