Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tir is vulnerable to a hash collision DOS attack. #10

Open
pygy opened this issue Jan 16, 2012 · 1 comment
Open

Tir is vulnerable to a hash collision DOS attack. #10

pygy opened this issue Jan 16, 2012 · 1 comment

Comments

@pygy
Copy link

pygy commented Jan 16, 2012

In its current form, Tir is vulnerable to the attack described here.

Lua strings are interned. The predictability of the hashing algorithm allows to flood it with strings designed to produced collisions, which can slow down the server. You can take a server down a single client using this technique.

Since the url_parse and its POST equivalent parse everything, Tir is vulnerable to these attacks.

A solution would be to pass a table with the keys to extract from the request.

@pygy
Copy link
Author

pygy commented Jan 16, 2012

Here's a lpeg-based solution. It could easily be extended to URL-decode the text on the fly.

This is for GET requests. A similar solution could be writtten for POST.

require'lpeg'

local      C,      Cg,      Cmt,      Ct,      l,             P
    = lpeg.C, lpeg.Cg, lpeg.Cmt, lpeg.Ct, lpeg.locale(), lpeg.P

local end_value = P(-1)+"&"

local function Not (pat) return P(1) - pat end

local other_arg = l.alnum^1 * '=' * Not(end_value)^0 * end_value


function new_GET_args_parser (tbl) 
-- builds a custom lpeg pattern for the keys given. 
-- It may be possible to write a generic version and pass it params,
-- but I don't knoz how.
  local already_found, args

  for _,k in pairs(tbl) do
    local key = Cmt( C( P(k) ) * "=", function( _, _, k )
      assert( not already_found[k], 'Aaaargh' )
      already_found[k] = true
      -- print('key', k)
      return true
    end)
    local value = Cg( Not(end_value)^0, k) * end_value
    args = args and args+ key*value or key*value
  end
  args = args + other_arg
  return Cmt(P'', function() 
    already_found = {} return true -- allows to reuse the parser
  end) * Ct(args^0)
end

args_parser = new_GET_args_parser{'login', 'password'}

params = args_parser:match'login=Foo&password=Bar&other=ignored'
--> {login='Foo', password='Bar'}

extracter2 = new_GET_args_parser{'same'}
success, msg = pcall(lpeg.match, extracter2, 'same=key&same=well-tried')
--> false, Aaaaarghh


--[[----------------------------------------------------------------------------
             The Romantic WTF public license.
             --------------------------------
             a.k.a. version "<3" or simply v3




     Dear Zed,


     this short piece of code

                                      \ 
                                       '.,__
                                    \  /
                                     '/,__
                                     /
                                    /
                                   /
                has been          / released
           - - - - - - - -       - - - - - - - - 
         under  the  Romantic   WTF Public License.
        - - - - - - - - - - -',' - - - - - - - - - - 
        I hereby grant you an irrevocable license to
         - - - - - - - - - - - - - - - - - - - - -
           do what the gentle caress you want to
                - - - - - - - - - - - - - - -  
                    with   this   little
                       - - - - - - - - 
                        / snippet.
                       /  - - - -
                      /    Love,
                #    /       -
                ##  /  ##    ,
                #######     
                #####
                ###
                #




     -- Pierre-Yves.




]]------------------------------------------------------------------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant