Skip to content

[2.x] feat(audit): search the log by partial IP address or subnet - #5431

Merged
imorland merged 3 commits into
2.xfrom
im/audit-ip-range-search
Nov 8, 2026
Merged

imorland merged 3 commits into
2.xfrom
im/audit-ip-range-search

Conversation

@imorland

@imorland imorland commented Nov 8, 2026

Copy link
Copy Markdown
Member

Fixes #4939

Changes proposed in this pull request:
The audit ip: filter now matches partial addresses, CIDR ranges and trailing wildcards as well as full addresses, for IPv4 and IPv6 (ip:192.168, ip:10.0.0.0/8, ip:2a02:390:9e5c:beef for its /64). Each entry also stores its address as 32 hex digits of the 16-byte form (IPv4 as IPv4-mapped IPv6) in a new indexed ip_hex column, so every way of writing an IPv6 address matches and a range is an indexed BETWEEN on every driver. Existing entries are indexed by the new php flarum audit:backfill-ip command rather than the migration, so upgrading a large log doesn't stall; until it runs they are still found by exact searches. The search help text shows the new forms.

Reviewers should focus on:

  • Hex in a char(32) column instead of a binary column, which avoids binding raw bytes for PostgreSQL bytea and SQLite blobs.
  • -ip: now keeps entries that have no IP address (e.g. console actions); before, SQL NOT IN dropped them as a side effect of NULL.
  • The migration's down() leaves the column in place, because uninstalling logs extension.uninstalled after rolling migrations back.

Screenshot

Before After
before after

Necessity

  • Has the problem that is being solved here been clearly explained?
  • If applicable, have various options for solving this problem been considered?
  • For core PRs, does this need to be in core, or could it be in an extension?
  • Are we willing to maintain this for years / potentially forever?

Confirmed

  • Frontend changes: tested on a local Flarum installation.
  • Frontend changes: tests are green (run yarn test in js/).
  • Frontend changes: tests have been added, or are not appropriate here.
  • Backend changes: tests are green (run composer test).
  • Backend changes: tests have been added, or are not appropriate here.
  • Where applicable, changes are suitable for all supported database drivers (MySQL, MariaDB, PostgreSQL, SQLite).
  • Core developer confirmed locally this works as intended.
  • The description above is written by me and describes what this pull request actually does.

Tests pass on SQLite and MariaDB 11.8 (utf8mb4_unicode_ci); PostgreSQL is covered by CI only.

Required changes:

The `ip:` filter matched only exact strings, so IPv6 subnets could not be
searched: the same address is stored in several representations, and where
`::` falls depends on the zeros, not on the subnet boundary.

Each entry now also stores its address as 32 hex digits of the 16-byte
form (IPv4 as IPv4-mapped IPv6) in an indexed `ip_hex` column, and `ip:`
accepts full addresses, CIDR ranges, partial addresses and trailing
wildcards, matched with an indexed range query on every database driver.

Existing entries are indexed by `php flarum audit:backfill-ip`, kept out
of the migration so upgrading a large log does not stall. Until then
they are still found by an exact `ip:` search.

Fixes #4939
@imorland imorland added this to the 2.1 milestone Nov 8, 2026
@imorland
imorland marked this pull request as ready for review November 8, 2026 13:23
@imorland
imorland requested a review from a team as a code owner November 8, 2026 13:23
@imorland
imorland merged commit deae012 into 2.x Nov 8, 2026
36 checks passed
@imorland
imorland deleted the im/audit-ip-range-search branch November 8, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit: search logs by partial IP address / subnet (v4 + v6)

1 participant