<?php
/**
* Plugin Name: RDAP POST-only Intake
* Description: Accepts RDAP lookups only via POST to /rdap/, stores server-side, then redirects back to /rdap/ with a clean URL.
*/
if (!defined('ABSPATH')) exit;
/**
* Helpers
*/
function rdap_is_valid_domain($domain) {
$domain = trim(strtolower(wp_unslash($domain)));
if (function_exists('idn_to_ascii')) {
$ascii = @idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
if ($ascii !== false) $domain = $ascii;
}
return (bool) filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
}
function rdap_set_cookie($name, $value, $seconds = 300) {
$secure = is_ssl();
setcookie($name, $value, [
'expires' => time() + $seconds,
'path' => '/',
'secure' => $secure,
'httponly' => true,
'samesite' => 'Lax',
]);
}
/**
* Block leaking via query string or extra path on /rdap/
* - Strip any query params by redirecting to /rdap/
* - Let WP naturally 404 /rdap/<anything> (no child pages)
*/
add_action('template_redirect', function () {
if (!is_page('rdap')) return;
// If someone tries GET with any params, strip them.
if ($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET)) {
wp_redirect(home_url('/rdap/'), 301);
exit;
}
// POST intake: accept only from our form
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Basic CSRF check
if (!isset($_POST['rdap_nonce']) || !wp_verify_nonce($_POST['rdap_nonce'], 'rdap_intake')) {
wp_die(esc_html__('Security check failed.', 'rdap'), 400);
}
$incoming = isset($_POST['rdap']) ? sanitize_text_field(wp_unslash($_POST['rdap'])) : '';
if (!$incoming || !rdap_is_valid_domain($incoming)) {
wp_die(esc_html__('Invalid domain.', 'rdap'), 400);
}
// Rate-limit (simple): 10 requests per 5 minutes per IP
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$rl_key = 'rdap_rl_' . md5($ip);
$count = (int) get_transient($rl_key);
if ($count > 50) {
wp_die(esc_html__('Too many requests. Please try again later.', 'rdap'), 429);
}
set_transient($rl_key, $count + 1, 5 * MINUTE_IN_SECONDS);
// Store server-side only (5 minutes)
$token = wp_generate_uuid4();
set_transient('rdap_' . $token, $incoming, 5 * MINUTE_IN_SECONDS);
rdap_set_cookie('rdap_token', $token, 5 * MINUTE_IN_SECONDS);
// Redirect back to pristine /rdap/ (no data in URL/history)
wp_redirect(home_url('/rdap/'), 303);
exit;
}
}, 0);
/**
* Public helper for the /rdap/ page template to read (and optionally consume) the stored value.
*/
function rdap_get_and_forget_value() {
if (empty($_COOKIE['rdap_token'])) return null;
$token = sanitize_text_field(wp_unslash($_COOKIE['rdap_token']));
if (!$token) return null;
$key = 'rdap_' . $token;
$val = get_transient($key);
if ($val !== false) {
delete_transient($key); // one-shot read to minimize exposure
return $val;
}
return null;
}