dwww Home | Manual pages | Find package

Safe(3perl)             Perl Programmers Reference Guide            Safe(3perl)

NAME
       Safe - Compile and execute code in restricted compartments

SYNOPSIS
         use Safe;

         $compartment = new Safe;

         $compartment->permit(qw(time sort :browse));

         $result = $compartment->reval($unsafe_code);

DESCRIPTION
       The Safe extension module allows the creation of compartments in which
       perl code can be evaluated. Each compartment has

       a new namespace
               The  "root"  of  the  namespace  (i.e. "main::") is changed to a
               different package and code evaluated in the  compartment  cannot
               refer  to  variables  outside this namespace, even with run-time
               glob lookups and other tricks.

               Code which is compiled outside the  compartment  can  choose  to
               place variables into (or share variables with) the compartment's
               namespace  and  only that data will be visible to code evaluated
               in the compartment.

               By default, the only variables shared with compartments are  the
               "underscore"  variables  $_  and  @_ (and, technically, the less
               frequently used %_, the _ filehandle and so on). This is because
               otherwise perl operators which default to $_ will not  work  and
               neither  will  the  assignment  of arguments to @_ on subroutine
               entry.

       an operator mask
               Each compartment has an associated "operator mask". Recall  that
               perl  code is compiled into an internal format before execution.
               Evaluating perl code (e.g. via "eval" or "do 'file'") causes the
               code to be compiled into an internal format and  then,  provided
               there was no error in the compilation, executed.  Code evaluated
               in  a compartment compiles subject to the compartment's operator
               mask.  Attempting  to  evaluate  code  in  a  compartment  which
               contains  a  masked  operator will cause the compilation to fail
               with an error. The code will not be executed.

               The default operator mask for a newly created compartment is the
               ':default' optag.

               It is important that you read the  Opcode  module  documentation
               for  more  information,  especially  for detailed definitions of
               opnames, optags and opsets.

               Since it is only at the compilation stage that the operator mask
               applies, controlled access to potentially unsafe operations  can
               be  achieved by having a handle to a wrapper subroutine (written
               outside  the  compartment)  placed  into  the  compartment.  For
               example,

                   $cpt = new Safe;
                   sub wrapper {
                     # vet arguments and perform potentially unsafe operations
                   }
                   $cpt->share('&wrapper');

WARNING
       The  Safe  module does not implement an effective sandbox for evaluating
       untrusted code with the perl interpreter.

       Bugs in the perl  interpreter  that  could  be  abused  to  bypass  Safe
       restrictions  are  not treated as vulnerabilities. See perlsecpolicy for
       additional information.

       The  authors  make  no  warranty,  implied  or  otherwise,   about   the
       suitability of this software for safety or security purposes.

       The  authors  shall  not  in any case be liable for special, incidental,
       consequential, indirect or other similar damages arising from the use of
       this software.

       Your mileage will vary. If in any doubt do not use it.

METHODS
       To create a new compartment, use

           $cpt = new Safe;

       Optional argument is (NAMESPACE), where NAMESPACE is the root  namespace
       to  use  for the compartment (defaults to "Safe::Root0", incremented for
       each new compartment).

       Note that version 1.00 of the Safe module supported  a  second  optional
       parameter,  MASK.   That functionality has been withdrawn pending deeper
       consideration. Use the permit and deny methods described below.

       The following methods  can  then  be  used  on  the  compartment  object
       returned  by  the  above constructor. The object argument is implicit in
       each case.

   permit (OP, ...)
       Permit the listed operators to  be  used  when  compiling  code  in  the
       compartment (in addition to any operators already permitted).

       You can list opcodes by names, or use a tag name; see "Predefined Opcode
       Tags" in Opcode.

   permit_only (OP, ...)
       Permit  only  the listed operators to be used when compiling code in the
       compartment (no other operators are permitted).

   deny (OP, ...)
       Deny the listed operators from being used when  compiling  code  in  the
       compartment (other operators may still be permitted).

   deny_only (OP, ...)
       Deny  only  the  listed operators from being used when compiling code in
       the compartment (all other operators will be permitted, so you  probably
       don't want to use this method).

   trap (OP, ...), untrap (OP, ...)
       The   trap   and  untrap  methods  are  synonyms  for  deny  and  permit
       respectfully.

   share (NAME, ...)
       This shares the variable(s) in the argument list with  the  compartment.
       This  is  almost  identical  to  exporting  variables using the Exporter
       module.

       Each NAME must be the name of a non-lexical variable, typically with the
       leading type identifier included. A bareword is treated  as  a  function
       name.

       Examples  of  legal  names are '$foo' for a scalar, '@foo' for an array,
       '%foo' for a hash, '&foo' or 'foo' for a subroutine  and  '*foo'  for  a
       glob  (i.e.   all  symbol table entries associated with "foo", including
       scalar, array, hash, sub and filehandle).

       Each NAME is assumed to be in the calling package. See share_from for an
       alternative method (which "share" uses).

   share_from (PACKAGE, ARRAYREF)
       This method is similar to share() but allows you to explicitly name  the
       package  that symbols should be shared from. The symbol names (including
       type characters) are supplied as an array reference.

           $safe->share_from('main', [ '$foo', '%bar', 'func' ]);

       Names can include package names, which are  relative  to  the  specified
       PACKAGE.  So these two calls have the same effect:

           $safe->share_from('Scalar::Util', [ 'reftype' ]);
           $safe->share_from('main', [ 'Scalar::Util::reftype' ]);

   varglob (VARNAME)
       This  returns  a glob reference for the symbol table entry of VARNAME in
       the package of the compartment. VARNAME must be the name of  a  variable
       without any leading type marker. For example:

           ${$cpt->varglob('foo')} = "Hello world";

       has the same effect as:

           $cpt = new Safe 'Root';
           $Root::foo = "Hello world";

       but avoids the need to know $cpt's package name.

   reval (STRING, STRICT)
       This evaluates STRING as perl code inside the compartment.

       The  code  can  only see the compartment's namespace (as returned by the
       root method). The compartment's root package appears to be the  "main::"
       package to the code inside the compartment.

       Any  attempt  by  the  code  in  STRING  to use an operator which is not
       permitted by the compartment will cause an error  (at  run-time  of  the
       main  program but at compile-time for the code in STRING).  The error is
       of the form "'%s' trapped by operation mask...".

       If an operation is trapped in this way, then the code in STRING will not
       be executed. If such a trapped operation occurs or  any  other  compile-
       time  or return error, then $@ is set to the error message, just as with
       an eval().

       If there is no error, then the method returns  the  value  of  the  last
       expression  evaluated,  or  a return statement may be used, just as with
       subroutines and eval(). The context (list or scalar)  is  determined  by
       the caller as usual.

       If  the  return  value  of  reval() is (or contains) any code reference,
       those code references are wrapped to be themselves  executed  always  in
       the compartment. See "wrap_code_refs_within".

       The  formerly undocumented STRICT argument sets strictness: if true 'use
       strict;' is used, otherwise it uses 'no strict;'.  Note:  if  STRICT  is
       omitted 'no strict;' is the default.

       Some points to note:

       If  the  entereval  op  is permitted then the code can use eval "..." to
       'hide' code which might use denied ops. This  is  not  a  major  problem
       since  when  the code tries to execute the eval it will fail because the
       opmask is still in effect. However this technique  would  allow  clever,
       and  possibly  harmful,  code  to  'probe'  the  boundaries  of  what is
       possible.

       Any string eval which is executed by code executing in a compartment, or
       by code called from code executing in a compartment, will be  eval'd  in
       the namespace of the compartment. This is potentially a serious problem.

       Consider  a function foo() in package pkg compiled outside a compartment
       but shared with it. Assume the compartment has  a  root  package  called
       'Root'.  If  foo() contains an eval statement like eval '$foo = 1' then,
       normally, $pkg::foo will be set to 1.   If  foo()  is  called  from  the
       compartment  (by  whatever means) then instead of setting $pkg::foo, the
       eval will actually set $Root::pkg::foo.

       This can easily be demonstrated by using a module, such  as  the  Socket
       module,  which  uses eval "..." as part of an AUTOLOAD function. You can
       'use' the module outside  the  compartment  and  share  an  (autoloaded)
       function  with  the  compartment. If an autoload is triggered by code in
       the compartment, or by any code anywhere that is  called  by  any  means
       from  the  compartment,  then  the  eval in the Socket module's AUTOLOAD
       function happens in the namespace  of  the  compartment.  Any  variables
       created or used by the eval'd code are now under the control of the code
       in the compartment.

       A  similar  effect  applies to all runtime symbol lookups in code called
       from a compartment but not compiled within it.

   rdo (FILENAME)
       This evaluates the contents of file FILENAME inside the compartment.  It
       uses the same  rules  as  perl's  built-in  "do"  to  locate  the  file,
       poossibly using @INC.

       See above documentation on the reval method for further details.

   root (NAMESPACE)
       This  method  returns  the  name  of the package that is the root of the
       compartment's namespace.

       Note that this behaviour differs from version 1.00 of  the  Safe  module
       where  the  root  module  could  be  used  to change the namespace. That
       functionality has been withdrawn pending deeper consideration.

   mask (MASK)
       This is a get-or-set method for the compartment's operator mask.

       With no MASK argument present, it returns the current operator  mask  of
       the compartment.

       With  the  MASK  argument  present,  it  sets  the operator mask for the
       compartment (equivalent to calling the deny_only method).

   wrap_code_ref (CODEREF)
       Returns a reference to an anonymous subroutine that, when executed, will
       call CODEREF with the Safe compartment 'in  effect'.   In  other  words,
       with the package namespace adjusted and the opmask enabled.

       Note  that  the opmask doesn't affect the already compiled code, it only
       affects any further compilation that the already compiled code  may  try
       to perform.

       This  is  particularly  useful  when applied to code references returned
       from reval().

       (It also provides a kind of workaround for RT#60374:  "Safe.pm  sort  {}
       bug                with                -Dusethreads".                See
       <https://rt.perl.org/rt3//Public/Bug/Display.html?id=60374>   for   much
       more detail.)

   wrap_code_refs_within (...)
       Wraps  any  CODE references found within the arguments by replacing each
       with the result of calling "wrap_code_ref" on the  CODE  reference.  Any
       ARRAY or HASH references in the arguments are inspected recursively.

       Returns nothing.

RISKS
       This  section  is  just  an  outline  of  some  of  the things code in a
       compartment might do (intentionally or unintentionally) which  can  have
       an effect outside the compartment.

       Memory  Consuming all (or nearly all) available memory.

       CPU     Causing infinite loops etc.

       Snooping
               Copying  private  information out of your system. Even something
               as simple as your user name is of value to others.  Much  useful
               information could be gleaned from your environment variables for
               example.

       Signals Causing  signals (especially SIGFPE and SIGALARM) to affect your
               process.

               Setting up a signal handler will need to be carefully considered
               and controlled.  What mask is in effect when  a  signal  handler
               gets  called?   If a user can get an imported function to get an
               exception and call the user's signal handler, does  that  user's
               restricted  mask  get  re-instated before the handler is called?
               Does an imported handler get called with its  original  mask  or
               the user's one?

       State Changes
               Ops  such  as  chdir obviously effect the process as a whole and
               not just the code in the compartment. Ops such as rand and srand
               have a similar but more subtle effect.

AUTHOR
       Originally designed and implemented by Malcolm Beattie.

       Reworked to use the Opcode module and other changes added by Tim Bunce.

       Currently maintained by the Perl 5 Porters, <perl5-porters@perl.org>.

perl v5.40.1                       2026-08-30                       Safe(3perl)

Generated by dwww version 1.16 on Sat Oct 3 06:01:32 CEST 2026.