Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Writing an Nginx authentication module in Lua and Go (stavros.io)
90 points by stavros on Sept 8, 2013 | hide | past | favorite | 22 comments


Lua string comparison IS constant time (its always just a pointer comparison).

The timing attack (i.e. memcmp) would happen at the string interning step; which cannot be avoided: but as a lua_State persists longer than a single request, I'm unsure if a timing attack here is plausible.


I don't understand how you can compare two strings in constant time by doing a pointer comparison. Can you elaborate?


Does Lua do string interning? If it does then every string the same will be at the same memory location so you can do a simple address comparison.

edit: someone answered this in a sibling post with 'yes'.



Strings are interned in Lua which means identical strings have the same reference.


That's interesting... Would interning change the speed at which strings are generated, then?


Yes, strings are hashed at creation time.

This means strings can never be modified => a new one is created.

The down side is that string modification (including appending) in a loop is expensive.


Of course, languages like Java have StringBuffer objects. In Lua, if you are generating a string, and you know that it will need a lot of concatenations, you can use something like this:

    local string_buffer = {}
    while condition() do
      table.insert(string_buffer, getString())
    end
    local string = table.concat(string_buffer)


Maybe you could instantiate every string in a global radix tree?


Even then, how would you know which string the one you have is, unless you compare it?


I don't think I've ever heard "not enough documentation" as a complaint about Go. It's always seemed fantastic to me. But, I don't use Lua and Python much, so maybe they are even better.


I have that personal gripe about Go's documentation. Compared to C# and even PHP, Go's documentation is very short, often being a single line. For a beginner, it's difficult to learn Go this way.[1] Since taking it up, I've found it more helpful to buy books on Go, whereas I've been able to learn PHP and C# almost solely off the documentation. I still don't know much about Go and I feel Golang could do a much better job of documenting the language and making it accessible to beginners.

http://golang.org/pkg/io/#WriteString

vs

http://php.net/fwrite and http://msdn.microsoft.com/en-us/library/ms143376.aspx

[1] Edit: I'm aware that learning via documentation is probably not the right way to do it, but it's part of the learning process and thus, good documentation is important.


I was also surprised by this. Googling "Python <problem>" usually gets me a solution in the docs or a blog or SO, Go only got me a few relevant projects.


I imagine this is caused by Go being so young.


I don't know, I couldn't find much documentation on doing HTTP basic auth, and something else which I forget now. I did find a project that had a code listing, though, and used that.


I'm also getting a lot of value from nginx+lua. It's amazing how many problems can be solved quickly and easily without going to another level of coding. And with the ability to call C libraries from within lua, integrating with 3rd-party binary libs has been another way to avoid another layer.


> can be solved quickly and easily without going to another level of coding

We've recently done a refactor of a lot of complex load balancer rules into lua + redis. It really is a lot more maintainable.

While it is more maintainable, don't let the illusion fool you - the complexity is still there. The solution may be quicker, but you still had to write code for the solution. It's just different code - and in a different place - from where you'd otherwise put it.

In our case, it made sense - the logic was all already in the load balancer, it was just a lot more scattered. In other cases - such as splitting what is truly application logic between your LB and your application - it may lead to more headache than it's worth in exchange for a few ms of performance improvement.

(I'll likely be writing this thought up in more detail in the near future.)


Beside the authentication highlighted by the article, any other use cases/problems that can be solved by nginx+lua?


i have been using lua for request manipulation and logging.

here's a use case: you want to proxy request cookies from your application into 2 cookies (session/persistent), but you don't want to rewrite the legacy app. lua does a great job with request/response manipulation.


  Also, the if c1 ~= c2 branch is obviously not constant-time, but in practice it’s close enough that it won’t matter for our case. I’d prefer XORing the two strings together and seeing if the result is 0, but Lua doesn’t seem to include a bitwise XOR operator. If I’m wrong on this, I would appreciate a correction.
LuaJIT provides bitwise operators out of the box [1], and the creator also provides an extension for regular lua [2].

[1] http://luajit.org/extensions.html

[2] http://bitop.luajit.org/


Thanks, our nginx is linked with 5.2, it turns out, it's just my test box that had 5.1/didn't support bitwise. I'll change the code, thanks.


Well, I remember writting proxy modules for Apache and IIS in C/TCL back in the day (~ 2000).

So not much different.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: