1 - About PHPSandbox & PHPSandbox Toolkit

PHPSandbox

PHPSandbox Toolkit 2.0


Developed by: Corveda, LLC.Github

PHPSandbox is a PHP 5.4+ class designed to implement tightly-controlled and highly configurable code sandboxes in pure PHP code. It utilizes the PHP-Parser and FunctionParser libraries to parse the sandboxed code for violations of the sandbox configuration and to disassemble closures passed to the sandbox.

The PHPSandbox Toolkit is used to demonstrate the use of the PHPSandbox class, its various configuration options, creation of custom templates and for easy experimentation. The JSON templates it generates can also be imported directly into a PHPSandbox instance to allow for easy sharing of common configurations.

The PHPSandbox project is licensed under the open source BSD License. Click the "PHPSandbox License" tab below or see the LICENSE file that came with your distribution for more information.

Click the "Using PHPSandbox" tab below to continue.

2 - Using PHPSandbox

Including PHPSandbox

If you have downloaded PHPSandbox through composer, then the only thing you need to do to include all required PHPSandbox classes is:

require_once('vendor/autoload.php');

If you have a PSR-0 compliant autoloader, simply put the PHPSandbox folder under /src in your library folder and it will handle loading all PHPSandbox files for you. Otherwise, you must include all PHPSandbox files and its dependencies yourself.

Instantiating A PHPSandbox Instance

You have two methods of instantiating a PHPSandbox instance: the new keyword, or the static method PHPSandbox::create();

New Keyword
$sandbox = new \PHPSandbox\PHPSandbox();
Static Method
$sandbox = \PHPSandbox\PHPSandbox::create();

You can pass the following array arguments to either method to setup the sandbox:

  • $options — This is equivalent to using the setOptions() method.
  • $functions — This is equivalent to using the defineFuncs() method.
  • $variables — This is equivalent to using the defineVars() method.
  • $constants — This is equivalent to using the defineConsts() method.
  • $namespaces — This is equivalent to using the defineNamespaces() method.
  • $aliases — This is equivalent to using the defineAliases() method.
  • $superglobals — This is equivalent to using the defineSuperglobals() method.
  • $magic_constants — This is equivalent to using the defineMagicConsts() method.
  • $classes — This is equivalent to using the defineClasses() method.
  • $interfaces — This is equivalent to using the defineInterfaces() method.
  • $traits — This is equivalent to using the defineTraits() method.
Examples:
$sandbox = new \PHPSandbox\PHPSandbox($options,
                                     $functions,
                                     $variables,
                                     $constants,
                                     $namespaces,
                                     $aliases,
                                     $superglobals,
                                     $magic_constants,
                                     $classes,
                                     $interfaces,
                                     $traits);
$sandbox = \PHPSandbox\PHPSandbox::create($options,
                                          $functions,
                                          $variables,
                                          $constants,
                                          $namespaces,
                                          $aliases,
                                          $superglobals,
                                          $magic_constants,
                                          $classes,
                                          $interfaces,
                                          $traits);

Click the "Configuring PHPSandbox" tab below to continue.

3 - Configuring PHPSandbox

You have four main areas of configuration available in PHPSandbox: Options, Whitelists, Blacklists and Definitions.

Options

Options are configured in the PHPSandbox class by accessing the flag's public instance property (e.g. $sandbox->allow_functions = true; ) or through the setOption() and setOptions() instance methods.

Example:
$sandbox->setOption('allow_functions', false);

Option Descriptions

  • Validate Functions: — Default Value: true
    If this flag is set the sandbox will validate functions within the sandboxed code. If this flag is disabled then all function validation, including custom function validation, will be ignored.
  • Validate Variables: — Default Value: true
    If this flag is set the sandbox will validate variables within the sandboxed code. If this flag is disabled then all variable validation, including custom variable validation, will be ignored.
  • Validate Globals: — Default Value: true
    If this flag is set the sandbox will validate globals within the sandboxed code. If this flag is disabled then all global validation, including custom global validation, will be ignored.
  • Validate Superglobals: — Default Value: true
    If this flag is set the sandbox will validate superglobals within the sandboxed code. If this flag is disabled then all superglobal validation, including custom superglobal validation, will be ignored.
  • Validate Constants: — Default Value: true
    If this flag is set the sandbox will validate constants within the sandboxed code. If this flag is disabled then all constant validation, including custom constant validation, will be ignored.
  • Validate Magic Constants: — Default Value: true
    If this flag is set the sandbox will validate magic constants within the sandboxed code. If this flag is disabled then all magic constant validation, including custom magic constant validation, will be ignored.
  • Validate Namespaces: — Default Value: true
    If this flag is set the sandbox will validate namespaces within the sandboxed code. If this flag is disabled then all namespace validation, including custom namespace validation, will be ignored.
  • Validate Aliases (aka Use): — Default Value: true
    If this flag is set the sandbox will validate aliases within the sandboxed code. If this flag is disabled then all alias validation, including custom alias validation, will be ignored.
  • Validate Classes: — Default Value: true
    If this flag is set the sandbox will validate classes within the sandboxed code. If this flag is disabled then all class validation, including custom class validation, will be ignored.
  • Validate Interfaces: — Default Value: true
    If this flag is set the sandbox will validate interfaces within the sandboxed code. If this flag is disabled then all interface validation, including custom interface validation, will be ignored.
  • Validate Traits: — Default Value: true
    If this flag is set the sandbox will validate traits within the sandboxed code. If this flag is disabled then all trait validation, including custom trait validation, will be ignored.
  • Validate Keywords: — Default Value: true
    If this flag is set the sandbox will validate keywords within the sandboxed code. If this flag is disabled then all keyword validation, including custom keyword validation, will be ignored.
  • Validate Operators: — Default Value: true
    If this flag is set the sandbox will validate operators within the sandboxed code. If this flag is disabled then all operator validation, including custom operator validation, will be ignored.
  • Validate Primitives: — Default Value: true
    If this flag is set the sandbox will validate primitives within the sandboxed code. If this flag is disabled then all primitive validation, including custom primitive validation, will be ignored.
  • Validate Types: — Default Value: true
    If this flag is set the sandbox will validate types within the sandboxed code. If this flag is disabled then all type validation, including custom type validation, will be ignored.
  • Error Level: — Default Value: null
    If this option is set then sandbox will set the error level to this value before executing the sandboxed code.
  • Restore Error Level: — Default Value: true
    If this flag is set the sandbox will restore the error level after the sandboxed code has executed.
  • Convert Errors: — Default Value: false
    If this flag is set the sandbox will convert errors to exceptions during execution of the sandboxed code.
  • Capture Output: — Default Value: false
    If this flag is set the sandbox will return all output generated by the executed code.
  • Auto Whitelist Trusted Code: — Default Value: true
    If this flag is set the sandbox will automatically whitelist all functions, variables (if the allow variables flag is false and blacklisted variables have not been defined, unnecessary otherwise), constants, classes, interfaces, traits, namespaces, alias (or uses), and types defined, declared or executed in prepended and appended trusted code.
    NOTE: Because whitelists take precedence over blacklists, any blacklist type defined whose type was automatically whitelisted will have no effect.
  • Auto Whitelist Functions — Default Value: true
    If this flag is set the sandbox will automatically whitelist all functions defined by the sandboxed code if the allow functions flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use functions it has defined earlier in its execution scope.
  • Auto Whitelist Constants — Default Value: true
    If this flag is set the sandbox will automatically whitelist all constants defined by the sandboxed code if the allow constants flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use constants it has defined earlier in its execution scope.
  • Auto Whitelist Globals — Default Value: true
    If this flag is set the sandbox will automatically whitelist all globals defined by the sandboxed code if the allow globals flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use globals it has defined earlier in its execution scope.
  • Auto Whitelist Classes — Default Value: true
    If this flag is set the sandbox will automatically whitelist all classes defined by the sandboxed code if the allow classes flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use classes it has defined earlier in its execution scope.
  • Auto Whitelist Interfaces — Default Value: true
    If this flag is set the sandbox will automatically whitelist all interfaces defined by the sandboxed code if the allow interfaces flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use interfaces it has defined earlier in its execution scope.
  • Auto Whitelist Traits — Default Value: true
    If this flag is set the sandbox will automatically whitelist all traits defined by the sandboxed code if the allow traits flag is set. This will prevent exceptions being thrown if your sandboxed code attempts to use traits it has defined earlier in its execution scope.
  • Auto Define Variables — Default Value: true
    If this flag is set the sandbox will automatically define arguments passed via prepended, appended and sandboxed code closures, so these variables will be available to the sandboxed code scope.
  • Overwrite Defined Functions — Default Value: true
    If this flag is set the sandbox will overwrite PHP's internal get_defined_functions, get_defined_vars, get_defined_constants, get_declared_classes, get_declared_interfaces, and get_declared_traits functions so they report only values available to the sandboxed scope.
    NOTE: If you define your own functions for get_defined_functions, get_defined_vars, get_defined_constants, get_declared_classes, get_declared_interfaces, or get_declared_traits, the PHPSandbox instance will call them instead.
  • Overwrite Func_Get_Args — Default Value: true
    If this flag is set the sandbox will overwrite PHP's internal func_get_args, func_get_arg, and func_num_args so they report only arguments available to the sandboxed scope.
    NOTE: If you define your own functions for func_get_args, func_get_arg, or func_num_args the PHPSandbox instance will call them instead.
  • Allow Functions — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to declare functions via the function keyword.
    NOTE: The function keyword is still subject to the keyword whitelist and blacklist!
  • Allow Closures — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to create closures.
  • Allow Variables — Default Value: true
    If this flag is set the sandbox will allow the sandboxed code to create variables.
  • Allow Static Variables — Default Value: true
    If this flag is set the sandbox will allow the sandboxed code to create static variables.
  • Allow Objects — Default Value: true
    If this flag is set the sandbox will allow the sandboxed code to objects via the new keyword.
    NOTE: Object creation is still subject to type whitelists and blacklists, and the new keyword is still subject to the keyword whitelist and blacklist!
  • Allow Constants — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to define constants.
  • Allow Globals — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to define globals via the global keyword.
    NOTE: The global keyword is still subject to the keyword whitelist and blacklist!
  • Allow Namespaces — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to define namespaces.
    NOTE: Namespaces are defined outside the sandboxed code scope, and the namespace keyword is still subject to the keyword whitelist and blacklist!
  • Allow Aliases (aka Use) — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to define aliases (aka use.)
    NOTE: Aliases (aka use) are defined outside the sandboxed code scope, and the use keyword is still subject to the keyword whitelist and blacklist!
  • Allow Classes — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to declare classes.
    NOTE: The class keyword is still subject to the keyword whitelist and blacklist!
  • Allow Interfaces — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to declare interfaces.
    NOTE: The interface keyword is still subject to the keyword whitelist and blacklist!
  • Allow Traits — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to declare traits.
    NOTE: The trait keyword is still subject to the keyword whitelist and blacklist!
  • Allow Generators — Default Value: true
    If this flag is set the sandbox will allow the sandboxed code to create generators.
    NOTE: The yield keyword is still subject to the keyword whitelist and blacklist!
  • Allow Escaping — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to escape to HTML.
  • Allow Casting — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to cast variables to primitive types.
    NOTE: The casted primitive type is still subject to the primitive whitelist and blacklist!
  • Allow Error Suppressing — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to suppress errors via the @ prefix.
  • Allow References — Default Value: true
    If this flag is set the sandbox will allow the sandboxed code to assign by reference, and to define functions that return by reference if the allow functions flag is set.
  • Allow Backticks — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to shell execute strings quoted in backticks. NOTE: This requires the shell_exec to be either defined or allowed according to the function whitelist and blacklist! If shell_exec is a defined function then backticked strings will be passed to that function instead for execution.
  • Allow Halting — Default Value: false
    If this flag is set the sandbox will allow the sandboxed code to halt the PHP compiler.
    NOTE: The __halt_compiler keyword is still subject to the keyword whitelist and blacklist!

Whitelists & Blacklists

By default, an exception is thrown if any function, variable, global, superglobal, constant, magic constant, namespace, alias (aka use), class, interface, or type is executed in sandboxed code without being either defined or whitelisted, or if it has been blacklisted.

Keywords other than eval, die, exit, include, require, include_once, require_once, and __halt_compiler, are allowed even if they are not whitelisted as long as they are not in the blacklist and a keyword whitelist hasn't been defined.

Operators and primitives are allowed even if they are not whitelisted as long as they are not in the blacklist and a whitelist hasn't been defined.

Whitelist & Blacklist Precedence

Whitelists override their blacklist counterpart, therefore if a whitelist of functions has been defined and also a blacklist of functions, the blacklist will have no effect. Furthermore, definitions override both whitelists and blacklists, so that a defined function will always be allowed even if that function is not defined in a function whitelist or is in a function blacklist.

Whitelists are configured in the PHPSandbox class through the whitelist(), whitelistFunc(), whitelistVar(), etc. instance methods.

Detailed explanations of the whitelist instance methods can be found in the API documentation.

Blacklists are configured in the PHPSandbox class through the blacklist(), blacklistFunc(), blacklistVar(), etc. instance methods.

Detailed explanations of the blacklist instance methods can be found in the API documentation.

Definitions

Definitions are configured in the PHPSandbox class through the define(), defineFunc(), defineVar(), etc. instance methods. They are fully trusted, and override any respective whitelist or blacklist.

Detailed explanations of the definition instance methods can be found in the API documentation.

Custom Validators

Custom validators are configured in the PHPSandbox class through the setValidator(),8 setFuncValidator(), setVarValidator(), etc. instance methods. They are passed the name of the element and the PHPSandbox instance as arguments, and override any respective whitelist or blacklist.

Detailed explanations of the custom validator instance methods can be found in the API documentation.

Click the "Using PHPSandbox Toolkit" tab to continue.

4 - Using PHPSandbox Toolkit

WARNING: The PHPSandbox toolkit is NOT DESIGNED to be used on a publicly accessible server! It is for local testing in a private environment only! Use of The PHPSandbox toolkit on a public-facing server will likely lead to the rooting of your server!


The Toolbar

The far right of the toolkit screen is the toolbar. Links to the API documentation and this help dialog can be found here. This is also where sandbox templates, stored in the /toolkit/templates/ folder, can be selected and automatically loaded in the toolkit environment to test, or templates can be imported from your local filesystem.

More importantly, this is where the various sandbox configuration options can be selected, whitelists and blacklists can be enabled, and definitions for functions, superglobals, etc. can be defined. Click the "Configuring PHPSandbox Toolkit" tab below for more information.

Finally, the error level for the code to be executed can be set, and clicking "Run Code In Sandbox" will execute the toolkit environment and output the response.

The Code Editor

The top left of the toolkit screen is the code editor, which can be set to four possible modes via the Editor Mode menu above the code editor. These modes are:

  • Sandboxed Code — Code entered in this mode will be run within the sandbox environment, and will be subject to all validation checks determined by the sandbox configuration.
  • Setup Code — This is a special mode that allows the toolkit to run trusted code outside the sandbox, in the global scope of the script. This will allow for testing the sandbox against globally scoped functions, variables, etc. it is NOT subject to any validation checks, and can do anything a typical PHP script can!
  • Prepended Code — Code entered in this mode will be automatically trusted by the sandboxed and will run before the sandboxed code runs, in the same execution scope as the sandbox. If auto_whitelist is not enabled you will likely run into validation errors if the sandboxed code attempts to use classes or functions declared by this code.
  • Appended Code — Code entered in this mode is treated exactly the same as prepended code except it is run after the sandboxed code runs, and in the same execution scope.

The Output Box

When "Run Code In Sandbox" is clicked, any execution output is sent to this box, including error messages, uncaught exceptions and echoed output. Any values returned by the sandbox via the return keyword will also be shown as a var_dump() output in a line underneath the echoed output.

Finally, a line will be shown at the end of the output showing the amount of milliseconds spent preparing and executing the sandbox as well as the total time spent.

Click the "Using Templates" tab below to continue.

5 - Configuring PHPSandbox Toolkit

In the toolbar on the right side of the screen is a set of tabs that allow you to define all four areas of configuration for your sandbox.

Options

This tab shows a list of checkboxes correlating with the configuration options available in the PHPSandbox class. When a checkbox is checked its corresponding flag will be enabled, when unchecked its corresponding flag will be disabled.

Whitelists & Blacklists

This tab shows a dropdown menu of the type and a text input of the name of the item to add. As you type the name of the item to add an alert tooltip will show if the name you are typing is invalid for the selected type. Click the "+" button next to the text input to add the item to your whitelist or blacklist. You can then click on an item to remove it from the whitelist or blacklist.

NOTE: Whitelists will override their blacklist counterparts! (e.g. if you define a whitelisted function then the function blacklist will have no effect.)

Whitelist & Blacklist Types

  • Functions: The names of the functions (must be fully qualified if namespace is not defined) to whitelist or blackist.
  • Variables: The names of the variables (without the $ prefix) to whitelist or blackist.
  • Globals: The names of the globals (without the $ prefix) to whitelist or blackist.
  • Superglobals: The names of the superglobals (without the $ prefix) to whitelist or blackist.
  • Constants: The names of the constants to whitelist or blackist.
  • Magic Constants: The names of the magic constants to whitelist or blackist.
  • Namespaces: The names of the namespaces to whitelist or blackist.
  • Aliases (aka Use): The names of the namespace aliases (aka uses) to whitelist or blackist.
  • Classes: The names of the classes to whitelist or blackist.
  • Interfaces: The names of the interfaces to whitelist or blackist.
  • Traits: The names of the traits to whitelist or blackist.
  • Classes: The names of the classes to whitelist or blackist.
  • Keywords: The keywords to whitelist or blackist.
  • Operators: The operators to whitelist or blackist.
  • Primitives: The names of the primitives to whitelist or blackist.
  • Types: The names of the object types to whitelist or blackist.

Definitions

This tab shows a dropdown menu of the definition type. Click the "Define" button next to the dropdown menu to open the selected definition editor.

NOTE: Definitions are fully trusted, and override their whitelist and blacklist counterparts!

Definition Editors

Each of the definition editors open in their own window, and will show you a preview of what their result will be in your sandboxed code.

  • Function Editor:

    In this editor you will be able to specify the name of your defined function, a checkbox that indicates whether to pass the PHPSandbox instance as the first argument, a text field in which you can describe the arguments of your function, and a code editor in which to write your defined function code. If this code is malformed the execution of your sandbox will fail.

  • Variable Editor:

    In this editor you will be able to specify the name of your defined variable, the variable scalar value type, and the variable value.

  • Superglobal Editor:

    In this editor you will be able to specify the name of your defined superglobal, the superglobal key to set, the superglobal scalar value type, and the superglobal value.

    NOTE: You are able to define a callable function as the value of superglobal when configuring the PHPSandbox class from PHP through the defineSuperglobal() instance method. It will be passed the PHPSandbox instance as the first argument, and is fully trusted.

  • Constant Editor:

    In this editor you will be able to specify the name of your defined constant, the constant scalar value type, and the constant value.

  • Magic Constant Editor:

    In this editor you will be able to specify the name of your defined magic constant, the magic constant scalar value type, and the magic constant value.

    NOTE: You are able to define a callable function as the value of magic constant when configuring the PHPSandbox class from PHP through the defineMagicConst() instance method. It will be passed the PHPSandbox instance as the first argument, and is fully trusted.

  • Namespace Editor:

    In this editor you will be able to specify the name of your defined namespace.

  • Alias (aka Use) Editor:

    In this editor you will be able to specify the name of your defined namespace to use, and the alias to use. If alias is left blank the namespace will not use an alias.

  • Class Editor:

    In this editor you will be able to specify the name of the class to redefine, and the class to redefine it to use.

  • Interface Editor:

    In this editor you will be able to specify the name of the interface to redefine, and the interface to redefine it to use.

  • Trait Editor:

    In this editor you will be able to specify the name of the trait to redefine, and the trait to redefine it to use.

Click the "Using PHPSandbox Templates" tab below to continue.

6 - Using PHPSandbox Templates

The PHPSandbox toolkit comes with a special template feature that allows for you to open and save templates in a JSON format that the PHPSandbox class can easily import. This makes the sharing of sandboxed configurations incredibly easy as well as making it simple to extend existing templates for your own uses.

Loading Templates

To load a template, simply select a template from the dropdown list of available templates in the /toolkit/templates/ folder, or click "Import A Template" to load one from your local filesystem. Once a template is selected the toolkit environment will automatically load all the template options, whitelists, blacklists, definitions, and all setup, trusted and sandboxed code in their respective modes.

Saving Templates

If you wish to save your current sandbox configuration, simply click the "Save As New Template" button. You will be prompted for a name for your new template. Once you have named your template, you will be alerted to the success or failure of the operation, and your template will be stored in the /toolkit/templates/ folder. Once your template is saved it automatically becomes available in the dropdown templates menu for you to choose from. If you check the "Download Template?" checkbox you will be prompted to download your template and save it in a location of your choosing instead of saving it to the /toolkit/templates/ folder.

Importing Templates

If you wish to import a JSON template into a PHPSandbox instance within PHP, simply call the import() instance method and either pass the JSON string or JSON array to the method. You may also specify a bitmask of import options, by passing it as the second argument to the method.

Example:
$sandbox->import(file_get_contents('template.json'));

Import Options

These class constants are provided to simplify setting the bitmask option to pass to the import() method.

  • PHPSandbox::IMPORT_ALL — Import everything from the template. This is the default setting.
  • PHPSandbox::IMPORT_OPTIONS — Import the template options.
  • PHPSandbox::IMPORT_DEFINITIONS — Import the template definitions.
  • PHPSandbox::IMPORT_WHITELIST — Import the template whitelist.
  • PHPSandbox::IMPORT_BLACKLIST — Import the template blacklist.
  • PHPSandbox::IMPORT_TRUSTED_CODE — Import the template trusted prepended and appended code.
  • PHPSandbox::IMPORT_CODE — Import the template sandboxed code.
Example:
$sandbox->import(file_get_contents('template.json'),
                 PHPSandbox\PHPSandbox::IMPORT_OPTIONS);

Click the "PHPSandbox License" tab below to continue.

7 - PHPSandbox License

Copyright (c) 2013-2016 by Corveda, LLC.

Some rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * The names of the contributors may not be used to endorse or
      promote products derived from this software without specific
      prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

© Copyright 2013-2016 Corveda, LLC.phpsandbox.org