Java Scripting – Dynamic Code Evaluation: Clever or Sloppy?

access-controljavajavascriptpermissionsscripting

I am trying to create a flexible ACL framework in Java for my application.

Many ACL frameworks are built on a whitelist of rules, where a rule is in the form of owner:action:resource. For example,

  • "JOHN can VIEW resource FOOBAR-1"
  • "MARY can VIEW resource FOOBAR-1"
  • "MARY can EDIT resource FOOBAR-1"

This is attractive because the rules can easily be serialized/persisted to a database. But my application has complex business logic. For example,

  • "All users in department 1 with over 5 years of seniority can VIEW resource FOOBAR-1, else not authorized"
  • "All users in department 2, if the date is after 03/15/2016, can VIEW resource FOOBAR-2, else not authorized"

Upon first thought, it would be a nightmare to devise a database schema that could handle infinitely complex rules such as these. Therefore, it seems as though I would need to "bake" them into the compiled application, evaluate them for each user, and then produce owner:action:resource rules as a result of the evaluation. I want to avoid baking the logic into the compiled application.

So, I was thinking of representing a rule in the form of predicate:action:resource, where the predicate is a boolean expression that determines whether a user is allowed. The predicate would be a string of a JavaScript expression that could be evaluated by Java's Rhino engine. For example,

  • return user.getDept() == 1 && user.seniority > 5;

In doing so, the predicates could easily be persisted to the database.

Is this clever? Is this sloppy? Is this gimmicky? Is this over-engineered? Is this safe (apparently, Java can sandbox the Rhino engine).

Best Answer

Piping dynamic data into an interpreter of your implementation language is usually a bad idea, since it escalates the potential for data corruption into a potential for malicious application takeover. In other words, you are going out of your way to create a code injection vulnerability.

Your problem can be better solved by a rules engine or maybe a domain-specific language (DSL). Look those concepts up, there is no need to reinvent the wheel.

Related Topic