REBOL 3 Docs Guide Concepts Functions Datatypes Errors
  TOC < Back Next >   Updated: 3-Aug-2010 Edit History  

REBOL 3 Functions: secure

secure  policy

Set security policies (use SECURE help for more information).


policy [word! lit-word! block! unset!] - Set single or multiple policies (or HELP)

See also:

protect   load   import  



The secure function controls file, network, evaluation, and all other external access and related policies.

The function uses a simple dialect to specify security sandboxes and other options that allow or deny access. You can set different security levels and multiple sandboxes for networking and specific files and directories.

What can be controlled

The secure function gives you control over policies for:

filefile read, write, and directory creation and listing
netread and write access to the network interfaces
evallimit the number of evaluation cycles allowed (always quits)
memorylimit the amount of memory used (always quits)
securecontrol changes to security policies with secure
protectprotecting and hiding values with protect
debuguse of debug-related functions: trace and stack
envrgetting OS/shell environment variables with get-env
calllaunching external programs with call
browseopening the web browser with browse
extensionimporting extensions (may contain native code)

A list of these for your current release can always be obtained with the line:

secure query

(Which will also show their current policy settings.)


R3 ASK not available

In current releases of R3, the ASK option is not available. Use either THROW or QUIT instead.

The main argument

The argument to the secure function can be a word or a block.

worda general, top-level action such as setting global security levels to allow or deny all access. It can also be used to query the current security policies.
blockspecify separate security policies for files, directories, networking, extensions, debugging, and other features.

Argument as a word

If the argument is a word, it can be:

helpsummarize what policies can be set
queryshow current policies
allowremove all policies (no security)
nonethe same as allow (no security)
askrequire user permission on all policies
throwthrow an error for all violations
quitexit the program for all violations

For example, developers often type:

secure none

to disable all security when developing new programs. However, use this with care. Do not run (or do) any programs other than those that you trust.

Another example is:

secure quit

the program will quit immediately if any security violation occurs. Of course, this is a little extreme, and you won't get far. You'll want to specify a block for greater control. See the next section.

Argument as a block

To provide more detailed security, use a block:

secure [
    net quit
    file ask
    %./ allow

This block will:

As you can see, the security dialect consists of a block of paired values. The first value in the pair specifies what is being secured (file or net), and the second value specifies the level of security (allow, ask, throw, quit). The second value can also be a block to further specify read and write security.

Security policies

The security policies are:

allowremoves all READ and/or WRITE restrictions.
askrestricts immediate READ and/or WRITE access and prompts the user for each access attempt, requiring approval before the operation may be completed.
throwdenies READ and/or WRITE access, throwing an error when a restricted access attempt is made.
quitdenies READ and/or WRITE access and quits the script when restricted access is attempted.

For example, to allow all network access, but to quit on any file access:

secure [
    net allow ;allows any net access
    file quit ;any file access will cause the program to quit

If a block is used instead of a security level word, it can contain pairs of security levels and access types. This lets you specify a greater level of detail about the security you require.

Access types

The access types allowed are:

readcontrols read access.
writecontrols write, delete, and rename access.
executecontrols execute access.
allcontrols all access.

The pairs are processed in the order they appear, with later pairs modifying the effect of earlier pairs. This permits setting one type of access without explicitly setting all others. For example:

secure [
    net allow
    file [
        ask all
        allow read
        quit execute

The above sets the security level to ask for all operations except for reading (which is allowed).

This technique can also be used for individual files and directories. For example:

secure [
    net allow
    file quit
    %source/ [ask read]
    %object/ [allow all]

will prompt the user if an attempt is made to read the %source directory, but it will allow all operations on the %object directory. Otherwise, it uses the default (quit).

If no security access level is specified for either network or file access, it defaults to ASK. The current settings will not be modified if an error occurs parsing the security block argument.

Querying security

The secure function returns the prior security settings before the new settings were made. This is a block with the global network and file settings followed by file or directory settings. The word query can also be used to obtain the current security settings without modifying them:

probe secure query
[file allow net allow ...]

Using query, you can modify the current security level by querying the current settings, modifying them, then using the secure function to set the new values.

Securing security

Once you have your security policies set, it's a good idea to secure the secure function to prevent modifications. This is done in the same way as other policies.

For example:

secure [secure quit]

will cause your program to immediately quit if any other code tries to modify the security policies.

User confirmation

Note that lowering the security level produces a change security settings requestor to the user. The exception is when the REBOL session is running in quiet mode which will, instead, terminate the REBOL session. No request is generated when security levels are raised. Note that the security request includes an option to allow all access for the remainder of the scripts processing.

Controlling security at startup

To disable all security on startup, you can start REBOL with:

rebol -s args...

This policy allows open access for everything.

You can also use the --secure argument to specify any other default security level on startup.

Limiting evaluation (quota)

You can set secure to limit interpreter evaluation. This feature allows you to restrict server scripts (such as CGI) to a specific evaluation length to prevent runaway programs.

This example sets the limit to 50000 cycles, after which the program will immediately quit (the default behavior):

>> secure [eval 50000]
>> loop 100000 [next "test"]

Also, for debugging you can use the more detailed form of secure:

>> secure [eval [throw 50000]]
>> loop 100000 [next "test"]
** Access error: security violation: eval
** Where: loop
** Near: loop 100000 [next "test"]

You can continue your debugging at the console, but secure will trap again on the next evaluation sample. To disable that behavior:

>> secure [eval allow]

When tuning your program, to determine how many cycles your code needs, you can use:

>> stats/evals
== 50403

However, add to that number a good margin of error for special conditions within your code. In many cases you will want to make it ten or twenty times larger, just to be sure.

A few notes:

Limiting memory

You can set secure to limit the amount of memory allocated by your program. This feature allows you to restrict server scripts (such as CGI) to a specific memory usage to prevent runaway programs.

>> secure [memory 2'000'000]
>> strings: []
>> loop 100000 [append strings make string! 100'000]

This feature works the same way as the evaluation limit described above. Read that section for more details.

To determine how much memory your program has currently used:

>> stats
== 913616

The number is shown in bytes.

In addition, it should be noted that the memory limit applies to actual memory consumed. Due to automatic memory allocation (garbage collection) it is possible for a program to run a indefinite amount of time on a specific amount of memory.

The memory limit can be set only once and cannot be reset. However, for debugging after an eval THROW exception, you can use secure to disable the trap:

secure [memory allow]

  TOC < Back Next > - WIP Wiki Feedback Admin