Security Configuration
Note: Security is not a feature, it's a process!
Manually Set The HSTS Header
If/once DRDB is configured for HTTPS access, it is strongly recommended to MANUALLY set the HTTPS Strict Transport Security (HSTS) header by creating a .htaccess file in the root directory of the project or include the required configuration in the Apache site config. The following code locks use of the site to HTTPS only, no downgrade is possible afterward anymore even when restarting the browser. Therefore, care is advisable!
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
</IfModule>
If you use a .htaccess file in the project folder, already think about how you will do updates in the future and how to preserve your .htaccess file and restore it afte the update!
For details see the OWASP Secure Header Project.
Headers Set By The Code
While the HSTS header has to be configured manually as not all projects might want to use it, the following security headers are already set by the by init.php for each page request. No configuration is necessary:
Cross Site Scripting Protection
The following headers ensure that Javascript and other parts of the front end are only loaded from the project server. Should an attacker still manage to insert JS code into the front end, it would still not be possible to exfiltrate data this way as inserted scripts would not be loaded even if the page contain external references.
// For details on the effect of the Content-Security-Policy header
// have a look at https://content-security-policy.com/
header("Content-Security-Policy: " .
"default-src 'self' data:; " .
"font-src 'self' data:; ".
"object-src 'none'; " .
"script-src 'self' 'unsafe-eval'; " .
"style-src 'self' 'unsafe-inline'; " .
"connect-src 'self'; " .
"worker-src 'self';" .
"frame-src 'self'");
// Note: Pages that include CKEDITOR-4 to edit fields require
// Javascript code to run inline. This is prevented by the
// CSP policy above. Therefore, the security requirement is
// relaxed for these pages:
// "script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
// The website must not be put into a frame. Protects against some forms
// of click-jacking.
header("X-Frame-Options: deny");
// Block rendering of the complete page if an XSS attack is detected. Note:
// It would be better to have script-src above not as "unsafe-inline"
// but since inline Javascript code is used, it's better than nothing
// to have this protection.
header("X-Xss-Protection: 1; mode=block");
// The browser must not try to change the MIME header by sniffing. This
// reduces the risk of running code embedded in up/downloaded files.
header("X-Content-Type-Options: nosniff");
// Always send the full referrer to this page unless there is a downgrade
// from https to http (which HSTS prevents if set by the admin)
header("Referrer-Policy: no-referrer-when-downgrade");
Other Security Considerations
In addition, the following security considerations are used in this project to protect against common exploits widely used by rouge actors on the Internet:
HTTP Username/Password
HTTP based authentication ensures that only users who know a valid username/password configuration can invoke any servers side code. Without a username/password, the web server itself denies access and hence, no server side project code is executed.
Cross Site Request Forgery Protection (CSRF)
To prevent CSRF via malicious links embedded in other pages, emails, etc., the server code checks HTTP URLs for the presence of a security token before data is written into the database. If the token is missing, an error message is returned to the browser and no data is changed in the database.
SQL Injection Protection
Another frequently used attack vector on the web is SQL injection. To prevent this kind of attack, care has been taken that all SQL queries that require user supplied information are executed as 'prepared statements'.
HTML Input Filtering
Data edited with the GUI editor is sent back in 'html' format to the server. The editor itself filters the HTML data before it is sent back and only allows a few HTML markup options. A malicious user, however, could bypass the editor and directly send malicious HTML data to be inserted into the database in a hand crafted query. As a consequence, the server side also filters user database input before it is written to the database or shown on the screen if protect_against_xss is set to true in config.php, which is the default. When set to true, database input is filtered with the htmlpurifier library.
Host Header Poisoning Protection
In general, the drdb server code only creates links relative to the document root. In other words, the domain name used for addressing the server is not used. In the future, however, it might be necessary to construct links that include the root, i.e the domain name as well. The domain name would then be taken from the HTTP HOST header. As the HOST header is generated by the client, care has to be taken at links are only constructed with valid domain names. Otherwise, an attacker could fake the HOST header to exfiltrate data that is contained in the link (e.g. session tokens, private information, etc.).
To counter this attack vector, config.php contains an array of valid domain names (or IP addresses for testing purposes) for the site. The host header is checked for every http operation and processing is stopped with an error message if the domain name used for the request is not properly configured in config.php.