0

Having a function that generates Java code in a textual form (something similar to a template-engine, if you will), how would you sanitize user-provided fields to prevent code injection?

For instances, if I'm using a template similar to:

void function_${user_provided_function_name}() {
    // Do stuff
};

And the user provides as input (){System.exit(0);}; void function_dummy, the generated code would be:

void function_(){System.exit(0);}; void function_dummy() {
    // Do stuff
};

Even if I'm tempted just to not allow parenthesis (to prevent function calls), this seems highly fragile.

gcandal
  • 937
  • 8
  • 23
  • You could check that the provided String is [a valid identifier](http://stackoverflow.com/questions/12857340/naming-restrictions-of-variables-in-java). – assylias Mar 25 '17 at 09:21
  • 1
    I wouldn't. This approach to safely running user-supplied source code is misguided. You need to run it in a security sandbox such that only a whitelisted set of objects and methods are available. Look at http://stackoverflow.com/questions/1715036/how-do-i-create-a-java-sandbox – slim Mar 25 '17 at 09:55

1 Answers1

1

If you want to validate user input (as is) to make your code compilable, you have to make three checks to user_provided_function_name:

  • Lexical check: It must be a valid Java identifier: starts by letter, dollar $ or underline _, and then zero or more ocurrences of letter, dollar, underline or digit.
  • Sintactical check: It must not be a Java keyword: for, while, class, abstract, void, etc.
  • Semantical check: It must not be a method from java.lang.Object: toString, notify, getClass, etc (neither a not-overridable method from its superclass).

To accomplish the first rule, a regular expression could do it. A single Set would do for the other two rules.

But if you are willing even to modify the user input, you must first make it a valid Java identifier by deleting all the wrong characters according the first rule above, and then apply the other two rules.

Little Santi
  • 8,563
  • 2
  • 18
  • 46