Security implications of Clojure keyword creation from user data?

clojure, keyword, security

Solution

Per http://clojure.org/reader, there are rules for which characters are valid in symbols and keywords. (For now, alphanumeric characters and `*`, `+`, `!`, `-`, `_`, and `?`.) You should never create a symbol containing any other characters. However, right now, these rules are completely unenforced by the compiler.

At best you could end up with invalid keywords. At worst you could end up with evil/dangerous ones, as Michał Marczyk said. Keep in mind that `#=()` can be used to run arbitrary code at read-time, so you don't even have to evaluate a string for bad things to happen, you only have to read it.

(keyword "foo #=(steal-passwords-and-delete-hard-drive)")

(See `(doc *read-eval*)` for how to disable this behavior, but read-eval is enabled by default.)

I think general rules for sanitizing user input apply here. Define precisely what you want to allow, and disallow everything else by default. Maybe allow something like the regex `#"[a-zA-Z0-9*+!-_?]+"`, with possibly other alphanumerics depending on the language you speak.

Problem

Suppose that I take a user-supplied string, userstring, and call (keyword userstring) on it. Are there any security concerns about doing this? And if so, what would be the best way to mitigate them?

Original source