One of my coworkers was having some trouble trying to escape data for
JSON in Lua, using the 'json' converter, based on the documentation, and
this lead to a deep bug discovery.

The Lua documentation [1] states that JSON escaping converter is exposed
in Lua, but it turns out that's not quite true.

Creatively dumping the function metatable [2] (see code at the end)
shows only a subset of converters exposed, and notable is missing at
least the following as of
v1.8.12:
- add *
- and *
- div *
- field
- json
- mod *
- mul *
- or *
- regsub
- sub *
- word
- xor *

Some fetches are also omitted:
- bool
- bin
- meth
- map*
- var
- set-var
- unset-var
(there might be more, I didn't have a comprehensive list of converters &
fetches).

All of these have in common that they have a validation of arguments.
Those with a * gained validation of arguments in commit
5d86fae2344dbfacce5479ba86bd2d2866bf5474 (v1.6-dev2-52-g5d86fae23)

This bug has been around since the start of Lua fetchers & converters.

hlua_run_sample_conv is capable of running the args checker [3]:
```c
 /* Run the special args checker. */
 if (conv->val_args && !conv->val_args(args, conv, "", 0, NULL)) {
        hlua_pusherror(L, "error in arguments");
        WILL_LJMP(lua_error(L));
 }
```

But any converters with arguments checking functions are not registered [4]:
```c
 /* Dont register the keywork if the arguments check function are
  * not safe during the runtime.
  */
 if (sc->val_args != NULL)
        continue;
```

Fetchers have a similar issue, but some checkers were explicitly permitted:
```c
 /* Dont register the keywork if the arguments check function are
  * not safe during the runtime.
  */
 if ((sf->val_args != NULL) &&
     (sf->val_args != val_payload_lv) &&
          (sf->val_args != val_hdr))
              continue;
```

Here's a Lua AppletHTTP [5] that lets you dump out which fetchers & converters 
are exposed:
```lua
core.register_service("dump", "http", function(applet)
  local response = core.concat()
  response:add('---\n')
  response:add('applet:\n')
  members = { 'sf', 'f', 'sc', 'c' }

  for i,m in ipairs(members) do
        response:add('applet.' .. m .. ':\n')
    for k, v in pairs(getmetatable(applet[m])) do
      if k == "__index" then
                local funcs = {}
        for i, j in pairs(v) do
                  table.insert(funcs, i)
        end
                table.sort(funcs)
                for i,j in ipairs(funcs) do
          response:add('- "' .. tostring(j) .. '"\n')
                end
                break
      end
    end
        response:add('\n')
  end
  response = response:dump()
  applet:set_status(200)
  applet:add_header("content-length", string.len(response))
  applet:add_header("content-type", "text/yaml")
  applet:start_response()
  applet:send(response)
end)
```

[1] https://www.arpalert.org/src/haproxy-lua-api/1.8/index.html#Converters
[2] https://github.com/haproxy/haproxy/blob/master/doc/lua.txt#L297-L307
[3] 
https://github.com/haproxy/haproxy/commit/594afe76e4694d9faf281ae87f2d026506f7a9d9#diff-fc1678dd7de891cf951a19f59a9a7375R2643
[4] 
https://github.com/haproxy/haproxy/commit/594afe76e4694d9faf281ae87f2d026506f7a9d9#diff-fc1678dd7de891cf951a19f59a9a7375R4003
[5] https://gist.github.com/robbat2/6c75f78e0d857b6d8649d591bc44c452

Initial-Discovery: Yue Zhu <y...@digitalocean.com>
Tracing: Robin H. Johnson <rjohn...@digitalocean.com>
Signed-off-by: Robin H. Johnson <rjohn...@digitalocean.com>
Signed-off-by: Robin H. Johnson <robb...@gentoo.org>
---
 src/hlua.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/src/hlua.c b/src/hlua.c
index 4715639a1..d575f31ea 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -7737,15 +7737,6 @@ void hlua_init(void)
         */
        sf = NULL;
        while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
-
-               /* Dont register the keywork if the arguments check function are
-                * not safe during the runtime.
-                */
-               if ((sf->val_args != NULL) &&
-                   (sf->val_args != val_payload_lv) &&
-                        (sf->val_args != val_hdr))
-                       continue;
-
                /* gL.Tua doesn't support '.' and '-' in the function names, 
replace it
                 * by an underscore.
                 */
@@ -7785,12 +7776,6 @@ void hlua_init(void)
         */
        sc = NULL;
        while ((sc = sample_conv_getnext(sc, &idx)) != NULL) {
-               /* Dont register the keywork if the arguments check function are
-                * not safe during the runtime.
-                */
-               if (sc->val_args != NULL)
-                       continue;
-
                /* gL.Tua doesn't support '.' and '-' in the function names, 
replace it
                 * by an underscore.
                 */
-- 
2.18.0


Reply via email to