For a visitor connecting directly to your web server, read and validate $_SERVER['REMOTE_ADDR']. If your site sits behind a CDN, reverse proxy, or load balancer, that value may be the proxy’s address instead. In that architecture, configure the proxy to write the original client address, trust only the specific header and proxy sources you control, and never treat an unchecked forwarded value as proof of identity.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What WordPress can—and cannot—tell you
An IP address identifies a network endpoint, not a person. It can still be useful for approximate geolocation, diagnostics, rate limiting, abuse investigation, comment moderation, and access logs. The correct value depends on how the request reaches WordPress.
As an Amazon Associate I earn from qualifying purchases.
| Site topology | What REMOTE_ADDR usually contains |
Safe starting point |
|---|---|---|
| Visitor connects directly to the origin web server | The visitor’s source address, subject to normal network behavior | Read and validate $_SERVER['REMOTE_ADDR'] |
| CDN, reverse proxy, or load balancer in front of the origin | Often the proxy or load balancer address | Use the provider’s documented client-IP header only after establishing a strict trust boundary |
| Origin is reachable both through the proxy and directly | Different values can appear on each path | Test both paths and restrict or block direct origin access when the design requires proxy-only traffic |
WordPress documents that $_SERVER['REMOTE_ADDR'] cannot be relied on in every situation, including requests made through a proxy or a web server that is itself behind a proxy. A forwarded address is meaningful only when a trusted component inserted it and your application knows which part of the forwarding chain to use.
Read and validate the address on a direct connection
For an unproxied request, this is the smallest appropriate implementation:
#1 Best Overall
<?php
$ip = filter_var($_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP);
if ($ip === false) {
$ip = null;
}
FILTER_VALIDATE_IP accepts valid IPv4 and IPv6 syntax and returns false for an invalid value. Keeping an invalid result as null gives later code an explicit “unknown” state instead of accidentally logging or displaying an untrusted string.
Escape it when displaying it
Even a syntactically valid address should be escaped for its output context. For HTML output:
<?php if ($ip !== null): ?>
<p>Your IP address is <?php echo esc_html($ip); ?></p>
<?php else: ?>
<p>Your IP address could not be determined.</p>
<?php endif; ?>
Do not print a raw server variable, and do not assume that validation alone makes a value safe in every output context.
Where to put the code
Use a small, maintained site-specific plugin or a child theme rather than editing WordPress core. If the value is needed in a template, compute it in a suitable PHP callback and pass the validated result to the template. Avoid collecting an address on every request when the feature does not need it; unnecessary collection increases privacy and retention obligations.
Why a proxy or CDN shows its own IP
A reverse proxy accepts the visitor’s connection and opens a separate connection to your origin. From the origin server’s point of view, the immediate peer is the proxy, so REMOTE_ADDR can legitimately be the proxy’s address. The original client address must be carried in a request header that the proxy creates or rewrites.
Rank #2
Common header names include X-Real-IP and X-Forwarded-For, but the correct header is provider-specific. WordPress’s HTTPS documentation shows these headers being forwarded through a reverse proxy; it does not make every such header trustworthy by default.
Recommended Free Tools
Configure the proxy before changing WordPress
- Identify the actual intermediary. Determine whether traffic passes through a CDN, web-application firewall, ingress controller, cloud load balancer, or another reverse proxy. Use that service’s current documentation to find its canonical client-IP header and published source-address ranges.
- Make the intermediary overwrite the header. It should remove a client-supplied copy and write the value it obtained from the incoming connection. Appending blindly to an attacker-controlled header creates an ambiguous chain.
- Limit origin access. Where the architecture requires proxy-only traffic, firewall the origin so visitors cannot bypass the proxy and send requests directly.
- Record the trust boundary. Document which proxy addresses are trusted, which header is accepted, and how a chain is parsed. This is an operational security setting, not merely a PHP preference.
Handling X-Forwarded-For safely
X-Forwarded-For is normally a comma-separated list such as client1, proxy1, proxy2. The left-most value may represent the original client, but that interpretation is safe only when every relevant proxy rewrites the chain correctly and your application applies the provider’s documented trusted-proxy algorithm.
Never replace REMOTE_ADDR with “the first value in any X-Forwarded-For header” for all requests. A visitor can send that header directly unless your trusted proxy strips it. An attacker could then select an address that bypasses an IP block or appears in an audit trail.
A practical trust decision
- If the request did not arrive from a documented trusted proxy range, ignore forwarded headers and use the validated connection address.
- If it did arrive from a trusted proxy, read only the header that proxy documents and parse the chain according to its rules.
- Validate the selected address as IPv4 or IPv6 before storing, displaying, or comparing it.
- Treat a missing, malformed, or contradictory header as an unknown client address, not as permission to guess.
WordPress’s restricted-access guidance recommends selecting trusted proxy IP ranges and explicitly configured trusted headers. That model is safer than globally trusting every request that happens to contain a client-IP header.
Using WordPress’s built-in helpers
WP_Community_Events::get_unsafe_client_ip()
WordPress core includes WP_Community_Events::get_unsafe_client_ip(), which checks several server variables—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 calls wp_privacy_anonymize_ip().
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #3
The method name and documentation are important: the result is explicitly “unsafe.” REMOTE_ADDR may be a proxy, and the other headers can be forged. Use this helper for approximate location or other low-consequence purposes where an inexact address is acceptable. Do not use it as proof of identity, as the basis for authentication, or as the sole input to a high-impact security decision.
Comment IPs and pre_comment_user_ip
When WordPress stores a comment, the pre_comment_user_ip filter can change the address before it is saved. This is useful when your infrastructure has a verified forwarding design, but it also creates a responsibility to preserve the trust model. The official hook documentation uses the chain X-Forwarded-For: client1, proxy1, proxy2 as an example and warns that the header is easy to forge.
If you alter comment IP storage, make the filter conditional on requests arriving from your known proxy ranges, use the proxy’s documented parsing rule, validate the selected result, and consider anonymizing it before persistence.
Custom code or a plugin?
| Approach | Best fit | Advantages | Risks and maintenance |
|---|---|---|---|
Validated REMOTE_ADDR in custom PHP |
Direct-origin sites and simple diagnostics | Small code footprint and clear behavior | Wrong for proxy topologies unless the network path is verified; you must handle escaping and privacy yourself |
| Proxy-aware custom integration | Sites with a documented, controlled CDN or load balancer | Can enforce your exact trusted ranges, header, and parsing algorithm | Requires infrastructure knowledge and updates when the provider changes its ranges or headers |
| Maintained visitor-IP plugin | Administrators who need an interface, display controls, or geolocation features | May provide validation, escaped output, optional proxy-header handling, caching, timeouts, and error handling | A plugin cannot establish a trustworthy proxy path for you; review its settings and source, and keep it updated |
The WordPress.org directory entry for the Show Visitor IP plugin lists safeguards that are useful when evaluating any plugin: IP validation, escaped output, opt-in proxy-header support, use of only the first X-Forwarded-For entry, cached geolocation requests, a three-second API timeout, and error handling. Those features are comparison points, not a substitute for configuring and testing your own proxy trust boundary. The directory records version 5.3 and an update one month before its listing was crawled; plugin versions and update dates can change.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Testing the value you receive
Test the complete request path rather than testing only from a browser at the origin.
Rank #4
- Direct-origin test: if the origin is intentionally reachable, request it directly and record the connection address and relevant headers. Confirm that untrusted forwarded headers are ignored.
- Proxied test: request the public hostname through the real CDN or reverse proxy. Confirm that the selected value matches the address the proxy documents as the client address.
- Forged-header test: send a request containing a fake
X-Forwarded-Foror similar header through an untrusted path. The application should not accept that value. - Chain test: use a request that passes through more than one trusted hop and verify that your parser selects the address defined by the provider’s algorithm, not simply the first or last token by habit.
- Malformed-input test: send empty, invalid, IPv6, and unusually long header values. The application should reject invalid results without warnings, crashes, or unsafe output.
- Failure-path test: temporarily make the geolocation or proxy-dependent service unavailable. Confirm that a timeout or missing header produces a controlled “unknown” result and does not block legitimate visitors unexpectedly.
Log enough metadata to diagnose a mismatch—such as the request path, whether it arrived from a trusted proxy, and which parsing branch ran—without retaining more personal data than your purpose requires.
Do not use an unchecked IP for security decisions
WordPress warns that its convenience helper is not intended for situations where IP authenticity matters. The same principle applies to any header-based implementation. An attacker who can choose the apparent address may evade an IP ban, defeat a rate-limit keyed only to that value, pollute audit records, or influence location-based logic.
- Do not authenticate a user based on a client-IP header.
- Do not grant administrative access, payment approval, or account recovery based solely on an address.
- Do not assume an address uniquely identifies a person; households, offices, mobile networks, VPNs, and carrier-grade NAT can share one address.
- For abuse controls, combine a correctly derived address with authenticated identity, session signals, request behavior, and provider-side controls.
Even a correctly forwarded address is a network indicator, not a cryptographic identity token.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Privacy, retention, and anonymization
WordPress privacy documentation lists IP addresses among data that can identify a user. The obligations that follow depend on your jurisdiction, purpose, sharing arrangements, and whether the address is retained. Before enabling collection, decide:
- Why the address is needed and what feature depends on it.
- Which administrators, contractors, security services, or geolocation providers can access it.
- How long raw addresses are retained and when logs, comment metadata, backups, and exports are deleted.
- Whether your privacy notice explains the collection, purpose, sharing, and applicable user rights.
- Whether the purpose can be met with a shortened or anonymized value instead of a full address.
WordPress’s wp_privacy_anonymize_ip() helper demonstrates anonymization. Use the anonymized result when exact precision is unnecessary, such as broad regional reporting. Apply anonymization before persistence where possible, not only when rendering a page, because raw values may otherwise remain in logs, caches, backups, or third-party systems.
Best Value
Consent and legal review
Some processing may require active consent, while other processing may rely on a different lawful basis. The answer varies by location and purpose; a privacy professional should review sites operating across jurisdictions. At minimum, align the privacy policy, retention schedule, access controls, and deletion process with what the site actually does.
Troubleshooting: the value is wrong
WordPress shows the proxy address
- Confirm that the proxy is forwarding the original address at all.
- Check that WordPress is reading the provider’s canonical header, not a generic header with different semantics.
- Verify that requests reach the origin from the documented proxy ranges.
- Check that a firewall, web server, or hosting layer is not replacing or stripping the header before PHP sees it.
- Repeat the test through the public proxy path and directly against the origin.
The visitor can spoof the address
Your application is probably trusting a header from every source. Restrict trust to the proxy’s source ranges, require the proxy to overwrite client-supplied copies, and ignore forwarded values on direct or untrusted requests. If you cannot establish those controls, use the connection address as an approximate transport value and do not use it for enforcement.
Free tools Windows power users keep installed
One-click scans. No signup required.
IPv6 or malformed values fail
Ensure your validation accepts both IPv4 and IPv6, handles whitespace when parsing a documented comma-separated chain, and rejects invalid tokens. Store a normalized validated value or an explicit unknown state. Never silently fall back to an unvalidated header after validation fails.
Geolocation is slow or unavailable
Geolocation is an additional, fallible service. Cache responses where appropriate, enforce a short timeout, handle API errors, and allow the page or security workflow to continue when location data is unavailable. A location result should not be presented as an exact physical location.
Quick Recap
A decision checklist
- Direct traffic: validate
REMOTE_ADDRand escape it for output. - Proxy traffic: identify the intermediary, its canonical header, source ranges, and chain algorithm.
- Trust: accept forwarded data only from those sources and only after header rewriting is controlled.
- Purpose: distinguish display or analytics from authentication, bans, and other high-stakes decisions.
- Data minimization: anonymize or truncate when full precision is not necessary; set a retention period.
- Verification: test direct, proxied, forged-header, multi-hop, malformed, and service-failure paths.
- Documentation: update the privacy notice and record who can access or receive the data.
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.




