Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

For a request that reaches your WordPress server directly, read and validate $_SERVER['REMOTE_ADDR']. If the site is behind a CDN, reverse proxy, or load balancer, that value may be the intermediary’s address instead of the visitor’s. In that architecture, configure the proxy to write the original client address, trust only that proxy’s documented header and source addresses, and never treat an unchecked forwarded value as proof of identity.

The practical choice depends on three things: your traffic path, what you need the address for, and how much personal data you should retain. The steps below cover a small display widget, comments, analytics, rate limits and bans, and privacy-compliant storage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What WordPress actually receives

Every HTTP request arrives at a web server through a network path. With a direct connection, the server’s REMOTE_ADDR variable is the visitor’s network address. With a reverse proxy, the connection that reaches your origin is made by the proxy, so REMOTE_ADDR can contain the proxy’s address. The proxy may add a header containing the original address, but that header is useful only when the proxy is trusted and rewrites it correctly.

An IP address identifies a network endpoint, not necessarily a person. Shared Wi-Fi, mobile carrier NAT, corporate gateways and household routers can make many people appear under one address. A single person can also change addresses. Use the value as a technical signal, not as a guaranteed identity.

Read and validate the address on a direct connection

Use this minimal PHP when the web server receives visitors directly and no intermediary changes the request:

<?php
$ip = filter_var($_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP);

if ($ip === false) {
    $ip = null;
}

if ($ip !== null) {
    echo esc_html($ip);
}

FILTER_VALIDATE_IP accepts valid IPv4 and IPv6 syntax and rejects an empty or malformed value. The null-coalescing operator prevents a notice when the server variable is absent. When displaying the result in WordPress HTML, escape it with esc_html(); when placing it in an HTML attribute, use the appropriate attribute-escaping function instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not replace REMOTE_ADDR with the first value found in every possible request header. Headers beginning with HTTP_ are supplied by the request and can be forged by a client unless a trusted intermediary has overwritten them.

Display a visitor IP in a shortcode

A shortcode keeps the output in a template or page while limiting the code to a deliberate location. Add the following to a small site-specific plugin or a child theme’s functionality file:

function site_visitor_ip_shortcode() {
    $ip = filter_var($_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP);

    if ($ip === false) {
        return '';
    }

    return esc_html($ip);
}
add_shortcode('visitor_ip', 'site_visitor_ip_shortcode');

Place [visitor_ip] in a post or page. This example assumes a direct origin connection. If a proxy sits in front of the site, it will show the proxy unless you first implement the trusted-proxy pattern described below.

Why a CDN or reverse proxy shows its own IP

A CDN, web application firewall, hosting load balancer or reverse proxy terminates the visitor’s connection and opens a second connection to WordPress. From PHP’s point of view, the second connection is the request source. That is why a diagnostic page can show the same address for many unrelated visitors.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Proxies commonly forward the original address in a provider-specific header such as X-Real-IP or X-Forwarded-For. The exact header and the trusted proxy ranges differ by provider and configuration. Treat the provider’s current documentation as authoritative rather than assuming one header works everywhere.

Configure a trusted-proxy design

Use this sequence before changing WordPress code:

  1. Map the path. Identify every intermediary between the visitor and the origin: CDN, firewall, ingress controller, load balancer and web server. Determine which component writes the client-IP header.
  2. Make the proxy authoritative. Configure it to remove any client-supplied copy of the chosen header and write its own value. If an attacker can send an arbitrary header through unchanged, WordPress cannot distinguish it from a genuine proxy value.
  3. Restrict by source. Where the infrastructure supports it, accept the header only on requests arriving from the proxy’s documented IP ranges. Also prevent public users from reaching the origin directly when the architecture requires all traffic to pass through the proxy.
  4. Choose one canonical header. Do not scan a long list and use whichever value appears first. Pick the header your proxy guarantees and document that choice for future maintenance.
  5. Parse and validate. Validate the selected address as IPv4 or IPv6. If the provider sends a chain, use its documented trusted-proxy algorithm rather than blindly taking the left-most or right-most item.
  6. Test both paths. Send a request through the real public hostname and inspect the result. If the origin is reachable separately, test that route too; an origin request should not be able to impersonate a proxy request.

Understanding an X-Forwarded-For chain

An X-Forwarded-For value can look like client1, proxy1, proxy2. The entries represent successive hops, but the meaning of each position depends on which proxies you trust. In a correctly controlled chain, the original client is often the left-most address. Because a client can submit its own header, that convention is not safe by itself. Start at the server-side connection address, walk through only the proxy addresses you explicitly trust, and select the remaining client address according to your provider’s documented procedure.

Never use an unchecked forwarded value for authentication, account recovery, payment controls, administrator access, bans or other high-impact security decisions. A forged header could make an attacker appear to come from an allowed or unbanned address.

WordPress’s built-in helper: useful, but explicitly unsafe

WordPress includes WP_Community_Events::get_unsafe_client_ip(). It checks several possible sources in sequence—HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_CLUSTER_CLIENT_IP, HTTP_FORWARDED_FOR, HTTP_FORWARDED, and finally REMOTE_ADDR—then passes the result to wp_privacy_anonymize_ip().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The method name and documentation are deliberate: the value is not guaranteed to be accurate or authentic. It is a convenience for approximate location or non-security features, not a proof of who made a request. Its broad header scan is especially unsuitable when your site has a strict trust boundary.

If you use the helper, keep its output away from authorization logic, and still validate and escape it before displaying or storing it. For a security-sensitive application, implement a narrow, infrastructure-specific resolver instead.

Changing the address saved with comments

WordPress stores a commenter’s address and exposes the pre_comment_user_ip filter before that value is saved. A controlled proxy integration can use this filter to substitute the validated client address. The filter does not make an untrusted header safe; it only gives your code a place to apply a trust decision.

function site_comment_ip($ip) {
    // Return a value only after your proxy-source and header checks.
    $candidate = filter_var($ip, FILTER_VALIDATE_IP);
    return $candidate === false ? '' : $candidate;
}
add_filter('pre_comment_user_ip', 'site_comment_ip');

For a forwarded chain, do not simply split the string and select an element unless your proxy documentation defines that algorithm and your code has verified the request came from a trusted proxy. WordPress warns that X-Forwarded-For is easy to forge.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a plugin is the better implementation

A maintained plugin can be preferable when you need an admin setting, a shortcode, comments integration, privacy controls and updates without maintaining custom PHP. Evaluate the implementation rather than assuming that a plugin automatically understands your network.

The official directory entry for the Show Visitor IP plugin records safeguards that are useful comparison points:

  • IP syntax validation and escaped output.
  • Explicit opt-in for proxy headers.
  • Use of only the first X-Forwarded-For entry in its documented behavior.
  • Cached geolocation lookups instead of a new request for every page view.
  • A three-second geolocation API timeout.
  • Error handling when the lookup service fails.

Those features reduce common coding mistakes, but they do not establish that your proxy header is authentic. Before enabling proxy support, confirm the plugin’s selected header, trusted-source settings and chain handling match your actual network. The directory currently lists version 5.3 and an update about one month before the directory was checked; plugin versions and update dates can change, so verify them in your dashboard.

Choose an implementation by purpose

Purpose Recommended approach What to avoid
Show an address to the visitor Validated REMOTE_ADDR for direct traffic, or a provider-specific trusted header behind a proxy Printing raw request headers
Approximate country or region Validated address followed by a reputable geolocation service, with caching and a short timeout Calling a geolocation API on every request without failure handling
Comment moderation records Store the address only after the proxy trust model is verified; consider anonymization Assuming the first forwarded value is genuine
Rate limiting Use a rate limiter at the proxy or application layer and treat IP as one signal among several Permanent decisions based on a single address
Authentication or access control Use user credentials, signed tokens and server-side authorization Trusting any client-provided IP header

Anonymize or minimize what you retain

If exact addressing is unnecessary, avoid storing the full value. WordPress’s wp_privacy_anonymize_ip() helper demonstrates anonymization by reducing identifying precision. Apply anonymization before persistence when your use case permits it, not only when rendering a page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$ip = filter_var($_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP);

if ($ip !== false) {
    $anonymous_ip = wp_privacy_anonymize_ip($ip);
} else {
    $anonymous_ip = null;
}

Decide whether you need IPv4 and IPv6 support, whether a short-lived security log is enough, and whether a hash or truncated representation meets the requirement. A hash of an IP can remain linkable, especially if the input space is small, so it is not automatically anonymous.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Privacy, disclosure and retention

WordPress privacy guidance lists an IP address among data that can identify a user. Your obligations depend on the visitor’s jurisdiction, your organization, the purpose of processing and any third parties that receive the data. Update the privacy notice to explain:

  • That IP addresses are collected and the specific purpose, such as abuse prevention, diagnostics or comment moderation.
  • Which systems or service providers can access the value, including a geolocation provider or security platform.
  • How long raw and anonymized values are retained.
  • Who can view the records and how access is restricted.
  • How visitors can request applicable access or deletion rights.

Some processing purposes or jurisdictions may require active consent. Do not retain a full address indefinitely merely because WordPress can collect it. Set an automatic deletion period for logs and comment metadata, and review backups because deleting the live record may not remove every copied version.

Troubleshooting: the value is wrong

Every visitor has the same address

This usually means the origin sees a CDN, load balancer or reverse proxy. Confirm the forwarding header written by that component, then restrict trust to its source ranges. If the origin is publicly reachable, close that path or ensure it cannot set the trusted header.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The address changes when you enable proxy support

Check whether multiple intermediaries add entries to a chain. Verify which hops you control and apply the provider’s algorithm. A change can also indicate that the plugin or application is reading a different header than the one your proxy writes.

A user can bypass an IP ban

Assume the header is forgeable until proven otherwise. Move the ban decision to the trusted proxy, enforce source-address restrictions, and make the application reject forwarded headers received from untrusted clients. Combine IP signals with accounts, rate limits, cookies or other controls; an address is not a durable identity.

The value is empty or invalid

Log the network path and the names of configured variables in a protected diagnostic environment, not in a public page. Check for IPv6 support, web-server forwarding rules and code that assumes an IPv4 dotted-quad. Return a safe null value when validation fails.

Geolocation is slow or unavailable

Cache successful lookups, impose a timeout and handle errors without blocking page generation. Geolocation is approximate and should not be used as authentication. If the service is unavailable, retain the validated address only if your stated purpose and retention policy allow it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Security checklist before going live

  • Know whether traffic reaches the origin directly or through one or more intermediaries.
  • Use REMOTE_ADDR only as the direct-connection source.
  • Document one canonical client-IP header for your proxy.
  • Strip client-supplied copies and rewrite the header at the trusted proxy.
  • Restrict acceptance to documented proxy source addresses.
  • Validate IPv4 and IPv6 syntax.
  • Escape every value rendered in HTML, JavaScript or an attribute.
  • Never use an unchecked value for authentication, bans or other high-stakes decisions.
  • Anonymize or truncate when full precision is not necessary.
  • Publish purpose, sharing, access and retention details in the privacy notice.
  • Test public-proxy and direct-origin paths, including failure cases.

Bottom line

Start with a validated REMOTE_ADDR on a direct WordPress connection. Behind a proxy, the real solution is not a different PHP variable; it is a verified trust relationship between your infrastructure and the header it writes. Keep that value out of identity decisions, minimize what you store, and align collection with your privacy obligations.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.