]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
it helps to document this, too
authorAlan T. DeKok <aland@freeradius.org>
Wed, 18 Oct 2023 20:36:05 +0000 (16:36 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 19 Oct 2023 19:27:15 +0000 (15:27 -0400)
We would really like to be able to do

%file.escape("foo/bar/" + %{User-Name})

but if that's an expression, then we get the entire string tainted,
and thge "/" in the first part of the string are escaped.

or maybe

%exec("/bin/rm", "foo/bar" + %file.escape(%{User-Name}))

but we can't (yet) pass expressions as function arguments.

doc/antora/modules/reference/pages/xlat/file.adoc
src/tests/xlat/file.txt

index 23471256cdbb893b584fb2b0e4e1eaf40dea3858..403417fd7e563c3a5dfa3a372f3421b3e3bdd958 100644 (file)
@@ -6,6 +6,27 @@ The filenames can be taken from `tainted` sources, in which cases special charac
 
 For example, the `tainted` string `user@freeradius.org/..` will turn into the filename `user@freeradius.org_2f..`.  This operation renders the filename "safe" for operations on the local file system.  It is not possible for `tainted` data to create files, or to perform directory traversal attacks.
 
+== %file.escape(_string_)
+
+.Return: _string_
+
+This function returns an escaped or "safe" version of the input string.
+
+In some cases, as when using `%exec(...)`, it is impossible to determine which arguments are filenames, and which are simple strings.  This function allows the server to safely pass in a filename to external programs.
+
+The returned filename is guaranteed to be safe to use.  Any portion of the filename which is taken from a "safe" source (i.e. configuration files, etc. controlled by an administator) is used as-is.  Any portion of the filename which is taken from an "unsafe" source (i.e. network apckets) is escaped.  The result is that characters like `/` in unsafe inputs cannot be used to perform directory traversal attacks.
+
+.Safely pass a filename to `%exec(...)`
+====
+[source,unlang]
+----
+&filename = "${logdir}/" + %file.escape(%{User-Name})
+
+%exec("/bin/rm", %{filename})
+----
+====
+
+
 == %file.exists(_string_)
 
 .Return: _bool_
index 4a7e33802aa811fb87a43e640e536c3e63bca136..a548820d0fac53840a9607f7b0b03d25e3af8a4b 100644 (file)
@@ -33,3 +33,12 @@ match yes
 
 xlat_expr %file.exists('src/tests/xlat/file/no-such-file')
 match no
+
+xlat_expr "foo/bar/" + %file.escape(%taint('..baz'))
+match foo/bar/_x2e_x2ebaz
+
+#
+#  Can't do expressions as function arguments
+#
+xlat_expr %file.escape('foo/bar' + "/baz")
+match ERROR offset 34 'Unexpected text after argument 1'