Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You never ever eval user input.


I thought this was super common knowledge, yet I reviewed a co-workers pull request the other day and found files filled with eval (easily 30 usages) as well as global state (treated and mutated as if it was thread local).

The most annoying part was that what they wanted to do didn’t even require eval and they refused to fix it even after I’d found a safe, non-eval way to do it.


This rule is true for Javascript and PHP too, yet it happened all the time. If Lisp relies heavily on eval, what specific protection measures does it employ?


Mainstream Lisp dialects do not "rely heavily" on eval. Its use is broadly discouraged in favor of other mechanisms like apply or macros.

Newbies sometimes learn about backquote before learning about apply, and when they need too pass a dynamic list of arguments to a function, they end up writing (eval `(fun 1 2 ,@args)) instead of (apply fun 1 2 args). Or doing some metaprogramming using (eval `(defun ...)) in the middle of a function, instead of making a function-defining macro.

In JavaScript and PHP, not to mention numerous other languages, eval is the only meta-programming you have. If you need to generate code, you end up using eval. Moreover, eval is textual. Textual code requires very careful escaping to avoid injection problems. Lisp's eval is AST-based, so it doesn't suffer from that.

If I have a user-data variable that holds untrusted user data and put it into an evaluated code template, as in (eval `(list ... (some-api ',user-data) ...), I can completely trust that user-data will not "go live". It's inserted under a quote, and that's that. There is no way that content can bypass the quote, no matter what object it is.




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

Search: