Securing MOOcode

Stunt inherits reasonable built-in support for executing untrusted code from LambdaMOO. However there are weaknesses. In particular, executable verbs (verbs with the x flag set) are callable from every other verb. There’s no notion of visibility (private or protected) in MOOcode. Programmers are forced to throw up ad hoc solutions, or worse, leave every verb wide open.

To rectify this shortcoming, Improvise provides a set of useful helpers to ensure that your callable verbs have an easy, consistent means of defining what can call them.

By convention, security helpers belong on the first line of verb code.  If a caller violates the constraints, the helper raises an E_PERM error.

By default, MOO verbs are public (using popular terminology). The helpers $protected() and $private() limit callers to verbs defined on ancestors and descendants of the target object (in the case of $protected()) or on the target object itself (in the case of $private()). Both helpers take an optional list of verb names. If provided, this list further constrains the caller to verbs with the specified names.

The helper $restrict_to_server() restricts the caller to the server itself. It is useful in verbs like do_login_command() and server_started(), both of which should never be called by user code.

The helper $restrict_to_builtin() works like $restrict_to_server() except that it is intended for verbs called from built-in commands like recycle() that are themselves called from user code. Like $protected() and $private(), the helper takes an optional list of names of built-in functions.

The helper $restrict_to_caller() restricts the calling verb to an arbitrary verb on an arbitrary object. It handles cases that the helpers above do not handle. It takes an object (the caller) and an optional list of verb names.

The helper $permit() restricts the calling verb by its permissions rather than its location. If the argument “wizard” or “programmer” is specified, the helper only allows the call if the calling verb is running with wizard permissions (“wizard”), or if the calling verb is running with the same permissions (has the same programmer) as the target verb (“programmer”). If the argument “owner” is specified, the helper only allows the call if the calling verb is running with the permissions of the owner of the object the target verb is defined on. This last case makes it possible to restrict callers to object owners in cases where an object is the parent of children belonging to players other than the creator of the parent itself (a common case for fertile objects).