WP Manifestindependent plugin directory
manifest / analytics / ipquery-wordpress

Stracini Visitor Analytics with IpQuery WP Registry grade B. Medium-severity findings · 1 findingWP RegistryMedium-severity findings · 1 findingOpen the reportB

🌍📊 Track and analyse visitor IPs in WordPress using the IpQuery API. World heatmap, country & city breakdowns, and VPN/proxy/Tor risk detection.

★ 2stars
29release downloads
v1.3.11latest · 3mo ago

Install

Download stracini-visitor-analytics-1.3.11.zip From the v1.3.11 release on GitHub, Jul 20, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/guibranco/ipquery-wordpress/releases/download/v1.3.11/stracini-visitor-analytics-1.3.11.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

🌍 Stracini Visitor Analytics with IpQuery

Track and analyse every visitor. Visualise traffic. Detect threats.

A WordPress plugin that enriches visitor IP addresses with real-time geolocation, ISP data, and risk intelligence — powered by the IpQuery API via guibranco/ipquery-php.

📖 Documentation · 🐛 Report a Bug · ✨ Request a Feature

Plugin renamed for WordPress.org directory compliance The WordPress.org Plugin Review Team flagged "IpQuery" as a trademark that belongs to the IpQuery API service. The plugin has been renamed to Stracini Visitor Analytics with IpQuery to make it clear this is an independent, third-party integration and is not officially affiliated with IpQuery. The repository name, internal class names, database table, and option keys are unchanged.


✨ Features

Feature Description
🗺️ World heatmap Interactive Leaflet.js map with a heat layer weighted by visit count
📊 Country & city charts Horizontal bar chart of top countries; dedicated top-cities table with country flags
🛡️ Risk intelligence Per-IP flags for VPN, proxy, Tor, datacenter, and mobile connections
🔢 Risk scoring Numeric risk score (0–100) per IP with colour-coded indicators
🔍 Visitors table Searchable, sortable, filterable table with full enrichment data for every IP
🔎 Manual lookup Instantly enrich any IP address on demand from the admin panel
⚡ Non-blocking API calls run at shutdown — visitor page load is never delayed
🗄️ Smart caching WordPress transients cache each IP for 1 hour; only one API call per IP per hour
🧹 Auto-retention Configurable data retention with daily WP-Cron cleanup
🔒 Privacy controls Exclude IPs, skip logged-in users or admins, disable tracking at any time
📥 CSV export Download all visitor data (or the current filtered view) as a UTF-8 CSV file

🖥️ Admin screens

Dashboard

The plugin adds a Visitor Analytics entry to the WordPress admin sidebar with three sub-pages.

Dashboard — a live overview built from four widgets:

  • Stat cards — total visits, unique IPs, VPN/proxy/Tor count, and overall risk rate
  • Visitor heatmap — world map with gradient heat layer (blue → yellow → red)
  • Top countries — bar chart (Chart.js) and a flag-annotated data table
  • Top cities — table with city name, country flag, visit count, and traffic share
  • Risk breakdown — doughnut chart and individual cards for each risk type

Visitors — full paginated table of every tracked IP with search, type filters, per-row delete, manual lookup form, and bulk purge.

Settings — all tracking options, data retention, excluded IPs list, and a system status panel.


🏗️ Architecture

Visitor browser request
        │
        ▼  WordPress bootstrap
        │
  [ init ]  IpQuery_Tracker registered
        │
  [ wp ]    maybe_track()
        │    ├─ skip: AJAX / REST / Cron
        │    ├─ skip: logged-in / admin (configurable)
        │    ├─ resolve IP (Cloudflare → X-Real-IP → X-Forwarded-For → REMOTE_ADDR)
        │    ├─ skip: private ranges, excluded IPs
        │    ├─ transient hit  →  bump visit_count only
        │    └─ transient miss →  register shutdown callback
        │
  Page rendered & sent to browser ◄──── no latency added
        │
  [ shutdown ]  lookup_and_store()
        │
        ▼
  IpQueryClient::getIpData($ip)   ← guibranco/ipquery-php
        │
        ▼
  GET https://api.ipquery.io/{ip}?format=json
        │
        ▼
  IpQueryResponse { location, isp, risk }
        │
        ▼
  IpQuery_DB::upsert()  →  wp_ipquery_visitors
        │
        ▼
  set_transient( "ipq_{md5}", 1, HOUR_IN_SECONDS )

📋 Requirements

Requirement Minimum
WordPress 6.0
PHP 8.2
PHP extension cURL
Database MySQL 5.7+ / MariaDB 10.3+

No Composer or external package manager needed — guibranco/ipquery-php is bundled inside includes/vendor/.


🚀 Installation

From GitHub releases

  1. Download the latest .zip from the Releases page.
  2. In your WordPress admin go to Plugins → Add New Plugin → Upload Plugin.
  3. Upload the .zip and click Install Now, then Activate.

Manually

git clone https://github.com/guibranco/ipquery-wordpress.git

Copy the ipquery-wordpress/ folder into wp-content/plugins/, then activate it from Plugins in the WordPress admin.

On activation

The plugin automatically:

  • Creates the wp_ipquery_visitors database table
  • Writes default settings to wp_options
  • Schedules a daily WP-Cron event for data retention cleanup

⚙️ Configuration

Navigate to Visitor Analytics → Settings to configure:

Setting Default Description
Enable Tracking ✅ On Master switch — disable to pause all tracking
Track Logged-in Users ❌ Off Whether authenticated visitors are tracked
Track Administrators ❌ Off Whether manage_options users are tracked
Look Up Private IPs ❌ Off Send private/LAN IPs to the API (useful for local dev)
Excluded IPs (empty) Newline-separated list of IPs to never track
Data Retention 90 days Records older than this are auto-deleted by cron

Full documentation: guilherme.stracini.com.br/ipquery-wordpress/configuration


🗃️ Database schema

A single table wp_ipquery_visitors is created on activation:

id            BIGINT UNSIGNED  PRIMARY KEY AUTO_INCREMENT
ip            VARCHAR(45)      UNIQUE NOT NULL
country       VARCHAR(100)
country_code  VARCHAR(10)
city          VARCHAR(100)
state         VARCHAR(100)
zipcode       VARCHAR(20)
latitude      DECIMAL(10,7)
longitude     DECIMAL(10,7)
timezone      VARCHAR(100)
asn           VARCHAR(50)
org           VARCHAR(255)
isp           VARCHAR(255)
is_mobile     TINYINT(1)
is_vpn        TINYINT(1)
is_tor        TINYINT(1)
is_proxy      TINYINT(1)
is_datacenter TINYINT(1)
risk_score    SMALLINT(3)
first_seen    DATETIME
last_seen     DATETIME
visit_count   BIGINT UNSIGNED

📦 Project structure

ipquery-wordpress/
├── ipquery-wordpress.php          # Plugin bootstrap & constants
├── includes/
│   ├── vendor/                    # Bundled guibranco/ipquery-php
│   │   ├── IpQueryClient.php
│   │   ├── IpQueryException.php
│   │   ├── IIpQueryClient.php
│   │   └── Response/
│   │       ├── IpQueryResponse.php
│   │       ├── Isp.php
│   │       ├── Location.php
│   │       └── Risk.php
│   ├── class-ipquery-db.php       # Table install, upsert, and query helpers
│   ├── class-ipquery-tracker.php  # Visitor capture, IP resolution, caching
│   └── class-ipquery-admin.php    # Admin menus, AJAX, action handlers
├── admin/views/
│   ├── dashboard.php              # Heatmap, charts, stat cards, tables
│   ├── visitors.php               # Searchable/sortable visitor log
│   └── settings.php               # Settings form & system status
├── assets/
│   ├── css/admin.css
│   ├── js/ipquery-maps.js         # Leaflet heatmap
│   └── js/ipquery-charts.js       # Chart.js bar & doughnut charts
├── docs/                          # Jekyll / Just the Docs site
│   ├── _config.yml
│   ├── index.md
│   ├── installation.md
│   ├── configuration.md
│   ├── dashboard.md
│   ├── visitors.md
│   ├── tracking.md
│   ├── api.md
│   └── privacy.md
└── .github/workflows/
    └── docs.yml                   # GitHub Pages deployment

🔌 Powered by

Dependency Role
guibranco/ipquery-php PHP client library for the IpQuery API — bundled inside the plugin
IpQuery API Free IP intelligence service providing geolocation, ISP, and risk data
Leaflet.js Interactive world map rendering
Leaflet.heat Heatmap layer for Leaflet
Chart.js Bar and doughnut charts
OpenStreetMap Map tile provider
Flag CDN Country flag images

📖 Documentation

Full documentation is available at guilherme.stracini.com.br/ipquery-wordpress.

Page Description
Installation System requirements and install steps
Configuration All settings explained
Dashboard Widget reference
Visitors Visitor table, filters, and lookup
How Tracking Works Technical flow and caching
IpQuery API API fields and PHP library reference
Privacy & GDPR Data collected, controls, and policy guidance

🤝 Contributing

Contributions, issues, and feature requests are welcome.

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Commit your changes: git commit -m "feat: add my feature"
  4. Push to the branch: git push origin feat/my-feature
  5. Open a Pull Request

Please follow the WordPress Coding Standards for PHP files.


📄 License

Distributed under the MIT License. See LICENSE for full text.


Made with ❤️ by Guilherme Branco Stracini · Built on guibranco/ipquery-php

Releases

25 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v1.3.11 latest
Jul 20, 2026 3mo ago
stracini-visitor-analytics-1.3.11.zip
4
Jul 6, 2026 3mo ago
stracini-visitor-analytics-1.3.10.zip
0
Jun 22, 2026 4mo ago
stracini-visitor-analytics-1.3.9.zip
0
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.8.zip
1
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.7.zip
1
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.6.zip
1
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.5.zip
1
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.4.zip
1
Jun 18, 2026 4mo ago
stracini-visitor-analytics-1.3.3.zip
1
May 25, 2026 5mo ago
stracini-visitor-analytics-1.3.2.zip
2
May 23, 2026 5mo ago
stracini-visitor-analytics-1.3.1.zip
3
May 23, 2026 5mo ago
stracini-visitor-analytics-1.3.0.zip
1
May 13, 2026 5mo ago
ipquery-1.2.0.zip
4
May 12, 2026 5mo ago
ipquery-1.1.4.zip
0
May 12, 2026 5mo ago
ipquery-1.1.3.zip
1
May 12, 2026 5mo ago
ipquery-1.1.2.zip
0
May 11, 2026 5mo ago
ipquery-1.1.1.zip
2
May 7, 2026 5mo ago
ipquery-1.1.0.zip
1
May 5, 2026 5mo ago
ipquery-1.0.5.zip
1
Apr 27, 2026 5mo ago
ipquery-1.0.4.zip
1
Apr 24, 2026 6mo ago
ipquery-1.0.3.zip
0
Apr 24, 2026 6mo ago
ipquery-1.0.2.zip
0
Apr 24, 2026 6mo ago
ipquery-1.0.1.zip
0
Apr 23, 2026 6mo ago
ipquery-1.0.0.zip
1
Apr 23, 2026 6mo ago
ipquery-0.0.1.zip
2
B grade

Security

Stracini Visitor Analytics with IpQuery 1.3.11 · audited by WP Registry

Medium-severity findings.

1 medium
Audited release
1.3.11
Findings
1
Worst severity
medium
Content hash
4660ea542b085f26dba11e76…

Findings

  • medium Untrusted forwarding headers bypass per-IP cache and amplify IpQuery lookups into a worker DoS

    dos

    SVA_Tracker::get_client_ip() prefers HTTP_CF_CONNECTING_IP, then HTTP_X_REAL_IP, then the first HTTP_X_FORWARDED_FOR hop, then REMOTE_ADDR, with FILTER_VALIDATE_IP but no trusted-proxy check. maybe_track (hooked on frontend 'wp' when tracking_enabled is true, which is the install default) uses that value as both the DB key and the 1-hour transient sva_{md5(ip)}. On a default WordPress host that does not strip those headers, an unauthenticated client can send a new public IP per request, miss the cache every time, and at shutdown force IpQueryClient::makeRequest — a blocking curl to https://api.ipquery.io/{ip}?format=json with CURLOPT_CONNECTTIMEOUT 5 and CURLOPT_TIMEOUT 10 — then SVA_DB::upsert into {prefix}sva_visitors. That is a PHP-worker exhaustion amplifier (up to ~10s extra hold per request) plus unbounded analytics-table growth and third-party lookups of attacker-chosen IPs from the site's IP. Private/reserved ranges are skipped unless lookup_private_ips is enabled, so this is not SSRF to RFC1918, but the public-IP throttle is fully attacker-keyed. Sites actually behind Cloudflare/nginx that overwrite these headers are not affected from the public internet; direct-to-origin or non-proxied installs are.

    includes/class-sva-tracker.php:41-86,152-172

    Recommendation

    Use REMOTE_ADDR unless the connection is from a configured trusted proxy (or Cloudflare IPs when CF-Connecting-IP is honored), and only then read CF-Connecting-IP / X-Real-IP / X-Forwarded-For from that proxy. Rate-limit API lookups and inserts on the connecting address (REMOTE_ADDR), not solely on the spoofable lookup IP. Cap concurrent/queued IpQuery calls per worker and per remote address.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.