Secure Coding Best Practices

Chapter 2 · Practice 5 of 5

Apply the same rule to templates, eval, LDAP and expression languages

From Injection: keep data out of commands

Why it matters

Any component that evaluates a string is an interpreter. OWASP's A05:2025 lists NoSQL, OS command, ORM, LDAP, and Expression Language or OGNL injection alongside SQL. A few that catch application developers:

InterpreterUnsafe patternSafe pattern
JavaScripteval, new Function, vm on inputparse data with JSON.parse, never run it
Pythoneval, exec on inputast.literal_eval for literals, or a real parser
Server-side templatesrendering a template string the user wroteuser text only as a variable inside a fixed template
LDAPbuilding filters with string formattingthe library's filter escaping functions
Regexnew RegExp(userInput)escape the input, or match with plain string methods

Server-side template injection is the one that surprises people. Rendering render_template_string(user_bio) in Jinja2 lets the bio run template expressions on the server. Templates must come from your code; user text goes in as data.

If you build a feature that genuinely runs user logic (formulas, rules, plugins), use a purpose-built, sandboxed expression language with no access to the host, not your own language's eval.