Skip to content

fix(security): persist IP filter config + enforce it in the authz pipeline (#6131) - #6132

Merged
diegosouzapw merged 2 commits into
release/v3.8.44from
fix/6131-ipfilter-persist-enforce
Jul 3, 2026
Merged

diegosouzapw merged 2 commits into
release/v3.8.44from
fix/6131-ipfilter-persist-enforce

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Closes #6131.

Problem (user-reported)

"the IP blacklist feature still doesn't save the IPs added, it resets to 'Disabled' and clears all the blacklisted IPs after every OmniRoute update."

Two root causes in open-sse/services/ipFilter.ts:

  1. No persistence — config lived in a module-level in-memory _config; the settings route mutated it but nothing wrote to the DB or loaded on startup, so every restart (every update) reset it to Disabled + empty lists.
  2. No enforcement — checkIP/checkRequestIP were never wired into the request pipeline, so listed IPs were never actually blocked.

Fix

  • A — persistence: lazy-load from key_value (namespace ipFilter) on first access + persist on every mutation. better-sqlite3 is sync, so no startup wiring; tempBans stay ephemeral; DB errors degrade to in-memory only.
  • B — enforcement: runAuthzPipeline calls checkRequestIP for non-loopback requests → 403 before the route policy. Loopback is exempt so the local operator can never lock themselves out.

Tests (TDD)

  • tests/unit/ip-filter-persistence-6131.test.ts — config + blacklist survive a simulated restart; blocked IP still blocked; whitelist mode; safe defaults.
  • tests/unit/authz/ip-filter-enforcement-6131.test.ts — blacklisted IP → 403; clean IP passes; disabled never blocks; loopback exempt.
  • Existing ip-filter (16) + authz/pipeline (27) suites stay green.

…eline (#6131)

The IP blacklist/whitelist lived in a module-level in-memory _config only: the
settings route mutated it but nothing persisted to the DB or loaded on startup, so
every restart (i.e. every OmniRoute update) reset it to Disabled + empty lists —
the user-reported symptom. Worse, checkIP/checkRequestIP were never wired into the
request path, so listed IPs were never actually blocked.

Part A (persistence): ipFilter.ts now lazily loads its config from the key_value
table (namespace 'ipFilter') on first access and persists on every mutation
(configure/add/remove). better-sqlite3 is synchronous, so this stays in the hot
path with no startup wiring; tempBans stay ephemeral; DB failures degrade to
in-memory only.

Part B (enforcement): runAuthzPipeline now calls checkRequestIP for non-loopback
requests, returning 403 before the route policy runs. Loopback is exempt so the
local operator can never lock themselves out of the dashboard.

TDD: ip-filter-persistence-6131.test.ts (config + blacklist survive a simulated
restart; blocked IP still blocked) and authz/ip-filter-enforcement-6131.test.ts
(blacklisted IP -> 403, clean IP passes, disabled never blocks, loopback exempt).
Existing ip-filter + authz/pipeline suites stay green.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

…h the real DB

Since #6131 the IP filter lazily loads/persists to the DB. Without DATA_DIR
isolation ip-filter.test.ts touched ~/.omniroute (side-effect + a WAL-lock flake
when run alongside other DB tests). Pin a throwaway DATA_DIR + reset per test.
@diegosouzapw
diegosouzapw merged commit f9b2fb4 into release/v3.8.44 Jul 3, 2026
2 of 3 checks passed
@diegosouzapw
diegosouzapw deleted the fix/6131-ipfilter-persist-enforce branch July 4, 2026 07:38
@diegosouzapw diegosouzapw mentioned this pull request Jul 4, 2026
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…eline (diegosouzapw#6131) (diegosouzapw#6132)

Integrated into release/v3.8.44 — IP filter persistence + authz-pipeline enforcement (closes diegosouzapw#6131). HARD-neutro: validate-release-green on the merge shows the same 3 pre-existing base-reds as the release baseline (test-masking cycle-wide, unit red-herring, integration batch-E2E env); diegosouzapw#6131's own tests + ip-filter/pipeline suites all green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant