-
Notifications
You must be signed in to change notification settings - Fork 2
Security Considerations
An example of deployment for production is available here (wiki) using NGINX/Apache and python virtual environment. This example respect all security considerations defined in this page.
- I recommend using a HTTPS proxy or HTTPS Server with WSGI module on production environments (to protect against
MiM
attacks and protect the WebScripts Server). - Set
webproxy_number
to the number of HTTP proxy used, it's important for IP Spoofing protection.
- 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
:payment 'none'; geolocation 'none'; microphone 'none'; camera 'none'
-
Permissions-Policy
:microphone=(),camera=(),payment=(),geolocation=()
-
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 scripts, modules and configurations will no longer be protected.
-
auth_failures_to_blacklist
andblacklist_time
configuration should be set, to protect your passwords againts bruteforce attacks.
- In the production environment, you must be notified from your WebScripts server, configure SMTP (server, email addresses...) to receive notifications.
- Do not use SMTP password (
smtp_password != None
) without StartTLS (smtp_starttls == True
) or SSL (smtp_ssl == True
). If connection is not secure the password may be sniffed.
- You should set to
true
theno_password
configuration when you don't have a password in command lines arguments to logs command line.
- You should never set
stderr_content_type
totext/html
because it may be used for XSS (HTML and javascript injection). - Some script required the
text/html
ascontent_type
, i should use specific function for XSS protection. - Don't unescape HTML special characters in console scripts (when
content_type
istext/plain
), the javascript does it for you.
- You should set the
timeout
configuration.
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, RCE (Remote Code Execution) or other attacks.
- Scripts, executables and configurations should never have setuid, setgid, sticky bit or other special permissions.
- Scripts, executables and configurations should never have the write permissions and any permissions for group and other
- Use this command to protect your executables:
chmod 100 <file>
- Use this command to protect your scripts and configurations:
chmod 400 <file>
- Use this command to protect your executables:
- The directories of scripts, executables and configurations should always have root as owner and never write permissions for group and other
- Use this command to change the owner as root:
chown root:root <directory>
- Use this command to change permissions:
chmod 755 <directory>
- Use this command to change the owner as root:
To protect your files the read and write 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>
).
The files and directories that need protection:
-
./data/
,<lib path>/data/
: encrypted or hashed passwords are stored here, user permissions are also set here -
./logs/
,<lib path>/logs/
: logs contains informations about configurations
-
./export_Configuration.json
is useful for debugging but it should be removed on production environments.
The WebScripts is a tool that can help you administer other system (using SSH or WinRM scripts for example) but never the WebScripts Server system. If your scripts can change the system configurations, an attacker can also use it. The principle is as follow: the system protects your WebScripts server and the WebScripts server must not change the system.
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:
import os, pickle
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, sys, os
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
?>
You should never print a user entry (headers, arguments, inputs, URLs, content, username, cookie, ...), when the output content-type
is set to text/html
, without escape HTML scpecial characters.
import html
print(html.escape(user.name))
<?php
echo(htmlspecialchars(cookie));
?>
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 and there is an IP spoofing protection.
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.