Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp data security/validation

This is really just a conceptual question for me at this point.

In Lisp, programs are data and data are programs. The REPL does exactly that - reads and then evaluates.

So how does one go about getting input from the user in a secure way? Obviously it's possible - I mean viaweb - now Yahoo!Stores is pretty secure, so how is it done?

like image 329
Wayne Werner Avatar asked Jun 08 '10 18:06

Wayne Werner


2 Answers

The REPL stands for Read Eval Print Loop.

(loop (print (eval (read))))

Above is only conceptual, the real REPL code is much more complicated (with error handling, debugging, ...).

You can read all kinds of data in Lisp without evaluating it. Evaluation is a separate step - independent from reading data.

There are all kinds of IO functions in Lisp. The most complex of the provided functions is usually READ, which reads s-expressions. There is an option in Common Lisp which allows evaluation during READ, but that can and should be turned off when reading data.

So, data in Lisp is not necessarily a program and even if data is a program, then Lisp can read the program as data - without evaluation. A REPL should only be used by a developer and should not be exposed to arbitrary users. For getting data from users one uses the normal IO functions, including functions like READ, which can read S-expressions, but does not evaluate them.

Here are a few things one should NOT do:

  • use READ to read arbitrary data. READ for examples allows one to read really large data - there is no limit.

  • evaluate during READ ('read eval'). This should be turned off.

  • read symbols from I/O and call their symbol functions

  • read cyclical data structures with READ, when your functions expect plain lists. Walking down a cyclical list can keep your program busy for a while.

  • not handle syntax errors during reading from data.

like image 116
Rainer Joswig Avatar answered Nov 12 '22 02:11

Rainer Joswig


You do it the way everyone else does it. You read a string of data from the stream, you parse it for your commands and parameters, you validate the commands and parameters, and you interpret the commands and parameters.

There's no magic here.

Simply put, what you DON'T do, is you don't expose your Lisp listener to an unvalidated, unsecure data source.

As was mentioned, the REPL is read - eval - print. @The Rook focused on eval (with reason), but do not discount READ. READ is a VERY powerful command in Common Lisp. The reader can evaluate code on its own, before you even GET to "eval".

Do NOT expose READ to anything you don't trust.

With enough work, you could make a custom package, limit scope of functions avaliable to that package, etc. etc. But, I think that's more work than simply writing a simple command parser myself and not worrying about some side effect that I missed.

like image 27
Will Hartung Avatar answered Nov 12 '22 01:11

Will Hartung