We wrote about WordPress security on a shared hosting and what to do if you get hacked. Here we will write about general programming practices to include in your web development projects. This is a technical article so good for your development team as well as should be made standard practice in all IT concerns.
Web security is often assumed out of the box and something even the best practices can’t always cover. Its important cover all your bases and be on your toes. Websites are a complex beast and need tending to constantly.
1. Never Trust User Input
The basic rule for securing web application is to always filter input and escape output. Do not trust user data and always make it validate and filter properly. To validate means to verify that the data is valid while filter means to remove unwanted characters from the data. Sometimes we trust user data because we never even know it’s actually user data. For example; consider $_SERVER[‘HTTP_HOST’]
which is a PHP global variable and some developers become confused that its server variable and not user data. So they used this variable in form action or site_url like
<form action=”<?= $_SERVER[‘HTTP_HOST’]?>/page”>
Or
$config[‘site_url’] = ‘HTTP://’.$_SERVER[‘HTTP_HOST’];
However a user (attacker) can modify this variable by sending a different host header. So we should avoid using $_SERVER[‘HTTP_HOST’] and use the domain name instead. E.g
$domain_name = 'mydomain.com';
$config['site_url'] = 'HTTP://'. $domain_name;
This type of security vulnerabilities leads to phishing attacks and cache poisoning.
2. Understand Cross site scripting (XSS):
In this type of web security attack, an attacker executes an unwanted malicious JavaScript in the user browser. Let’s say a website contains the following input field
<input type="text" value="user" />
So an attacker comes and insert script like this
"<script>alert(‘website hacked’);</script><input type="text" value="
so it becomes
<input type="text" value="" />
<script> alert(‘website hacked’);</script>
<input type="text" value="" />
In this way attacker can execute the script he/she wants to execute and can steal user cookie, spread malwares and perform many other tasks.
Type of cross site scripting are
- Persistent XSS: originates from website database.
- Reflected XSS: originates from victim’s request
- DOM-Based XSS: originates from vulnerabilities in client side code
The prevention for this type of web security vulnerability is to encode and properly validate user input both on the client side as well on the server side.
3. Cross site request forgery (CSRF):
In this type of web security vulnerability, malicious website sends a request to a web application that a user is already authenticated against. The attacker inspects the website and finds the form action and then submit the form from a malicious website to the found action url with the desired values.
To prevent this type of security attacks always include an unpredictable token to each request and verify request again that token.
4. SQL Injection:
This type of security attack arises because of security weakness which allows attacker to take control of application’s database. Thus the attacker can view, modify, delete records or even drop tables. For example, let’s say we have a website that displays student result based on the student id.
Student Id
The actual SQL query is
SELECT * FROM std_result WHERE std_id=1005
So it will fetch the user result but what if the user type 1005 or 1=1 into the box. The query will become
SELECT * FROM std_result WHERE std_id=1005 or 1=1
In this case the first condition will become false but the second condition will become true and it will fetch all the rows. The attacker can also drop the whole table if he/she types 1005; DROP table std_result;
into the box.
This type of attacks can be prevented by using PDO and mysqli with strongly typed parameterized queries.
5. Session Fixation
In this type of security vulnerability an attacker explicitly sets session identifier of a session for a user. It’s typically performed by making a URL like http://www.example.com/index.php...?session_name=sessionid
. This URL is then passed to the victim. As soon as the victim clicks on the link, the attack is succeeded.
This type of security vulnerability can be prevented by
- Setting session_use_trans_sid = 0 in php.ini file which will tell PHP not to include identifiers in URL as well as not to read URL for identifiers.
- Setting session_use_only_cookies = 1 in php.ini file which will tell PHP to never use URLs with session identifiers.
- Always regenerate session ID when session’s status changes, i.e. user authentication or storing sensitive information in the session
6. Session Hijacking:
In this type of security vulnerability an attacker gets hold of a session identifier and thus attacker becomes able to send requests as if they were the actual user. As the attacker has got the identifier, so they can perform any thing that can be done by the actual user.
We can’t really prevent session hijacking but we can make it difficult and harder to use by using strong hash identifier, setting additional entropy, changing session name from default PHPSESSID etc.
Note that the difference between session fixation and session hijacking is that of how the attacker gets access to identifier. In session fixation the identifier is set to a value that the attacker knows while in hijacking the identifier is being stolen from the user or being guessed by the attacker. The impact of both is the same.
7. Patch Your Servers
Sometimes you may get hacked even when its not your fault. There have been some severe hacks recently such as Heartbleed and WannaCry. It would be very helpful when you can patch your webservers against such wide ranging hacking techniques. Kernel hardening or OS hardening is a valid technique. For large websites and business concerns, its important to patch your servers, even every week if need be. You can setup a server cron job (scheduled task) to send you list of outdated packages so you can update manually. We do this regularly for our dedicated clients.Finally, you can ask a software company specializing in web security to look into your setup. They will do stress tests, performance tests and penetration tests to find of any vulnerabilities. If you are looking to get your website tested then you can discuss with us.
If you want to get familiar particularly with woocommerce security you can Read.
8. Use Fail2Ban for Brute-Force Protection
Fail2Ban is a powerful intrusion prevention software that protects servers from brute-force attacks and suspicious login attempts. While it’s not WordPress-specific, integrating it into your security strategy can provide an additional layer of protection.
Fail2Ban works by monitoring log files for failed login attempts and blocking IPs that show malicious behavior, such as repeated login failures or scanning for vulnerable pages.
Steps to Set Up Fail2Ban for WordPress:
1. Install Fail2Ban:
On Ubuntu/Debian systems, use:
sudo apt-get install fail2ban
2. Configure Jail for WordPress Login:
Create a custom jail file, for example:/etc/fail2ban/jail.d/wordpress.conf
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600
3. Create a Custom Filter:
Add a filter file at /etc/fail2ban/filter.d/wordpress.conf
and include patterns for WordPress login attempts:
[Definition]
failregex = ^.*Failed login attempt.*$
ignoreregex =
4. Restart Fail2Ban
After configuring, restart the service to apply changes:
sudo systemctl restart fail2ban
This setup ensures that malicious actors who repeatedly fail to log in are automatically blocked for a specified duration.
9. Disable XML-RPC for Enhanced Security
XML-RPC is an API that allows remote communication with your WordPress site, such as publishing content or managing comments via third-party tools. However, it’s often exploited in brute-force attacks and distributed denial-of-service (DDoS) attacks.
Steps to Disable XML-RPC in WordPress:
1. Use a Plugin:
The simplest way to disable XML-RPC is by using a plugin like Disable XML-RPC.
2.Manual Method (via .htaccess
):
Add the following lines to your .htaccess
file to block access to the XML-RPC file:
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
3. Disable via Functions File:
Add the following code snippet to your theme’s functions.php
file:
add_filter('xmlrpc_enabled', '__return_false');
Disabling XML-RPC significantly reduces the attack surface of your WordPress site without affecting most modern integrations, as the REST API has largely replaced XML-RPC for remote functionality.
By adding Fail2Ban and disabling XML-RPC to your security measures, you further bolster the defenses of your WordPress site, ensuring a more robust security posture.
Conclusion
Web security is an ongoing process that demands vigilance, proactive measures, and regular updates. From securing user input and understanding common vulnerabilities like XSS, CSRF, and SQL injection, to protecting sessions and ensuring servers are patched, every step matters in safeguarding your web applications.
By integrating practices like using parameterized queries, validating and sanitizing inputs, implementing session security, and setting up intrusion prevention systems like Fail2Ban, you significantly reduce the risk of exploitation. Additionally, disabling XML-RPC and staying up-to-date with server patches further fortifies your defenses.
Remember, no system is 100% secure, but adhering to these best practices ensures you’re minimizing vulnerabilities and staying ahead of potential attackers. Whether it’s a small website or a large-scale application, investing in a strong security framework is crucial for maintaining user trust and protecting your digital assets. If you need professional assistance or want to conduct a security audit, feel free to reach out to experts for a tailored solution.