Composr Tutorial: Security

Written by Chris Graham
This tutorial details and explains Composr's security features and provides a lot of general advice for maintaining security.

The developers have put a lot of effort into making Composr very secure. We:
  • perform the practices of producing secure and robust code
  • scan and scrutinise security hot-spots (such as database queries)
  • design the Composr architecture to abstract away common security hot-spots wherever possible
  • have designed Composr to actively detect and log possible security issues via defining and enforcing tight interfaces into Composr, and consistency rules
  • develop on our own version of PHP that can detect XSS security holes and potential errors via automatic type-conversion problems
If you find a flaw in Composr's security please contact us so that we may have time to fix the problem before hackers get a chance to exploit it on innocent users.


Overview of security features in Composr

Here is a list of the main security features in Composr…

Passwords:
  • Visual representation of password quality
  • Password complexity rules
  • Password expiry and prevention of re-use
  • Password hashing with configurable ratchet (even if hackers steal the database they won't have actual passwords; controlled via "Cryptographic ratchet" configuration option)
  • Configurable cryptographic complexity ratchet to protect against brute-force techniques to convert hashes back into passwords
  • Temporary passwords, so that staff may set up accounts without needing to know the final password that will be used

Login restrictions:
  • Approval process when a member accesses via a new IP address (a form of two-factor authentication) [optional, per-usergroup]
  • IP address banning, including wildcard banning
  • Integrated blocks/escalation-process for IP addresses identified as malicious, using various third party services
  • Login sessions are locked to IP address, so that if a hacker steals a session ID they cannot normally use it
  • Configurable session expiry time (shorter = reduced potential for a hacker using a stolen session ID, longer = more convenience)
  • Ability to prevent privileged actions being performed by users who were automatically logged in via cookies (it forces them to confirm their login); ability to reverse ("concede") a confirmed login to help improve security around insecure workstations that are kept logged in
  • Approval of new members (optional)

Auditing systems:
  • Audit logging of almost all administrative actions
  • Logging of all user actions and IP address history
  • Sophisticated tools to analyse the above
  • Logging of failed logins
  • Hack-attack detection / logging / banning (described in further detail in this tutorial)
  • E-mails to members when their username, e-mail address (e-mail is sent to the old address), password, or phone number is changed

Framework security:
  • CSRF-attack prevention (Cross-Site-Request-Forgery) via referrer checking and form security tokens
  • Click-jacking prevention via CSP implementation
  • Parent reloading prevention via rel="noopener"
  • Documented policies for meeting secure programming standards (in our Code Book and our standards checklist spreadsheet)
  • Scanning techniques to automatically enforce most of our security standards, such as:
    • automatic monitoring and scanning of database queries to confirm they were composed in a secure way
    • disabling of common attack vectors by default such as 'UNION' database queries (only enabling them when necessary)
    • automatic input sanitisation in standardised input-access APIs
  • Configurable levels of HTML filtering, to prevent XSS attacks (Cross-Site-Scripting attacks), including full CSP implementation
  • Our own version of PHP used during development – featuring strict types and a detector for XSS security holes
  • Our Code Quality Checker tool has the ability to scan for security hotspots in the code (areas that need careful quality reviews)
  • "Kid-gloves modes" that automatically impose restrictions and filters on third-party code unless the programmers of them explicitly declare that they understand key security issues
  • Prevention of attacks carried out by the upload of malicious files, via various forms of automatic filtering. Per-directory disabling of PHP code as an extra level of security (Apache-only)
  • Prevention of access-control-bypass via manually downloading privileged files via URL via automatic filename obfuscation
  • Prevention of directory listing attacks in deep directories, via empty index.html files
  • Disabling of common insecure PHP features such as "allow URL fopen"
  • Automatic enabling of a number of Suhosin features designed to improve security, and coding standards that allow our code to work with them. Suhosin is an unofficial extension to PHP that adds extra security constraints
  • Prevention of "jumping-in" attacks against deep framework code via a secure code modularisation standard
  • Automatic imposition of limits, to prevent exploitation of bugs leading to the draining of computational resources
  • Following of many other security best practices, such as those espoused by WASP (for example, we protect against session fixation)

Other features:
  • Privileges and access permissions to restrict privileged functionality
  • Validation process for content submission
  • Rootkit detector system (maintenance status) (manually generate security signatures representing the state of the website, to compare to previous ones)
  • Many spam-prevention systems (outside the scope of this tutorial)
  • Automatic download of new web application firewall rules (for emergency patching)
  • Many moderation systems such as warnings, probations, and bans (outside the scope of this tutorial)

We are always coming up with new ideas for security. If you want us to keep going further then you can consider sponsoring new ideas posted on our development tracker.

Advice for webhosting

Your ideal webhost should:
  • Ensure the server is configured well for SSL (it should not allow degrading of encryption ciphers that are known as insecure). There are tools to help you scan.
  • Keep the server patched with secure versions of software
  • Have suEXEC or equivalent (if it is shared hosting), and PHP open_basedir. This is described below under "Optimum server environment for shared hosting". It is much better to actually have a VPS, Cloud IaaS hosting, or a dedicated server.
  • Not install unnecessary server services (as this increases the likelihood of an attack – it just takes one system-level vulnerability to take a server down)

You should consider:
  • Enabling SSL for the whole site (soon web browsers are going to be giving out warnings when you browse a website that is not fully running SSL)
  • Using Cloudflare for the free DDOS protection, or a more advanced service such as SiteLock or Sucuri

You should be wary about:
  • PHP "disable_functions" (this increases security by disabling arbitrary parts of PHP – this should only be done by consent with a programmer, to confirm those parts that were decided to be disabled are not actually necessary for functionality)
  • ModSecurity (Composr does have inbuilt features, as described above – and ModSecurity rules have a tendency to block legitimate administrative requests, such as use of Commandr or theme editing)
  • Suhosin/SuPHP (actually Suhosin/SuPHP is okay if you have control over its settings or know for sure that nobody is going to set anything that is too restrictive)

The best way to ensure your hosting is secure is to choose a webhost that you're confident in and/or a server management team who will carry out their system administration tasks diligently. There are a thousand ways a bad host or a bad team could make things insecure, but if they stick to default/careful software configurations and industry-standard practices then usually things will be in decent shape.

Optimum server environment for shared hosting (advanced)

It is an unfortunate fact that shared webhosting environments are almost always very insecure, as different users with hosting accounts on the web server may interfere with your files on a number of levels. In addition, by extension, if one of the other accounts on the server becomes compromised, your files could also be.

This section is highly complex, the summary to it all is that if you care about security a lot, don't use shared webhosting. The risk of the host, or you, getting it wrong, is very high.

If you run a website with particularly privileged information, or security is critical for other reasons, we highly advise you operate your web server from a dedicated server(s).

The main issue with shared hosting, is that, unless either:
  1. the web environment for hosting accounts is restricted to being only PHP with open_basedir enabled
  2. or, the server is set to run web scripts on different hosting accounts using the account holder usernames (suEXEC)
…then every web-server-created/writable file, and your database, is fully writable to by any other account holder.

suEXEC means that PHP scripts load up under the user of your own hosting account, and are constrained as such too. open_basedir restricts PHP to only operate within the directory of the hosting account, although it has performance problems. We recommend suEXEC with open_basedir configured also (for extra protection).

If webhosts allow shell access or non-PHP scripts then they should either deploy "jail shell" or ensure home directories are not world-readable because the open_basedir protection would be bypassed. These are further mitigations against account-vs-account tampering. Without this you'd have to worry about read permissions on files such as the _config.php file. So actually ideally you would have suEXEC, open_basedir, jail shell, and well configured home directory security.

More information about suEXEC is provided in the Webhosting for Composr tutorial.

Is suEXEC really safe?

You may find claims that suEXEC is a security concern.
The fact that suEXEC is now extremely common-place, without disaster having unfolded, disputes this quite well.

However, here's my more serious rebuttal…

He makes 3 points:
  1. The web server has to run with root permissions if it is to initiate web requests under the appropriate permissions. That's a risk in any event.
  2. You could set it up wrong and cause terrible problems. The suEXEC authors themselves warn of that.
  3. With suEXEC, scripts on an account have full control of the files on that account.

Regarding point 1, that's true, but only if there's a vulnerability found in Apache. Lots of things already run under a server with root privileges, so could have vulnerabilities also. i.e. this doesn't change the state of affairs that much. If there's a vulnerability, Apache will be patched and hosts will update.

Regarding point 2, I disagree. Hosting control panels come with a whole configuration for the services on the server. This isn't a case of every host manually configuring suEXEC, it's a case of the control panels knowing how to do it right and automatically rolling it out correctly for all users of those webhosting control panels.

Regarding point 3, I agree and disagree. He is correct to say there's a risk, but it's one of these "you can't avoid crossing the street" kind of scenarios. Modern web systems should be able to have deep control over their own files. For example, if you're installing or uninstalling addons in Composr, you don't want to have to manually handle everything, you want Composr to be able to self manage itself. Sometimes we just have to accept that to have good progressive functionality, we need to take certain risks, and then mitigate those risks.

Testing the security of a webhost

If you don't have a well-configured server, anybody with an account on the server can mess with anybody else with your account. In other words, if someone wants to hack your site, they just need to sign up with the same webhost (assuming they only have one server, and many unfortunately do), or they just need to find any one single site on the server that is hackable (it's easy to find sites on the same server, and people are often running stuff that is very easy to hack).

There's a simple way you can test the security without needing a full understanding of LAMP (Linux/Apache/MySQL/PHP) configurations. Here's a very simple script that you can upload (just save it as filesystem_browser.php):

Code (PHP)

<?php
if (!isset($_GET['dir'])) {
    $_GET['dir']='.';
}

if (is_dir($_GET['dir'])) {
    $h=opendir($_GET['dir']);
    if (!$h) {
        return;
    }

    while ($f=readdir($h)) {
        $found[]=$f;
    }
    sort($found);

    foreach ($found as $f) {
        echo '<a href="?dir='.
        $_GET['dir'].'/'.$f.'">'.$f.'</a><br />';
    }

    closedir($h);
} else {
    echo file_get_contents($_GET['dir']);
}
 

Load up the script by URL, and see if it lets you browse up the filesystem and then into other hosting accounts.

The script just tests read access. Depending on the server configuration, you might have access to write any file in another user's directory that has been given '666' permission or was originally created by the web server itself. Even if you don't have write permission though, you can probe into the configuration file for the PHP software they have installed and find MySQL access details, and then you can easily install phpMyAdmin on your hosting account and give yourself full read/write access to their database.

It's scary stuff: you probably never imagined security for a website could be so poor. So, please make sure you check your host is competent before putting too much faith in them.

I am not exposing any security holes in LAMP software here, but what I am exposing is how inept many webhosts are. Hosting is cheap, they often cannot afford to hire people who have a good understanding of security for a website, so be wary.

Advice for website maintenance

Advice for website maintenance:
  • Never connect using FTP (passwords are sent in plain text, so anyone with administrative infrastructure access between you and the server can read them)
  • Never use IMAP or POP3 e-mail unless you have SSL turned on for it (again, passwords are sent in plain text)
  • Use secure passwords, according to best practices
  • Don't re-use passwords across different services (if one is found you don't want everything to tumble like a house of cards)
  • Keep your own computers secure and patched (if your own machine becomes infected and you are being targeted actively by a hacker then anything you do becomes exploitable)
  • Remove the maintenance password from the _config.php, only put it back when you need access to Composr's low-level configuration/upgrade system

Some philosophy

There's always a trade-off between security and convenience. Before inconveniencing yourself too much bear in mind that for very high-grade security you need:
  • Regular user training
  • Regular audits of user behaviour
  • Regular monitoring
  • Regular reading of logs
  • Immediate system patching whenever security updates come out
  • High-availability of system administrators to solve any problems rushed security updates could cause
  • Secure storage of all backups
  • High-quality processes for all system management tasks

Any weak point can and will be exploited by a persistent hacker who has a strong motivation. For example, even if your software security is perfect, they can likely use a confidence trick ("social engineering") to persuade one of your users to give up their passwords. Or, anyone with the resources can do a DDOS attack against you, which is similar to a sit-in protest at a real-world organisation.

Also bear in mind there is basically no protection from government agencies who have a reason to target you or one of your users. Secret court orders may result in system implants that you have no way of detecting.

The point I am trying to convey is that you should decide on an appropriate level of security for your particular organisational needs, and ensure that everything necessary for that level is maintained. If you or your users are touching on anything that security services could be interested in, or have a motivated enemy, you'll be exposed regardless of what you do.

Security logs

Composr defines a large number of 'hack-attack' situations, and in case of any of these situations occurring it will: stop the execution; send out an e-mail detailing the attack; and log the attack in the security log. These situations are varied, but the most common is when input is found that does not match input constraints (for example, a script parameter which should be a number is not).

Security logs can be reached from:
Admin Zone > Audit > Security logging

Image

A security alert for a real hack-attempt

A security alert for a real hack-attempt

(Click to enlarge)

If you get alerts that suggest someone is actively trying to hack into your website, it is advisable to ban their IP address at the web server level as soon as humanely possible (unless they have already been automatically banned). This is just a precaution, but it is possible (although unlikely) that a skilled hacker who is referring to Composr source code has only accidentally triggered an alert, and may have found an alternative vulnerability in your site already, or may find one soon. Of course we know of no such vulnerabilities, and we do in fact consider it unlikely that a direct vulnerability will be found in Composr, but it is always best to be cautious with regards security. You should also be aware that a hacker may change their IP address, simply by changing their Internet connection, or working through proxies: you may decide in this case of a serious attack, to consult authorities, passing them the IP address of the offender and the hack-attack e-mail.

Most security logs are accidental (caused by mistyped URLs, or buggy software) or are caused by bots. The screen-shot shows a typical hack-attack by a bot that crawls the web looking for vulnerable scripts: in this case, the bot is trying to use a parameter of the Composr poll voting form to send an e-mail, on the basis that by trying to abuse every form it finds, it will eventually find one that does work as a spam relay: it would then latch on to this and use the victim website as a mass spam relay, for as long as it can. In this case it hit a Composr site, so was logged.

Alert types

The following types of alert (hack-attack codenames) are defined:
  • DODGY_GET_HACK, A suspicious URL was given that includes characters looking like they may be there to do dodgy things. As URLs are generally clean of symbols, it is safe for Composr to detect dangerous looking ones, such as file system paths, new line characters, and HTML symbols
  • EVIL_POSTED_FORM_HACK, This may be due to a social engineering attack, where a logged in administrator has been tricked into filling in a form targeted to delete something from the website (CSRF)
  • VOTE_CHEAT, The user tried to vote outside the allowed range of options (e.g. 11 or -2). I can think of no way this could be done accidentally
  • SCRIPT_UPLOAD_HACK, The user tried to upload a PHP script. This may well be innocent (if they are uploading a saved web-page with .php in the URL for example, or if they are uploading a script they expect people to be able to download in raw form)
  • ASCII_ENTITY_URL_HACK, The user introduced HTML into a Comcode HTML tag that used ASCII-encoded entities. This is likely to be innocent, but is blocked because it can be used to trick JavaScript filtration
  • SCRIPT_URL_HACK / SCRIPT_URL_HACK_2, This is highly likely to be a hack attempt, as a user explicitly specified a URL which was code and not a real URL
  • BLACKHOLE_SPAM_HACK, This is a blocked spam attempt, where the anti-spam blackhole feature was activated – this would only happen if a spam bot was posting and can be detected early, so doesn't go through the spam heuristics system
  • DOWNLOAD_PRIVATE_URL_HACK, The user tried to add a download with a manual URL that links to private files that are not meant to be downloadable. This may be an honest mistake. A more detailed explanation follows further in this tutorial
  • TRY_TO_DOWNLOAD_SCRIPT, The user tried to add a download with a manual URL that links to a PHP file. This is very likely to be a hack attempt to try downloading potentially sensitive code (e.g. _config.php or data_custom/errorlog.php). A more detailed explanation follows further in this tutorial
  • TICKET_OTHERS_HACK, The user tried to access support tickets from another user. This is either a bug (we know of no way it would happen normally), or a hack attempt
  • ORDERBY_HACK, Tried to change the SQL ordering attribute, perhaps for SQL injection
  • BYPASS_VALIDATION_HACK, The user tried to specify that their content be validated even though they had no form option to specify it as such. The user is therefore very likely to be trying to hack the site by specifying options that don't exist for them in the hope they will go unfiltered
  • HEADER_SPLIT_HACK, A URL was submitted that contains a blank line. The submitter of the content with this URL is very likely to be a hacker, as there is no conventional way this situation could be come by
  • EVAL_HACK, The EVAL command would have executed arbitrary code if it was not blocked. This is extremely likely to be a hack attempt and should be taken seriously
  • PATH_HACK, Tried to use a file path redirection to get outside intended directory
  • PHP_DOWNLOAD_INNOCENT, Somehow a PHP file got referenced in the download system. This should have been filtered by 'TRY_TO_DOWNLOAD_SCRIPT', but was not. This is a serious security breach if it happens
  • BRUTEFORCE_LOGIN_HACK, Someone gave incorrect login details a certain number of times over a certain period as configured (brute-force attack)
  • ANTISPAM, The user came up against anti-spam heuristics or an integrated anti-spam service
  • CAPTCHAFAIL, The user failed filling in the CAPTCHA
  • CAPTCHAFAIL_HACK, The user failed filling in the CAPTCHA while simultaneously posting code that looks like it is from other software (the very clearest spam signal)
  • HACK_ATTACK_PASSWORD_CHANGE, The user gave an invalid confirmation code while finalising a password reset
  • SQL_INJECTION_HACK, The user seemed to be trying to extract database data using an SQL UNION operator (a very clear hacker signal when Composr is not expecting it to be used)
  • HACK_ATTACK, A generic hack-attack has been raised with no further explanation given

After an IP address accumulates a certain amount from risk scores ("Hack-attack risk score ban threshold" configuration option) it will be banned, if the "Enable auto-banning" configuration option (Admin Zone > Setup > Configuration > Security options > General) is enabled.
Similarly and more specifically there are a number of options specifically attached to the brute force login detection for automatic bans.

The "TRY_TO_DOWNLOAD_SCRIPT" error in detail

The full error is:
Tried to add a downloaded file that points to a script: so they could get the script contents (e.g. passwords)

This error is saying that the server tried to check the URL was valid but that it pointed to a PHP file. This tells Composr it is almost certainly not a file meant for download, and that someone may be trying to download sensitive information (such as PHP files containing configuration, passwords, or errors).

Unlike "DOWNLOAD_PRIVATE_URL_HACK", this is almost certainly a hack-attack attempt and should be treated seriously!

The "DOWNLOAD_PRIVATE_URL_HACK" error in detail

The full error is:
Tried to add a download whose URL points to a private or invalid file: so they could get its contents

The error is saying that the server tried to check the URL was valid but that it found the downloaded file was different to what there was on disk. That suggests to Composr that there's a security issue, that some kind of script is behind the URL or the file is not supposed to be accessed publicly, and therefore to not allow a 'trusted' relative URL to it because direct access could bypass security layers.

This error could also be caused by some server configuration issue too. For example:
  1. If the server cannot download files from itself properly to check, and whatever it does manage to access is returning HTTP '200' (file found) messages. This seems unlikely but it can be surprising what weird situations happen "in the wild".
  2. If something on the server is interfering with downloads. Something like the new Apache mod_spdy module could cause something like this. That might alter images during transfer and Composr would not receive the file it expected to be checking.

Tuning alert behaviour (advanced)

You can configure exactly how particular alert types are handled in XML from Admin Zone > Setup > Configuration > Configure advanced banning – or by hand-editing data_custom/xml_config/advanced_banning.xml based on the default data/xml_config/advanced_banning.xml.
Some sensible default <hackattack> rules are provided that take into account varying commonalities and severities.

Composr starts with the defaults for each setting, then tries matching each rule by the hack-attack codename and the 2 parameters associated with it, in order. Whatever settings are there when all rules are processed are those that will be used. Later rules have precedence. Rules that don't define attributes don't affect the settings behind those attributes.

Each rule can take the following attributes:
  • Matching attributes:
    • codename – the alert type (required)
    • param_a_pattern – a wildcard pattern to match against the first parameter (optional, default matches all)
    • param_b_pattern – a wildcard pattern to match against the second parameter (optional, default matches all)
  • Setting attributes:
    • silent_to_user – set to true if the user should not be told a hack-attack was raised (optional, default false)
    • silent_to_staff_notifications – set to true if the staff should not be sent a notification (optional, default false)
    • silent_to_staff_log – set to true if the hack-attack should not show in the UI browser of the logs (optional, default false)
    • risk_score – set to a score according to how severe this hack-attack is perceived (10 or more is almost certainly an intentional hack-attack); once an IP address reaches the "Hack-attack risk score ban threshold", they are auto-banned (optional, default 10)
    • syndicate_as_spammer – set to true if the hack-attack is related to spam and thus any ban should be syndicated out to any anti-spam partners (optional, default false)

Failed logins

Image

Failed login attempts

Failed login attempts

(Click to enlarge)

When a user tries to login Composr, but fails, it is logged. A proportion (approximately 15%) of these failures turn out to be real attempts to gain unauthorised access to the site, as demonstrated in the screen-shot.

The log can be reached from:
Admin Zone > Audit > Security logging

Filtering

Input filtering

The "Avoid broad input filtering security layer" privilege turns off filtering that may result in some data loss. Without the privilege it adds an additional level of security in case we have an actual security hole at another layer.
This generally protects against:
  • Request parameters that look like the file paths of particularly sensitive files
  • Request parameters that look like particularly dangerous HTML, or miscellaneous vectors for injecting CSS or JavaScript code
It is generally a good idea to not given untrusted users this privilege, as the need for such users to be able to post text that looks like file paths, dangerous HTML, or JavaScript, is not very high.

There are many privileges relating to Comcode filtering. These are detailed in the Advanced Comcode tutorial.

We also have of internal checks that always run, many related to "Alert types" (see above), including:
  1. Constraining of input parameters for filename-only scenarios (filter_naughty, PATH_HACK)
  2. Constraining of input parameters for codename-only scenarios (filter_naughty_harsh, EVAL_HACK)
  3. Checks for URL fields, e.g. making sure "data:" URLs are not submitted, or special characters that could allow interference with HTTP headers (DODGY_GET_HACK)
  4. Checks for posted JavaScript URLs ("javascript:"), anywhere (SCRIPT_URL_HACK_2)
  5. Referrer checks, to make sure POST requests aren't being made from non-trusted sites (i.e. CSRF-prevention, EVIL_POSTED_FORM_HACK)
  6. Input field length, so that strangely long parameter inputs are not accepted in most cases (this was removed, it didn't raise security, and created bugs)
  7. External redirections, so that hackers can't create URLs linking to your site that immediately redirect you to an unsafe third-party site (this kind of thing can trick users into thinking they have clicked onto your site, when they're not there anymore). This isn't logged as a hack-attack, as it can happen too innocently, but it is filtered out.
  8. Obvious spamming
  9. Generally making sure things are filled in when required, and expected numbers really are numbers

We also have standard output escaping mechanisms so that attempts to inject bad data do not lead to bad outcomes.

In summary, we have defence across a number of layers, and code without making poor assumptions. This is called "defence in depth" – programmers are fallible, so it's best to have multiple lines of defence.

Content Security Policy (CSP)

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks.
CSP prohibits developers from using inline event handlers and inline script tags.

All code bundled with Composr strictly adheres to these guidelines and thus is completely free of inline event handlers and script elements.

Adherence to CSP for custom code is optional, CSP can be enabled/disabled/tuned in the configuration. To maintain CSP adherence requires a higher degree of discipline when designing your website.

CSP is built on the back of the "Trusted partner sites" configuration options, as well as hooks that inject new trusted sites based on the need of addon functionality. We apply restrictions to mitigate the following possible attack vectors…
Inbound or Outbound Vector/trust Risk level Mitigation via Configured by
Inbound Sending HTTP POST requests to your website

CSRF-risk, you trust them not to trick users into submitting malicious forms, automatically or by deception.
Low

CSRF-token protection and referrer checking also exists.
PHP code Trusted partner sites (level 1), Trusted partner sites (level 2)
Inbound Send calls to your website via in-browser requests [AJAX]

As above, but extended risk due to automation to both read and write any number of sequential pages with requests being potentially logged in as the user due to cookies.
High

Allows invisible remote controlling of a logged in user.
CORS configuration Trusted partner sites (level 1)
Inbound Putting your website in a frame

You trust them to not do confidence-tricks on users, like impersonating arbitrary parts of your website like login forms, or doing click-jacking.
Low

Due to fragility of the trickery and needing gullibility.
CSP Trusted partner sites (level 1), Trusted partner sites (level 2), Allowed frame ancestors
Outbound Loading in a frame

Risk of confidence-tricks on users, like impersonating arbitrary parts of your website like login forms.
Low

Due to the fragility of the trickery and needing gullibility.
CSP Trusted partner sites (level 1), Trusted partner sites (level 2), Allowed frame descendants
Outbound Making calls to JavaScript files

Risk of malicious code via XSS attack.
Medium

XSS-protection already exists for requests and content.
CSP Trusted partner sites (level 1), Trusted partner sites (level 2), Nonces (*)
Outbound Making calls to CSS files

Risk of malicious layout changes for trickery.
Low

XSS-protection already exists for requests and content, and very fragile attack than needs gullibility.
N/A No limitations implemented in Composr
(webmasters could not realistically meet these CSP limitations)
Outbound Making calls to scripts via in-browser requests [AJAX mode]

Risk of your site being used as an intermediary in attacks.
Low

XSS-protection already exists for requests and content,  and only possible if the remote server has opened the possibility up for this.
CSP Trusted partner sites (level 1), Trusted partner sites (level 2)
Outbound Making calls to scripts via form posting

Risk of your site forms being redirected to some kind of sophisticated attack.
Low

It would be unlikely to find such a vulnerability.
CSP Trusted partner sites (level 1), Trusted partner sites (level 2)
Outbound Redirecting to third-party sites

Composr passes redirect parameters around, so it knows where to return after actions, but this could be abused to redirect someone to a website impersonating your site.
Medium

Due to needing gullibility.
PHP code Trusted partner sites (level 1), Trusted partner sites (level 2)
Outbound Making calls to media/objects/images/fonts [AJAX mode]

Unclear risk.
Trivial

There is no clear risk.
N/A No limitations implemented in Composr
(webmasters could not realistically meet these CSP limitations)
* Nonces are configurable in HTML/templates via placing {$CSP_NONCE_HTML} in the opening tag. An XSS hacker has no way to know the nonce, so can't inject script/style requiring it. At the current time nonces are only supported in CSP by script and CSS files, but the W3C is discussing changes this.

Note that the "Trusted partner sites" configuration options automatically include "www." if not specified.
The "Allowed iframe ancestors" configuration option and "Allowed iframe descendants" configuration option allow wildcarding to allow any request (and "Allowed iframe descendants" does by default due to the low risk and commonality of frame use).

There are many settings related to CSP in the Composr security options (Admin Zone > Setup > Configuration > Security options), including:
  • Enabling/disabling
  • Relaxing some of the deeper restrictions
  • Defining pages that don't run with CSP
  • Specifying whether CSP violations are reported to the error log

Limitations:
  • We highly advise to not use Internet Explorer because it does not have fully support for CSP 2, or even really CSP 1 (it is under a special beta header only). Microsoft Edge is fine though.
  • Unfortunately when WYSIWYG is in use then CSP is disabled, due to limitations with CkEditor.
  • Particular parts of Composr may have CSP restrictions relaxed based on the behaviours they need to allow.

If you are a programmer and want to customise the CSP rules in more detail, override the sources/csp.php file.

A detailed technical writeup of the implementation is at the top of the sources/csp.php file.

Security headers you can implement manually

There are some additional HTTP headers you can implement in your server configuration (outside the scope of Composr) if you consider it appropriate:

Anti-spam measures

Image

In this config option that embeds an "E-mail the staff" link, the address is obfuscated so most bots won't understand it

In this config option that embeds an &quot;E-mail the staff&quot; link, the address is obfuscated so most bots won&#039;t understand it

(Click to enlarge)

Throughout Composr, measures are taken to reduce the chance of e-mail addresses being harvested for use by spammers. Typically, spammers gather e-mail addresses by using bots to automatically scavenge text that looks like an e-mail address from web pages; however Composr does not display member e-mail addresses publicly at all, and instead provides a 'contact member' module. In addition, whenever the staff address, or a staff member's address , is shown, it is obfuscated, so as to make it unlikely to be picked up as an e-mail address.

robots.txt

To remove the possibility of search engines indexing the login screens of your Admin Zone you can create a robots.txt file on the root of your domain name. The bundled robots_txt addon provides a good default. The installer puts this default in place if you don't already have a robots.txt and if it can write out the file. There is also an editing UI at Admin Zone > Structure > Search engine policy (robots.txt).

File-type safelisting

In the security configuration, Composr defines a list of file types that may be uploaded to the website, via the various upload mechanisms that exist in Composr, such as that of the download module and the attachment system. By default, this safelist is roughly (this is not kept up-to-date):
  • sql,odt,ods,ps,pdf,doc,txt,psd,tga,tif,gif,png,bmp,jpg,jpeg,avi,mov,mpg,mpeg,asf,wmv,ram,ra,rm,qt,mov,zip,tar,rar,gz,wav,mp3,ogg,torrent,php

It is important to understand that there are two sides to the security of file uploads:
  1. on the server-side, it must be impossible for a file to be uploaded that might execute on the server, instead of download (such as a php file). You may have noticed that php is an allowed file extension in the list: this is because php uploads are explicitly blocked internally, but only in the situation where the file would be stored on disk with its original extension (which the attachment system does not do)
  2. on the client-side, it must be impossible for a file to be uploaded that might get downloaded and automatically execute a malicious action on a client computer. One example of such a file type is, to the surprise of most, 'html'. .html files can contain JavaScript, which could be used, if the file was downloaded from the main website domain, to transmit the user's login cookies to any arbitrary hacker. Therefore it is crucial that HTML files, and other files (svg, xml are suspected to be dangerous at this time) are not added to the list

Protect your domain name

It is important that you don't use a public domain name, or give people access to upload their own sites to your domain. If you do, basic web browser security walls will be broken down, and someone malicious could use techniques to extract your access from you. Giving other's access to subdomains is generally okay, so long as you are careful to configure your cookies so that only the main domain can read them.

Protect your session security

We recommend the 'Enforce IP addresses for sessions' option is left enabled. If you are on some kind of network such as TOR where your IP address may randomly change, we advise to not use this when administering Composr – it will greatly reduce your security. If you have an ISP where your IP address changes very frequently, you may want to consider a more reliable ISP.

For a break-down of the risk of disabling this option, see this tracker discussion.

Techniques for increasing security further

This section details some techniques to increase the security of your site. Most of these techniques are either advanced, or unattractive for most Composr users, which is why they are not included in the default Composr configuration.

Referrers

All users with privileged access should have referrers enabled in their web browser. Without this, Composr can't prevent malicious requests being redirected through to your own website's forms from other (malicious) websites.
By default browsers do have referrers enabled, but some firewall products may disable them for very minor privacy reasons (to stop a website knowing what link you followed to get to it, which most people would agree is not really a privacy issue to them at all).

To check you have referrers enabled, go to Commandr (Admin Zone > Tools > Commandr) and type:

Code

:echo $_SERVER['HTTP_REFERER'];
You should get a URL back that is a URL under your own website.

If you get a blank result, or something like 'unset' or 'hidden', you need to find out why referrers are disabled and re-enable them.

Guest access

Image

Securing the member joining process

Securing the member joining process

(Click to enlarge)

In order to reduce the risk of hackers gaining unauthorised access to areas of your website, you could close down access to all possible areas except to vetted members. These options are located in Admin Zone > Setup > Configuration > User/usergroup options. By default, Composr is set up to deny guest access to almost all of the site; however, security can be improved further by only allowing members to become fully joined after a manual vetting process.
To force members to be vetted, you need to enable the 'Require member validation' option, as shown in the screen-shot.

SSL

When you access a website via an HTTPS URL, rather than an HTTP URL, you are using <abbr title="Transport Layer Security">TLS</abbr> (or the older protocol, <abbr title="Secure Sockets Layer">SSL</abbr>).

An HTTPS page view encrypts bi-directional traffic securely (to avoid unauthorised tampering and interception by third-parties) but also imposes a small performance cost on the server. Nowadays websites will warn users if they visit a non-HTTPS site.

To use HTTPS you must have an SSL/TLS certificate installed on your server. SSL certificates vary in price immensely, but you can get a free one from the Let's Encrypt project (this requires provisioning via their software installed on your server).

You set HTTPS in Composr by choosing a base URL that starts https://.

Note that a page viewed under HTTPS must use HTTPS for all images and other embedded files. The reason for this is that users should not get mixed environment messages that warn them about potential security problems, or in some browsers lock out the whole page. Template makers and coders should be careful to use the proper Composr mechanisms for referencing resources. Under HTTPS user provided media that is not linked under HTTPS will either be automatically upgraded or proxied.

Migrating HTTP websites

It you change the protocol (or domain name) in the base URL, Composr will automatically provide redirects to the corrected version of the URL.
The CSP implementation will also provide automatic redirects. We just don't rely on all clients having a CSP implementation.
Ideally these redirects would happen for all requests though, not just dynamic PHP requests. There are some default rules in the recommended.htaccess for this.

If you are on Apache then you can add this to your .htaccess file to tell web users to use HTTPS for the whole domain:

Code

Header always set Strict-Transport-Security "max-age=31536000"

Or merge this into the <customHeaders> section you have in web.config for IIS :

Code (XML)

<add name="Strict-Transport-Security" value="max-age=31536000"/>
 

Don't add any rules to just redirect HTTP traffic to the root of the domain because that could hurt your SEO.

Secured zones

Image

Securing a zone so that an explicitly logged-in session is required

Securing a zone so that an explicitly logged-in session is required

(Click to enlarge)

Composr has "confirmed" and "non-confirmed" sessions.
When you login to the Composr site you have a "confirmed" session. If you then come back to the site and automatically are logged in via cookies then that session is "non-confirmed". This distinction is common on many sites as a security feature.

It is possible to configure zones so that they require a confirmed session to access them. This means that a user can only access the zone if they have actively chosen, in the specific web browser window that is currently being used, to login: login cookies alone cannot gain them access.

This might seem like a very strange thing to enforce, but there is a very good reason: it is very easy for someone to create a malicious website that contains a form with a target of your website, such that the form directs a malicious action when you are tricked to fill it in and click 'submit'. If a barrier of a required session was not imposed, this action could go unabated with your access level direct to perform some malicious action by proxy through you. These kinds of attacks are called CSRF ("Cross-Site-Request-Forgery").

Additionally, if someone else accesses your computer you don't necessarily want the cookie login to let them have complete website control.

The Admin Zone is configured to require confirmed-sessions by-default because it has lots of very dangerous features. You may choose to also secure the site zone in the similar fashion.

Essentially the idea of confirmed vs non-confirmed sessions is a trade-off. You can maintain cookie-based logins, but to do the higher level of actions you need to confirm yourself.

Composr does provide a secondary defence against this scenario, by checking referrers, but we do not consider referrers secure based on two facts:
  1. this seems an area where there may be web browser vulnerabilities, or unfortunate situations, that lead to inaccuracy of this data
  2. user firewalls, ironically, often block this data (for privacy reasons), preventing us from using it to add to security
We also have security tokens on forms as a third defence.

Conceded mode

Conceded mode is a link to turn a confirmed session into a non-confirmed session if you worry someone else might use your computer while you're away (for example).

It is a bit like a partial log out.

Restricting logins

Image

Restricting login so it can only be done for IP addresses that are confirmed via e-mail

Restricting login so it can only be done for IP addresses that are confirmed via e-mail

(Click to enlarge)

In Conversr, it is possible to set usergroups so that members of those usergroups may only immediately login from IP addresses that have been confirmed as valid. To confirm an address as valid, an e-mail is sent out to the member with a confirmation link.

This technique reduces the chance of someone gaining unauthorised access to an account, but is also very annoying for users who do not have a stable IP address.

_config.php (when suEXEC is not enabled)

By default, _config.php is left 'world-writable' by the installer if suEXEC is not enabled. This allows the Installation Options editor to work with it, and allowed the file to be initially filled, but does represent a potential security risk on a shared server.

While many files are world writable, this file is a particular target, because it may be executed. Therefore if someone on a shared server can write to the file, perhaps via shell access, then they can execute code on your site, possibly unnoticed. It is worth noting that if they had shell access, they could trash your database and uploads anyway, but not so easily execute code on your domain.

To solve this problem, simply remove execute permission for the _config.php file.

It may seem an obvious solution, to not use an executable file to store configuration information. However this file contains critical data, and therefore if it was a file that would be downloaded if accessed instead of executed, this critical data would be exposed; the usual advice is to put the file outside of a downloadable location, or to restrict download, but this is tenuous due to differing web environments Composr must on: in trying to increase security, there would be a big likelihood we could incidentally decrease it.

Maintenance password

For added security you can remove the:

Code (PHP)

$SITE_INFO['maintenance_password'] = '...';
 
line from _config.php.

It is best to remove it completely, not comment it out. This prevents maintenance password based logins to tools such as the code editor and upgrader.

It means:
  1. If someone found a vulnerability that allowed them to read the hashed maintenance password out of _config.php, they could not use software-specific rainbow tables to get the original password and therefore login.
  2. Bruce force login attempts cannot work.

Maintenance scripts

To provide additional protection beyond the maintenance password you may want to set IP-based restrictions (or temporary access blocks) to the following scripts:
  • rootkit_detection.php
  • upgrader.php
  • uninstall.php
  • data/upgrader2.php
  • config_editor.php
  • code_editor.php

Follows are sample access rules for an Apache .htaccess file to provide a temporary access block:

Code

<FilesMatch ^((rootkit_detection|upgrader|uninstall|data/upgrader2|config_editor|code_editor)\.php)$>
   Require all denied
</FilesMatch>

For IIS, the web.config file's hiddenSegments can be extended:

Code (XML)

<hiddenSegments>
        (existing rules)

        <add segment="rootkit_detection.php" />
        <add segment="upgrader.php" />
        <add segment="uninstall.php" />
        <add segment="upgrader2.php" />
        <add segment="config_editor.php" />
        <add segment="code_editor.php" />
</hiddenSegments>
 

You should test these rules are working correctly after applying them.

If the "Auto-maintained maintenance script IP-barrier" configuration option (Admin Zone > Setup > Configuration > Security options > General) is enabled and the "Enquire on new IPs" option is set on a Conversr usergroup(s) then the .htaccess file will automatically be updated to include all confirmed IP addresses with access. This option is not always available as it requires write access to the .htaccess file and also the Apache web server. It is also not available if the .htaccess file contains a require valid-user directive (HTTP-Auth), or if there are 500 or more IP addresses which would have had to go into the .htaccess file. If the option is enabled then you should not manually add the above rules to the .htaccess file or try to adjust the automatically maintained code. Additionally only enable "Enquire on new IPs" for usergroups you trust.

Denial Of Service prevention

Composr is a sophisticated system and comes with an unavoidable overhead. This increases the opportunity for a malicious individual/group to try and take down a server by flooding it with requests. Composr is designed to prevent against this – it will ban flooders and hackattack repeaters after a point. However, the normal IP banning that Composr uses works via the database, and hence a significant overhead is taken before the ban can be detected. To workaround this, Composr can write IP bans directly into the Apache .htaccess file (obviously, Apache only) – to do this, the .htaccess file must be writable by the web server (typically, 666 permissions, although as explained, a well configured environment won't need that).

Rooted-website prevention

"Rooting" a server involves hacking the web server account and leaving a 'backdoor'. 'Rooting' is either done from some direction that Composr cannot monitor (such as via another web application), or done via a yet unknown vulnerability in Composr.

There is a special script (rootkit_detection.php) that will help detect if Composr PHP files or critical/sensitive database settings are changed, by off-server comparison of data. This is a very advanced script and requires a level of expertise that is outside the scope of this documentation. This method isn't foolproof, but does significantly raise the bar security-wise, reducing the chance that any particular hacker will be able to compromise your website.

HTTP authentication

There is nothing stopping you using HTTP authentication served by your web server on top of the website if you want some extra security.
For example, it is possible to use HTTP Authentication to deny access to the whole of Composr to anyone without a preallocated HTTP-Auth password. For more information on this, see 'related topics'.

However, you should let requests from the web server itself through that without needing to authenticate so that it can read its own URLs (otherwise you could have some problems, such as security errors when editing theme images).

Have you been hacked?

This advice is not specific to Composr, but rather a writeup on how web scripts generally can get hacked. It is not discussing any security holes in Composr, or anything specific to Composr's history.

If you are ever hacked, it is much more likely that you'd be attacked automatically than individually. Hackers write scripts to automatically probe servers for common vulnerability categories, or specific vulnerabilities.

A telltale sign of being hacked is unrecognised code or redirects suddenly showing up on your website.

Often these kinds of hacks run on the server level, going from one site to the next on the server. That is possible if files are set to be world-writable (i.e. another account on the server can access your files for writing if that's the case), which should not be necessary on most modern hosting as suEXEC is now commonplace (PHP can write to its own files without special access). Composr tries to limit file permissions if it detects suEXEC.

This said, it is easy for permissions to get set too liberally when uploading. This can happen if an FTP client is set to mirror local permissions, and local permissions are set to full write – or if the client or server just has default permissions that are too high.

The above is the most likely scenario and is quite common among people running web scripts.

The other less likely possibilities that come to mind would be:
  1. some hole in some script on your account. It could be any script you have because this kind of situation often combines with the likely one above: some script on the server somewhere has a hole, then the hacker tunnels through that to infect other things on the server that have too liberal permissions. Or, if you do have correct permissions, some script on your hosting account, affecting other things on your hosting account.
  2. something local to your PC. That seems unlikely because it would be a lot of work for a virus to do this, and they'd have more commonplace targets (only a small proportion of people will have their own websites).
  3. some server-level vulnerability, e.g. in PHP or Apache, or the FTP server.

To find the true cause of a hack it is a good idea to go through your access logs to find any evidence of malicious-appearing requests that happened around the time of your files being modified (you can easily find the last-modification date for your files).

However, be careful that once you have a cause identified, you do a full cleanup/restore as well as addressing that cause. You don't want to miss something a hacker might have left behind. It is best if you seek expert help for this.

Most users never get hacked, so it's pretty bad luck if you have been (or, you've not updated scripts with important security updates in :S ).

General considerations

This section contains some general things to bear in mind when considering your security.

URL monikers

The URL monikers feature puts content titles into URLs instead of IDs, and for SEO purposes Composr will enforce those URLs consistently. It does this when generating a page-link for inclusion from content (e.g. from a forum post), or if the numeric-ID URL is accessed (it redirects).

This is a long way of saying that the URL moniker exposes content titles to users who may not have access to that content, which could be a concern in some cases.

If you have sensitive material that might be in a URL moniker, you should either customise that moniker(s), or turn the feature off in the configuration.

Server hardening

If you are managing your own server, you may want to consider:
  • Disabling any Internet services you do not actually need, such as FTP
  • Changing the default SSH port (change the Port setting in /etc/ssh/sshd_config to a random port number)
  • Disabling remote access to the e-mail server (for Postfix set inet_interfaces localhost in main.cf)
  • Disabling remote access to the database server (for MySQL set bind-address=127.0.0.1 in my.cnf)
  • Disabling the TRACE feature in the web server (for Apache set TraceEnable Off in httpd.conf)
  • Disabling web server version/architecture disclosure (for Apache set ServerSignature Off and ServerTokens Prod in httpd.conf and typically comment out the contents of welcome.conf)
  • Enabling automatic updates (for RedHat-based releases install the dnf-automatic package and set apply_updates = yes in /etc/dnf/automatic.conf and run systemctl enable --now dnf-automatic.timer)
  • Installing MySQL/MariaDB from an official repository rather than the distribution repository, for faster deployment of security fixes
  • Running a scanner tool such as ZAP


See also


Feedback

Please rate this tutorial:

Have a suggestion? Report an issue on the tracker.