A few easy tricks to improve the security of your WordPress website

I will show you six easy tricks to improve the security of your WordPress website.

In this blog post, I will show you six easy tricks to improve the security of your WordPress website.

Create a new administrator and delete the default one

Why?

Each new WordPress website has a default administrator. Now let’s assume that an attacker targets my website. They can easily find out that the content management system (CMS) for this website is WordPress by using a Chrome extension like Wappalyzer. Then they can find the WordPress default admin usernames with a Google search and enumerate users on my website thanks to a flaw on the WordPress login page.

By entering username=”test” and password=”test”, an attacker learns that “test” is not a valid username. This is an example of information disclosure that helps threat actors to enumerate the users on a webserver.
WordPress should change this message to the more generic “invalid username or password”.

Knowing the administrator username reduces the search space for dictionary attacks and brute force attacks. Now if the admin password is also common1 or weak, the attackers will take over the website in a matter of minutes.

How?

Add a new user2 with role “administrator” with a strong password. I like my passwords to have at least 20 characters (a mixture of lowercase, uppercase, numbers, and special characters). Then login with the new admin account and set-up 2FA right away (see below), and delete the default admin user3.

Add the recommended security headers

Why?

Security headers add an extra layer of protection to SSL4.

  • HSTS: This header forces the browser to do all requests to the website domain over HTTPS.
  • X-Content-Type-Options: The browser is forced not to guess what kind of data is passed. If the extension is “.pdf”, the browser will expect a PDF file.
  • X-XSS Protection: It will block the page in the browser from loading if reflected cross-site scripting (XSS) is detected.
  • Expect-CT: In order to prevent fraud, the SSL Certificate Authority has to log the certificates with the Certificate Transparency (CT) framework.
  • Referrer-Policy: A referrer header contains the address of the previous web page from which a link to the currently requested page was followed. The policy “no-referrer-when-downgrade” does not include the origin, path, and query string of the URL when the protocol security level is downgraded (HTTPS→HTTP).
  • Content-Security-Policy: This header is another method to force requests to the website domain over HTTPS.

How?

Open the .htaccess file on your server5 and add the following lines:

Add the following security headers to your .htaccess file.

Hide the PHP version from the HTTP Response Header

Why?

By default, the Apache server running my website exposes the PHP version in the HTTP Response Header. That is, it makes the PHP version that I use public on the Internet. This is particularly dangerous when the PHP version is an old and vulnerable one. An attacker could look for exploits against this specific version, and maybe get a reverse shell on the server.

The PHP version is visible in the HTTP response Header.

How?

Open the php.ini file on your Apache server. Set the expose_php variable to Off. Restart php-fpm and apache.

The PHP version is not visible anymore.

Enable auto-updates for WordPress, plugins, and themes

Why?

It is important to install the newest stable software releases as soon as they are available because they usually contain security patches. Enabling auto-updates takes this task off of your mind.

How?

  • WordPress: Go to Dashboard > Updates. Under “Current version”, click on “Enable auto-updates”.
  • Plugins: Go to Plugins > Installed Plugins. Under the column “Automatic updates”, enable auto-updates for every single plugin used. Delete inactive plugins.
  • Themes: Go to Appearance > Themes. Open the current theme and click on “Enable auto-updates”. Keep only one other theme as a backup. Delete all other inactive themes.

Use Two-Factor-Authentication for each single user

Why?

This adds an extra layer of protection to the authentication process. If the password of a user is cracked or leaked accidentally, the attacker will not be able to authenticate on the website (at least not easily).

How?

Install and activate the WP 2FA plugin as the admin user. Force each user on the blog to add 2FA to their account without delay.

Make sure that only used server ports are open

Why?

Open ports on a server are a security vulnerability that can potentially allow a hacker to exploit services on your network. If those services are unpatched, a hacker can easily take advantage of the system after running a port scan.

How?

Go to https://www.shodan.io/ and enter the IPv4 address of your server. Under “Ports”, you will see the open ports. If any port that you are not using is listed there, close it right away.

I hope you liked this post. If you have any questions, feel free to leave a comment in the comment section. Never stop learning!

How I made my website more secure

I will describe how I made my website more secure by integrating a free SSL certificate into my WordPress website with the Really Simple SSL plugin.

In this post, I will describe how I made my website more secure by integrating a free SSL1 certificate into my WordPress website with the Really Simple SSL plugin. Before doing that, I will give a brief introduction about how data is transferred over the Internet, and why encrypting and signing that data is very important.

Data over the World Wide Web is transferred with the HTTP (Hypertext Transfer Protocol) protocol2. HTTP messages can be categorized in two main groups: requests and responses. I will now briefly describe what HTTP requests and responses are.

An HTTP request is generated when a user interacts with their web-browser (e.g., Firefox). For example, when a user enters info.cern.ch in their URL bar and press enter, their browser will send a series of HTTP GET requests in order to get the information necessary to render that page.

The image here below, which I took while monitoring my WiFi traffic with Wireshark,3 shows how such a request looks like:

Example of an HTTP GET request

HTTP requests go to a server4 and that server generates an HTTP response which looks similar in its form to an HTTP request. As you can see, HTTP responses and requests are sent across the Internet as plain text. This means that any data, sensitive data included, that users send or receive can be read by anyone who is monitoring the session. Another problem with HTTP is that the recipient of a message cannot be confident that the message was sent by the legitimate sender, and that it hasn’t been changed while in transit.

The solution to this problem is called HTTPS, where the S stands for secure. HTTPS uses TLS/SSL5 to encrypt HTTP requests and responses. In this way, anyone monitoring your traffic will only see gibberish. Moreover, TLS/SSL signs your data. Both these results are achieved by using public and private keys6.

This is how a TLS/SSL encrypted HTTP request sent to my own website looks like when monitored with Wireshark:

Example of an HTTP over TLS request

My website didn’t have HTTPS when I opened it. In order to provide secure communication from/to my website server, I first got hold of an SSL certificate and then integrated it into my WordPress website using the Really Simple SSL plugin.

An SSL certificate is a data file hosted on a website’s origin server. It is what enables websites to move from HTTP to HTTPS7. It is possible to obtain a SSL certificate from Let’s Encrypt8 for free. Let’s Encrypt certificates need to be renewed every 90 days.

In order to request a Let’s Encrypt SSL certificate I first had to connect to my server via SSH9. After updating the packages on my instance, I installed Certbot – a client used to request a certificate from Let’s Encrypt and deploy it to a web server.

The next step was to request a Let’s Encrypt SSL wildcard certificate10. In order to do so, I had to prove that I owned the domain I asked a certificate for. I did this by adding TXT records to the DNS records of my domain. Once the TXT records had been propagated to the internet’s DNS, I completed the Let’s Encrypt certificate request.

As Certbot saved my SSL certificate, chain, and key files into /etc/letsencrypt/live/michelepariani.com/, I created links to these files in the Apache directory11 on my server.

Finally, I installed the Really Simple SSL plugin on my WordPress website and used it to integrate the SSL certificate with a few clicks on the website admin page.

A detailed tutorial about the steps described above can be found here: https://lightsail.aws.amazon.com/ls/docs/en_us/articles/amazon-lightsail-using-lets-encrypt-certificates-with-wordpress.

I hope you liked this post. If you have any question, feel free to leave a comment in the comment section. Never stop learning!

How I set up this website in minutes

After taking Stéphane Maarek’s AWS Cloud Practitioner course on Udemy, I decided to use the power of AWS to create my own website. Discover how I did it!

After taking Stéphane Maarek’s AWS Cloud Practitioner course on Udemy, I decided to use the power of AWS to create my own website. My goal was to create a website quickly and with a predictable price. In this post, I will describe how I did it.

The basic ingredients to build a website are a server, a content management system (CMS)1 and a domain name2. As these terms can be intimidating for a beginner, I will explain what these mean:

  • Server: A server is a computer running one or more programs that are designed to listen for and process incoming internet requests. In this case, the server takes on the responsibility of serving up the content for a website.
  • CMS: A CMS is a software that allows users to create, manage, and modify content on a website, without needing to code.
  • Domain name: A domain name is the website name. For example, my domain name is michelepariani.com.

Wait, what? Do I need a server in my basement to run my own website? No, you don’t. Enter the cloud. The cloud refers to servers that are accessed over the Internet, and the software and databases that run on those servers.

I decided to rent a server on AWS, as I know this cloud service from the AWS Cloud Practitioner course. After researching a bit on AWS, Amazon Lightsail offered itself as the right solution for my needs.

Lightsail offers different preconfigured, one-click-to-launch operating systems. For my website, I chose a Linux instance – a VPS (virtual private server) – that comes with WordPress3 preinstalled on it. After a few clicks, I was able to launch my own website on my VPS. Is this how heaven feels like?

The Lightsail plan I chose costs 3.50 USD a month and offers 512 MB Memory, 1 Core Processor, 20 GB SSD Disk, 1 TB Transfer. This plan comes, among other things, with a free static IP address4.

By default, a Lightsail instance comes with a dynamic public IP address that changes every time the instance is stopped and restarted. This is not optimal, because one doesn’t want to update their Domain Name System (DNS) records5 every time the instance is rebooted. In order to solve this problem, I attached a static IP address to my instance. 6

I now had two of the three ingredients needed to create a website, namely a server and a CMS, but I was still missing a domain name. No problem! A domain name can be easily registered with AWS Route537. I chose michelepariani.com for 12 USD a year. I then routed traffic for my domain name to my Lightsail instance by adding a record to the DNS of my domain8.

I hope you liked this post. If you have any question, feel free to leave a comment in the comment section. Never stop learning!