Skip to content

fix: go to the zones list after saving a zone opened without a Referer - #5207

Merged
connortechnology merged 1 commit into
ZoneMinder:masterfrom
nabbi:fix/b8-zone-save-referer
Oct 11, 2026
Merged

connortechnology merged 1 commit into
ZoneMinder:masterfrom
nabbi:fix/b8-zone-save-referer

Conversation

@nabbi

@nabbi nabbi commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Automated PR, tested in a zm-holodeck sandbox. An AI agent (Claude Opus 5.5) reproduced the bug on a disposable ZoneMinder built from upstream master 6c0f976c2, wrote this fix and ran the checks below on the same lab. Minimal human review before opening: please review it as you would any contributor's PR.

TL;DR

  • Fixes: Saving a zone opened from a typed URL answers 500 (the zone is saved) #5206: saving a zone opened without a Referer answers 500.
  • Change: an empty REFERER falls back to the zones list (?view=zones&mid=N), so the save redirects as it does from the list. 1 file, +5/-2.
  • Risk: only the redirect after a zone save; a non-empty REFERER behaves as before.
  • Tested: reproduced before, redirects after; ui suite as on master.
Details: change, checks

Before

Upstream master 6c0f976c2, typed-URL save: HTTP 500, Location None ... row saved: 7 4.

Change

  • web/includes/actions/zone.php: use REFERER only when it is !empty(), otherwise '?view=zones&mid='.$mid.
  • Test: ui test test_zone_save_typed_url in holodeck (browser-driven; ZoneMinder has no web UI test harness).

Behaviour changes

Change Who sees it Intended / collateral Tested by
A save from a directly opened zone page lands on the zones list instead of a 500 web users intended HTTP probe, ui test

After

Branch at 42b6e6b27 (base 6c0f976c2): HTTP 302, Location '?view=zones&mid=1'.

Check Result
holodeck checks script tests PASS=28; smoke PASS=11 XFAIL=1 (known); ui-api PASS=9; ui suite green apart from known XFAILs

Not run: release-1.38 (same code; the patch applies with git am -3).

refs #5206

🤖 Generated with Claude Code

The zone form posts its Referer back as REFERER, and posts it empty when
the form was opened from a typed URL or a bookmark. The action used it
whenever it was set, so $redirect was empty, index.php rendered the zone
view with the action's $zone (a database row, or array() for a new zone,
neither with Points) and ksort() at views/zone.php:105 failed with
'Argument #1 must be of type array, null given'. The zone was saved but
the browser got a 500.

Use REFERER only when it is not empty and fall back to the monitor's
zones list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@connortechnology
connortechnology merged commit 6a35e89 into ZoneMinder:master Oct 11, 2026
10 checks passed
connortechnology pushed a commit that referenced this pull request Oct 11, 2026
#5207)

The zone form posts its Referer back as REFERER, and posts it empty when
the form was opened from a typed URL or a bookmark. The action used it
whenever it was set, so $redirect was empty, index.php rendered the zone
view with the action's $zone (a database row, or array() for a new zone,
neither with Points) and ksort() at views/zone.php:105 failed with
'Argument #1 must be of type array, null given'. The zone was saved but
the browser got a 500.

Use REFERER only when it is not empty and fall back to the monitor's
zones list.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 6a35e89)
connortechnology added a commit that referenced this pull request Oct 11, 2026
After saving a zone, actions/zone.php redirected to the REFERER the zone form
posted, which the form fills from the Referer its page was loaded with. A
zone editor who reached the zone page through a link on another site was sent
to that site after saving: an open redirect, usable to lead someone from a
trusted ZoneMinder page to a look-alike login. Forging the POST itself is
blocked by the CSRF token, so it needs an editor who followed such a link.

localRedirectUrl() returns the target only if it is a query-only URL or an
absolute http(s) URL on the host and port of the current request, and the
fallback otherwise: another host, //host, backslashes, user@host, other
schemes and control characters all give the fallback. The zone save falls
back to the zones list, as it already does with no Referer (#5207).

tests/php/test_local_redirect_url.php covers 21 cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 16817e4)
connortechnology added a commit that referenced this pull request Oct 11, 2026
After saving a zone, actions/zone.php redirected to the REFERER the zone form
posted, which the form fills from the Referer its page was loaded with. A
zone editor who reached the zone page through a link on another site was sent
to that site after saving: an open redirect, usable to lead someone from a
trusted ZoneMinder page to a look-alike login. Forging the POST itself is
blocked by the CSRF token, so it needs an editor who followed such a link.

localRedirectUrl() returns the target only if it is a query-only URL or an
absolute http(s) URL on the host and port of the current request, and the
fallback otherwise: another host, //host, backslashes, user@host, other
schemes and control characters all give the fallback. The zone save falls
back to the zones list, as it already does with no Referer (#5207).

tests/php/test_local_redirect_url.php covers 21 cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants