[Haskell-cafe] More on the random idea
Donald Bruce Stewart
dons at cse.unsw.edu.au
Sat May 26 06:07:10 EDT 2007
> Since the online lambdabot still doesn't seem to want to talk to me,
> I've been thinking about how I might rectify the situation...
> Apparently GHC has a flag that makes it execute a Haskell expression
> directly. For example,
> C:\> ghc -e "map (2*) [1,2,3]"
> Now, if I could just figure out how to make a web server call GHC... I'm
> Oh, but there is the *minor* detail that I am literally allowing
> unauthenticated users to perform arbitrary code execution. For example,
> C:\> ghc -e "writeFile \"Test.txt\" \"Hi mum!\""
> (Generates a file on my harddrive "Test.txt" containing the text "Hi mum!".)
> AFAIK, Lambdabot dissalows any expression that performs IO. In Haskell,
> this is beautifully easy: reject any expression having an IO type. And
> it seems that GHC accepts not just an *expression*, but a *command*. In
> particular, this works:
> C:\> ghc -e ":t writeFile \"Test.txt\" \"Hi mum!\""
> writeFile "Test.txt" "Hi mum!" :: IO ()
> However, when you consider that the result type could be "IO ()" or "IO
> String" or "IO [Either (Maybe Int, (String, Bool)) [Either (Int ->
> String) (Complex Integer)]]", and the expression itself may well contain
> the "::" sequence... you see we have a nontrivial parsing task here!
> (Get the parsing wrong and somebody might be able to do Evil Things to
> the box.)
Don't use parsing for security, use the type checker. By using 'show',
you can write an instance for IO a that renders all IO harmless. Then
just wrap your user's arbitrary expression in 'show.
This is what lambdabot does. So we have:
Safe, pure expressions, just shown:
20:04 dons> > map (^2) [1..]
20:04 lambdabot> [1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484...
IO, shown, by a Show instance that renders it harmless:
20:04 dons> > readFile "/etc/passwd"
20:04 lambdabot> <IO [Char]>
And we can then play some clever tricks for functions:
20:04 dons> > ord
20:04 lambdabot> <Char -> Int>
> The other possibility is to somehow run GHC under a user context that
> doesn't *have* write access to anything on the filesystem. That way
> there is no margin for error.
Well, that's overkill, when you have a pure language, with a strong type
system that tags IO. :-)
> This leaves only the problem of how to make a web server call GHC. I can
> think of a number of possibilities.
> - Write my own HTTP server from scratch. (Not keen...)
> - Configure Apache to do it. (Is that physically possible?)
> - Use Apache and some bizzare Perl scripting to do the actual call.
> (Assuming *that* is possible.)
> - Use Apache and some Perl scripts to write the data to a text file, and
> write a small Haskell program to poll the filesystem waiting for request
> files to appear, run then though GHC, and put the result back into a
> file. Write another Perl script to slurp up the result and send it back
> to the caller.
> - Doesn't Java have a free HTTP server implementation? Maybe I could use
> - ...others?
You could also just use 'runplugs' from lambdabot, which also handles
non-terminating programs :-)
> (I'm not sure why this should be, but it seems that Don has made several
> replies to my emails that didn't show up in my inbox, and only show up
> on the list archives. Oh well, anyway...)
> I lurk on the POV-Ray NNTP server, and we recently had quite a
> discussion about Haskell. I'd *love* to be able to say to people "hey,
> you don't even need to bother working out how to install GHC, just CLICK
> THIS LINK and you can play with Haskell instantly!" But at the moment
> I'm not entirely sure how to set this up. Ideas?
Yeah, an online solution to this would be good. lambdabot gives us a
start, lambdaweb goes further. But the last 5% need more work.
More information about the Haskell-Cafe