Skip to content

Security Considerations

mauricelambert edited this page Sep 8, 2021 · 10 revisions

Security Considerations

An example of deployment for production is available here using NGINX and python virtual environment. This example respect all security considerations defined in this page.

Installations

Secure server and connection

  • I recommend using a HTTPS proxy on production environments (to protect against MiM attacks and protect the WebScripts Server).

Virtual environments

  • I recommend using a python virtual environment

Configurations

Interface

  • The WebScripts Server is not secure enough to be used directly on public interface (the proxy is very important). It should not use an interface other than 127.0.0.1.

HTTP headers

  • To protect your WEB clients (against XSS, CSRF, MiM and other threats) the configuration named security of the WebScripts Server sends HTTP headers. This configuration should be true. The headers are:
    • Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
    • Content-Security-Policy: default-src 'self'; form-action 'none'
    • X-Frame-Options: deny
    • X-XSS-Protection: 1; mode=block
    • X-Content-Type-Options: nosniff
    • Referrer-Policy: origin-when-cross-origin
    • Cache-Control: no-store
    • Clear-Site-Data: *
    • Feature-Policy: microphone 'none'; camera 'none'
    • Cross-Origin-Embedder-Policy: require-corp
    • Cross-Origin-Opener-Policy: same-origin
    • Cross-Origin-Resource-Policy: same-origin

Debugging

  • The debug configuration should be false, if set to true some code and configuration information will no longer be protected.

Bruteforce

  • auth_failures_to_blacklist and blacklist_time configuration should be set, to protect your passwords againts bruteforce attacks.

SMTP password

  • Do not use SMTP password (smtp_password != None) without StartTLS (smtp_starttls == True) or SSL (smtp_ssl == True).

Credentials

Change the password of the Admin user and the API key or use custom authentication script, database and system.

System

Files rigths and access

Some files and directories must be protected by the system, to avoid privilege escalation or other attacks. To protect your files, you need to change permissions on group and other (on Linux run this command: chmod -R 600 <directory or file>) and make sure the owner is the user who is launching the WebScript Server (on Linux run this command: chown -R <user>:<user> <directory or file>).

Files and directories that need protection:

  • data/: encrypted or hashed passwords are stored here, user permissions are also set here
  • config/: contains: server configurations (with security configurations), script configurations (with command to generate documentation) and loggers configurations (logging.config.fileConfig use eval function)
  • logs/: logs contains informations about configurations
  • scripts/: contains default scripts (admin scripts), scripts are executed by system user (or service user) and with their rights.

Delete files

  • ./export_Configuration.json is useful for debugging but it should be removed on production environments.

Remote Code Excution

You should never use a function to execute string as code on users inputs. A remote code execution is very dangerous.

  • I show some examples here but these are not exhaustive.
  • You can use other languages, read the documentation and pay attention to the functions exec, shell, eval, ....

Python

Some examples of Remote Code Execution on WebScripts custom module:

def page(environ, user, configuration, filename, arguments, inputs, *args, csrf_token=None):

    """Some examples of remote code executions are shown in this function, 
    you should never use this example or an equivalent."""
    
    eval(environ["HTTP_COMMAND"]) # Run the Command HTTP headers as python code
    exec(filename)                # Run the URL parameter as python code
    os.system(arguments[0])       # Run the first argument as a command line
    pickle.loads(inputs[0])       # De-serailize a pickle payload (Pickle contains weakness don't use it on user inputs)

    # Don't execute a (encrypted) cookie !

    return "200 OK", {}, "Response"

Some examples of Remote Code Execution on python script:

import pickle
import sys

eval(environ["HTTP_COMMAND"])        # Run the Command HTTP headers as python code
eval(sys.argv[1])                    # Run the first argument as python code
eval(input())                        # Run stdin as python code

exec(environ["HTTP_COMMAND"])        # Run the Command HTTP headers as python code
exec(sys.argv[1])                    # Run the first argument as python code
exec(input())                        # Run stdin as python code

os.system(environ["HTTP_COMMAND"])   # Run the Command HTTP headers as a command line
os.system(sys.argv[1])               # Run the first argument as a command line
os.system(input())                   # Run stdin as a command line

pickle.loads(environ["HTTP_COMMAND"])# De-serailize the Command HTTP headers as a pickle payload (Pickle contains weakness don't use it on user inputs)
pickle.loads(sys.argv[1])            # De-serailize the Command HTTP headers as a pickle payload (Pickle contains weakness don't use it on user inputs)
pickle.loads(input())                # De-serailize the Command HTTP headers as a pickle payload (Pickle contains weakness don't use it on user inputs)

Bash

Some examples of Remote Code Execution in bash script:

eval $1                           # Run the first argument as a command line
$1                                # Run the first argument as a command line

python3 -c "${1}"                 # Run the first argument as python code
php -r "${1}"                     # Run the first argument as php code

PHP

Some examples of Remote Code Execution in php script:

<?php 
  shell_exec($argv[1]);           // Run the first argument as a command line
  eval($argv[1]);                 // Run the first argument as php code
?>

WebScripts Web Security

Session

The WebScripts Server use HTTP Cookies for session. The session are generated with secrets.token_hex(64). The cookie is set with this HTTP header: Set-Cookie: SessionID=<user id>:<64 random byte hexadecimal>; Path=/; SameSite=Strict; Max-Age=3600; Secure; HttpOnly. Sessions can be used with only one IP address and expire after one hours.

CSRF token

The server uses CSRF tokens for POST requests when a session is used. The CSRF tokens are generated with b64encode(secrets.token_bytes(48)).decode(). Tokens can only be used once, for one session and they expire after 300 seconds (5 minutes).

Cautions:

  • BasicAuth and API keys should never be used with a web browser because CSRF protections is not enabled with these methods.
Clone this wiki locally