IP Risk Normalizer
Normalizes IP data and assigns risk signals without blindly trusting proxy headers.
Function signature
ogNormalizeClientIpRisk(server_data = array(), trusted_proxies = array())
Categories
- Security
Parameters
server_dataServer header data, normally copied from server environment data by caller. Recognized keys: `HTTP_X_FORWARDED_FOR`, `REMOTE_ADDR`.trusted_proxiesApproved proxy IP addresses.Return value
Short public-safe status message.
- client_ip
- remote_addr
- source
- risk_score
- risk_flags
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Normalizes IP data and assigns risk signals without blindly trusting proxy headers.
*
* Primary use case: Security logs, rate limits, admin alerts.
* Typical inputs: server headers, trusted proxy config.
* Typical output: IP and risk metadata.
*
* Implementation note: Only trust forwarded headers from known proxies.
*
* @param array $server_data Server header data, normally copied from $_SERVER by caller.
* @param array $trusted_proxies Approved proxy IP addresses.
* @return array Structured result data with success, message, and data keys.
*/
function ogNormalizeClientIpRisk($server_data = array(), $trusted_proxies = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($server_data)) {
$server_data = array();
}
if (!is_array($trusted_proxies)) {
$trusted_proxies = array();
}
$remote_addr = '';
if (!empty($server_data['REMOTE_ADDR'])) {
$remote_addr = trim((string)$server_data['REMOTE_ADDR']);
}
$client_ip = $remote_addr;
$source = 'remote_addr';
$trusted_proxy_used = false;
if (!empty($remote_addr) && in_array($remote_addr, $trusted_proxies, true)) {
if (!empty($server_data['HTTP_X_FORWARDED_FOR'])) {
$forwarded_parts = explode(',', (string)$server_data['HTTP_X_FORWARDED_FOR']);
$forwarded_ip = trim($forwarded_parts[0]);
if (filter_var($forwarded_ip, FILTER_VALIDATE_IP)) {
$client_ip = $forwarded_ip;
$source = 'trusted_x_forwarded_for';
$trusted_proxy_used = true;
}
}
}
if (empty($client_ip) || filter_var($client_ip, FILTER_VALIDATE_IP) === false) {
$result['message'] = 'Client IP could not be validated.';
return $result;
}
$risk_score = 0;
$risk_flags = array();
if (filter_var($client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
$risk_score += 20;
$risk_flags[] = 'private_or_reserved_ip';
}
if (!$trusted_proxy_used && !empty($server_data['HTTP_X_FORWARDED_FOR'])) {
$risk_score += 10;
$risk_flags[] = 'untrusted_forwarded_header_present';
}
$result['success'] = true;
$result['message'] = 'Client IP risk normalized.';
$result['data'] = array(
'client_ip' => $client_ip,
'remote_addr' => $remote_addr,
'source' => $source,
'risk_score' => $risk_score,
'risk_flags' => $risk_flags
);
return $result;
}