[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LuaSocket: No way to protect against fuzzing attacks?
- From: Sam Roberts <vieuxtech@...>
- Date: Tue, 11 Oct 2011 12:36:38 -0700
On Tue, Oct 11, 2011 at 12:37 AM, HyperHacker <hyperhacker@gmail.com> wrote:
> To properly defend against this attack, the server needs to be able to either:
...
> 2) Read all data received in the next x seconds or the next n bytes,
> whichever comes first. (Bonus if "or until the next line break" is
> also an option.) The server can then buffer lines in the same manner
> as option 1.
If you :settimeout(t>0), then call receive(n/"*l"), and the timeout
occurs before n bytes/a line
has been read, you should get
nil, "timeout", partial
as the result.
> Unfortunately, LuaSocket doesn't seem to offer methods to do either of
> these, thus leaving every server using it vulnerable to such attacks.
I think luasocket provides the required functionality, though you
might not be able to take advantage
of some of its high-level buffering.
If you can reliably reproduce it not behaving as documented or
describe why it is impossible to use, I might have time to fix it (I'm
collecting patches at https://github.com/sam-github/luasocket).
luasocket's buffering is convenient, but not necessarily what you want
for a server. And a multiplexing
server will need to set the timeouts to 0 on all sockets, and to use select().
If you do that, you will need to buffer the data yourself, and
evaluate your conditions for determining when a peer is misbehaving.
You'll have to track time associated with each connection, and buffer
the data for each connection yourself.
Apache, as I recall, has a short timeout in which it requires seeing
some data, then a longer one to recv the complete head of the request.
Your buffering scheme can use the prefix argument to :receive(), if it
wishes, or use a table as a queue of segments, and concat them with
table.concat().
You might find the code below useful to explore some of these
behaviours, though it doesn't multiplex using select. As a start, try
calling it like:
./read-safely 4567 "*l" 4
with a client:
(sleep 10; echo -n helo; sleep 10; echo bye; sleep 10) | nc localhost 4567
Cheers,
Sam
------ read-safely -----
#!/usr/bin/env lua
require"socket"
if arg[1] == "-h" then
print("usage: "..arg[0].." port pattern timeout")
os.exit(1)
end
port = tonumber(arg[1]) or 0
pattern = arg[2] or 1024
timeout = arg[3] or 10
print("port", port, "pattern", pattern, "timeout", timeout)
serv = assert(socket.tcp())
assert(serv:setoption("reuseaddr", true))
assert(serv:bind("*", port))
assert(serv:listen())
print("at", serv:getsockname())
sock = assert(serv:accept())
print("from", sock:getpeername())
assert(sock:settimeout(timeout))
while true do
mesg, emsg, part = sock:receive(pattern)
if emsg then print("error", emsg) end
assert(mesg or emsg == "timeout", emsg)
if mesg then
print("recv mesg", #mesg, "<"..mesg..">")
elseif #part > 0 then
print("recv part", #part, "<"..part..">")
end
end