-
Notifications
You must be signed in to change notification settings - Fork 2
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.
- I recommend using a HTTPS proxy on production environments (to protect against
MiM
attacks and protect the WebScripts Server).
- I recommend using a python virtual environment
- 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
.
- To protect your WEB clients (against
XSS
,CSRF
,MiM
and other threats) the configuration namedsecurity
of the WebScripts Server sends HTTP headers. This configuration should betrue
. 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
-
- The
debug
configuration should befalse
, if set totrue
some code and configuration information will no longer be protected.
-
auth_failures_to_blacklist
andblacklist_time
configuration should be set, to protect your passwords againts bruteforce attacks.
- Do not use SMTP password (
smtp_password != None
) without StartTLS (smtp_starttls == True
) or SSL (smtp_ssl == True
).
Change the password of the Admin
user and the API key or use custom authentication script, database and system.
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
useeval
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.
-
./export_Configuration.json
is useful for debugging but it should be removed on production environments.
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
, ....
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)
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
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
?>
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.
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.