
pdp at exim
Oct 3, 2011, 5:23 AM
Post #1 of 1
(785 views)
Permalink
|
|
Exim Security: 4.77 hardening of match_* conditions
|
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 Folks, The forthcoming Exim 4.77 release (now in Release Candidate state) will have a backwards-incompatible change by default, in configuration parsing of four expansion conditions: "match_address", "match_domain", "match_ip" & "match_local_part". Exim's treatment of these options has matched the documentation, but does not appear to match the expectations of many administrators, who as a result may have created configurations which have a security flaw, leading to problems such as SQL injection. Exim's configuration language generally provides a lot of power, but also requires the administrator to use functions like ${quote_mysql:...} when constructing an SQL query. We let you shoot yourself in the foot. We also provide an ${expand:...} operator, to let you re-expand strings; hopefully it is obvious that re-expanding data extracted from an email's headers is a security problem. This is much like the "eval" functionality of many scripting languages. In the case of the match_* operators, the problem is more subtle and too many folks did not understand the documented behaviour and so inadvertently created similar situations, using expansion conditions more powerful than they realised. The four expansion conditions "match_address", "match_domain", "match_ip" & "match_local_part" all take two arguments. The first is something to look for, the second is a list of data to match against. In common with Exim typed list handling, these lists can contain more than just literal string data. In particular, they can contain arbitrary database lookups with arbitrary SQL execution. At this point, it should be clear that using a value derived from an email header or an SMTP exchange as the specification of the list is somewhat unwise. And yet, experience has shown that, time and again, we are seeing people use conditions such as: match_address{$something}{$another_address} where $another_address is extracted from untrustworthy sources. Going forward, by default those four expansion conditions will be unusually different from other conditions, in that the contents of the second string WILL NOT BE SUBJECT TO STRING EXPANSION. Thus this works: ${if match_domain{example.org}{+local_domains}} but this does not, because the '$' is left as a literal '$': ${if match_domain{example.org}{$sender_domain}} Note that the named domainlist "local_domains" here can still contain arbitrary data lookups, as before. Those can still refer to variables derived from an email, as before. It's just that the specification of what the list is that Exim should compare against is no longer expanded and thus can not directly refer to data from an email. This may break some existing configurations, but if so then we believe that your current configuration may have unpleasant security implications. Because we recognise that there may be safe usage of variables _not_ derived directly from the email being handled there is a new build-time option to keep the old behaviour, "EXPAND_LISTMATCH_RHS". Please let us know if you need to use this built-time option, so that we can consider providing safer alternatives. If we do not hear of cases where this was needed, then we may remove the build-time option in a future release. Two new expansion conditions have been added to Exim to help with this change. They are "inlist" and "inlisti". The check: ${if inlist{needle}{foo:needle:bar}} is equivalent to the existing: ${if forany{foo:needle:bar}{eq{$item}{needle}}} but is a little easier to understand and matches the existing match_<foo> layout. The "inlisti" condition is similar, but uses "eqi" instead if "eq" for case-insensitive comparison. The second parameter here is subject to string expansion, but the contents are not subject to lookup expansion, including named list handling. So it's: ${if inlist{example.org}{${complicated_expansion_giving_list}}} ${if inlist{example.org}{<, example.org, example.com}} ${if match_domain{example.org}{+my_domain_list}} It is likely that current incorrect usages of the match_<foo> conditions can be migrated to use of either "eqi" for direct string equality checks, or "inlisti" for looking in ${expanded_data}. Regards, - -Phil Pennock, pp The Exim Maintainers -----BEGIN PGP SIGNATURE----- iEYEAREDAAYFAk6JqTQACgkQQDBDFTkDY3+r5wCfeh/WH5GhSwzvh9nS/uZxrZpf +NQAn0Lj+6ZRqscljdygVqF8kUHQCaaR =2mhA -----END PGP SIGNATURE----- -- ## List details at https://lists.exim.org/mailman/listinfo/exim-announce Exim details at http://www.exim.org/ ##
|