hlua_http_add_hdr() rejects CR/LF/NUL in header names and values,
but three other functions that write headers from Lua don't:

  - hlua_applet_http_addheader()
  - hlua_txn_reply_add_header()
  - hlua_http_rep_hdr()

Without this check, CRLF bytes in values passed through these
functions reach the wire unfiltered via h1_format_htx_hdr().

Add the same byte-scan loop to all three. For hlua_http_rep_hdr()
only the replacement value needs checking since existing header
values were already validated at ingress.

Signed-off-by: Mohammed sarfaraz [email protected]
---
Addresses the CRLF gap I reported privately. Three functions
missed by the original hlua_http_add_hdr() fix in 3.4-dev14.
Fixed the declaration ordering you flagged.

 src/hlua.c | 37 +++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/hlua.c b/src/hlua.c
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -6089,9 +6089,22 @@ __LJMP static int
hlua_applet_http_addheader(lua_State *L)
 {
  const char *name;
+ size_t name_len;
+ const char *value;
+ size_t value_len;
  int ret;
+ size_t i;

  MAY_LJMP(hlua_checkapplet_http(L, 1));
- name = MAY_LJMP(luaL_checkstring(L, 2));
- MAY_LJMP(luaL_checkstring(L, 3));
+ name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
+ value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
+
+ for (i = 0; i < name_len; i++) {
+   if (name[i] == 0 || name[i] == '\r' || name[i] == '\n')
+     WILL_LJMP(lua_error(L));
+ }
+ for (i = 0; i < value_len; i++) {
+   if (value[i] == 0 || value[i] == '\r' || value[i] == '\n')
+     WILL_LJMP(lua_error(L));
+ }

  /* Push in the stack the "response" entry. */

@@ -6564,8 +6577,16 @@ __LJMP static inline int hlua_http_rep_hdr(lua_State
*L, ...)
  size_t name_len;
  const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
  const char *reg = MAY_LJMP(luaL_checkstring(L, 3));
- const char *value = MAY_LJMP(luaL_checkstring(L, 4));
+ size_t value_len;
+ const char *value = MAY_LJMP(luaL_checklstring(L, 4, &value_len));
  struct htx *htx;
  struct my_regex *re;
+ size_t i;
+
+ for (i = 0; i < value_len; i++) {
+   if (value[i] == 0 || value[i] == '\r' || value[i] == '\n')
+     WILL_LJMP(lua_error(L));
+ }

  if (!(re = regex_comp(reg, 1, 1, NULL)))

@@ -8726,8 +8747,19 @@ __LJMP static int
hlua_txn_reply_add_header(lua_State *L)
 {
- const char *name = MAY_LJMP(luaL_checkstring(L, 2));
- const char *value = MAY_LJMP(luaL_checkstring(L, 3));
+ size_t name_len;
+ const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
+ size_t value_len;
+ const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
  int ret;
+ size_t i;
+
+ for (i = 0; i < name_len; i++) {
+   if (name[i] == 0 || name[i] == '\r' || name[i] == '\n')
+     WILL_LJMP(lua_error(L));
+ }
+ for (i = 0; i < value_len; i++) {
+   if (value[i] == 0 || value[i] == '\r' || value[i] == '\n')
+     WILL_LJMP(lua_error(L));
+ }

  /* First argument (self) must be a table */
  MAY_LJMP(luaL_checktype(L, 1, LUA_TTABLE));
--

Reply via email to