Quoting =~ in unlang on string expansion
Hi folks! String expansion is behaving different in case just adding a string or being a result in a regex compare. (1) if (&Called-Station-ID =~ /%{reply:FeatureA}/) { (1) EXPAND %{reply:FeatureA} (1) --> \^\(3\[0-79]\|38\[0-25-9]\|4\[014-9]\|42\[123]\|29\[89]\|43\[1-6]\|43800\|43720) (1) ERROR: \^\(3\[0-79]\|38\[0-25-9]\|4\[014-9]\|42\[123]\|29\[89]\|43\[1-6]\|43800\|43720) (1) ERROR: ^ Pattern compilation failed: unmatched parentheses (1) ERROR: Failed retrieving values required to evaluate condition Sure this does not compile because it quoted "(" but not ")". In this use case some chars in the reply string are quoted: ^(|[ are quoted while ]) are not for some reasons But adding the reply value to some debug AVPair this is done without quoting: This shows the real content of the reply attr: (1) else { (1) update control { (1) Auth-Type := Reject (1) } # update control = noop (1) update reply { (1) EXPAND block=%{reply:FeatureA} (1) --> block=^(3[0-79]|38[0-25-9]|4[014-9]|42[123]|29[89]|43[1-6]|43800|43720) (1) Generic-Debug := block=^(3[0-79]|38[0-25-9]|4[014-9]|42[123]|29[89]|43[1-6]|43800|43720) I was looking through source code why this is happening, but I am lost. Any hint to source code is appreciated. I'm using version from Debian Buster Backports: 3.0.21+dfsg-1~bpo10+1 I tried a lot already: "/%{}/", /"%{}"/, %{unescape:...}, ... even if (&Called-Station-ID =~ /&reply:FeatureA/) (which results in FALSE always) Why are some character quoted here in this expansion? Where are the "safe charaters" defined for unlang compare operator? Greetings, Walter
On Sep 13, 2021, at 9:32 AM, Walter Schober <walter.schober@neotel.at> wrote:
String expansion is behaving different in case just adding a string or being a result in a regex compare.
Yes.
(1) if (&Called-Station-ID =~ /%{reply:FeatureA}/) { (1) EXPAND %{reply:FeatureA} (1) --> \^\(3\[0-79]\|38\[0-25-9]\|4\[014-9]\|42\[123]\|29\[89]\|43\[1-6]\|43800\|43720) (1) ERROR: \^\(3\[0-79]\|38\[0-25-9]\|4\[014-9]\|42\[123]\|29\[89]\|43\[1-6]\|43800\|43720) (1) ERROR: ^ Pattern compilation failed: unmatched parentheses (1) ERROR: Failed retrieving values required to evaluate condition
Sure this does not compile because it quoted "(" but not ")".
OK. That should be fixed. But... v3 doesn't track "trusted" versus "untrusted" data. So it treats all data as untrusted. This means that you can't really create a regular expression from an attribute. Because the attribute contents will be quoted. Which is probably not what you want. For v4, we're looking on fixing this. But it will be a bit before v4 is ready.
In this use case some chars in the reply string are quoted: ^(|[ are quoted while ]) are not for some reasons But adding the reply value to some debug AVPair this is done without quoting:
Yes, because it's not being used in a regular expression.
I was looking through source code why this is happening, but I am lost. Any hint to source code is appreciated.
src/main/evaluate.c, function cond_do_regex(). For the list of escaped characters, see regex_escape() in that file
I'm using version from Debian Buster Backports: 3.0.21+dfsg-1~bpo10+1 I tried a lot already: "/%{}/", /"%{}"/, %{unescape:...}, ... even if (&Called-Station-ID =~ /&reply:FeatureA/) (which results in FALSE always)
Why are some character quoted here in this expansion?
Because we don't want untrusted data from the network being used in a trusted regex. It's a security issue.
Where are the "safe charaters" defined for unlang compare operator?
See regex_escape() Alan DeKok.
Thanks for clarify! So this is hardcoded in 3.0 and there is no chance to change (even with a pull request) since it is intended. I can move the execution of the "called-station-id regex REGEX" into the MySQL and return the result from there since my "authreply_table" is already a call to a stored procedure. Br Walter
participants (2)
-
Alan DeKok -
Walter Schober