Skip to content

mod_setenvif: look up the header again after a SetEnvIfExpr rule - #860

Open
arshsmith1 wants to merge 1 commit into
apache:trunkfrom
arshsmith1:setenvif-expr-stale-value
Open

arshsmith1 wants to merge 1 commit into
apache:trunkfrom
arshsmith1:setenvif-expr-stale-value

Conversation

@arshsmith1

Copy link
Copy Markdown

match_headers() reuses val/val_len for consecutive SetEnvIf rules on the same header and only looks the value up again when b->name != last_name. A SetEnvIfExpr rule in between leaves last_name alone, but ap_expr_exec_re() is passed &val and, when the expression's regex has a capture group and matches, points val at the string that regex was applied to. The next rule for the earlier header then matches that other value, still using the earlier header's val_len, so a literal (apr_strmatch) pattern can also read past the end of a shorter string. With

SetEnvIf X-A foo SEI_FIRST=1
SetEnvIfExpr "req('X-B') =~ /(.+)/" SEI_EXPR=$1
SetEnvIf X-A bar SEI_LITERAL=1
SetEnvIf X-A ^bar$ SEI_REGEX=1

a request with X-A: foo-xxx and X-B: bar sets SEI_LITERAL and SEI_REGEX although X-A does not contain "bar". Expression rules now reset last_name, so the next header rule looks its value up again. The new test_005_setenvif.py fails without the change. The rest of test/modules/metadata and test/pytest_suite's test_setenvif.py pass; the two libmagic ELF cases fail on macOS with and without it.


  • This PR does not report or address a security vulnerability
    (see SECURITY.md and
    https://www.apache.org/security/#reporting-a-vulnerability).
  • Code follows the httpd style guide.
  • New log messages (level debug or higher) use an empty APLOGNO() tag;
    numbers are assigned by a committer at merge time (see docs/log-message-tags/README).
  • If the change is user-visible, a changes-entries/*.txt file is included,
    following the template in README.CHANGES (not needed otherwise).
  • Test cases based on pyhttpd are included where appropriate, in the
    test/modules/xxx directory matching the modules/xxx module source,
    or test/modules/core for core server changes. On Unix, verify these
    pass locally with e.g. make check-pytest PYTEST_DIRS=test/modules/xxx.

match_headers() reuses val and val_len for consecutive rules on the
same header, but a SetEnvIfExpr rule in between can point val at the
string its regex was applied to.  The next rule for the earlier header
was then matched against that other value, with the earlier header's
length.  Reset last_name for expression rules so the value is looked
up again.

* modules/metadata/mod_setenvif.c (match_headers): Reset last_name
  for expression rules.

* test/modules/metadata/test_005_setenvif.py: New test.
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