Skip to content
← Back to Snippets
Code

IP Risk Normalization Workflow

Normalizes an inbound IP address into a safe risk-review structure without trusting spoofable forwarding headers by default.

Purpose

Normalizes an inbound IP address into a safe risk-review structure without trusting spoofable forwarding headers by default.

Snippet details

ContextSecurityLevelAdvancedCopy-and-paste statusMarked safe after review.

Categories

  • Security

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.
 */

/**
 * IP Risk Normalization Workflow.
 *
 * Purpose:
 * Converts request address data into a normalized review packet for login,
 * admin, and abuse-control decisions.
 *
 * @param array $server_input $_SERVER-style request data.
 * @param array $trusted_proxy_addresses Proxy IPs whose forwarding headers may be considered.
 * @return array Normalized IP review data.
 */
function ogSnippetIpRiskNormalizationWorkflow(array $server_input, array $trusted_proxy_addresses): array {
	$remote_address = '';
	$forwarded_address = '';
	$selected_address = '';
	$risk_flags = array();

	if (isset($server_input['REMOTE_ADDR']) === true) {
		$remote_address = trim((string) $server_input['REMOTE_ADDR']);
	}

	if (isset($server_input['HTTP_X_FORWARDED_FOR']) === true) {
		$forwarded_parts = explode(',', (string) $server_input['HTTP_X_FORWARDED_FOR']);
		$forwarded_address = trim((string) $forwarded_parts[0]);
	}

	$remote_is_valid = filter_var($remote_address, FILTER_VALIDATE_IP);
	$forwarded_is_valid = filter_var($forwarded_address, FILTER_VALIDATE_IP);

	if ($remote_is_valid === false) {
		$risk_flags[] = 'remote_address_invalid';
	} else {
		$selected_address = $remote_address;
	}

	if ($forwarded_address !== '' && $forwarded_is_valid === false) {
		$risk_flags[] = 'forwarded_address_invalid';
	}

	if ($remote_is_valid !== false && in_array($remote_address, $trusted_proxy_addresses, true) === true && $forwarded_is_valid !== false) {
		$selected_address = $forwarded_address;
		$risk_flags[] = 'trusted_proxy_forwarded_address_used';
	} elseif ($forwarded_address !== '') {
		$risk_flags[] = 'forwarded_address_ignored';
	}

	$is_public = false;

	if ($selected_address !== '') {
		$public_check = filter_var($selected_address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);

		if ($public_check !== false) {
			$is_public = true;
		}
	}

	if ($selected_address === '') {
		$risk_flags[] = 'no_usable_address';
	}

	if ($is_public === false && $selected_address !== '') {
		$risk_flags[] = 'non_public_address';
	}

	return array(
		'address' => $selected_address,
		'is_public' => $is_public,
		'flags' => $risk_flags,
		'hash' => hash('sha256', $selected_address)
	);
}

$firefly_server = array(
	'REMOTE_ADDR' => '203.0.113.77',
	'HTTP_X_FORWARDED_FOR' => '10.9.8.7'
);
$ip_review = ogSnippetIpRiskNormalizationWorkflow($firefly_server, array('198.51.100.10'));

echo 'Firefly IP review flags: '.implode(', ', $ip_review['flags']);