Cross Site Scripting

Cross Site Scripting - How a Website is Hijacked

XSS, SQL Injection, XMLrpc - when a WordPress security update is released, you'll find mostly cryptic acronyms in the update reports. Even if it is clear that these updates are necessary and the plus in security is very pleasing, it is important to understand what is behind these vulnerabilities. Because only if you understand which gaps the updates close, you can also make an informed decision. So today we're going to dedicate ourselves to Cross Site Scripting, or XSS, which is by far the most common complex attack on WordPress websites.

Hacker attacks can be compared to a burglary. Brute force attacks are more like crowbar attacks. Criminals use the tool bluntly, until the door or window breaks open. Attacks on XSS vulnerabilities, on the other hand, are sophisticated: The criminals know exactly where to start and gain targeted access to a website.

Cross-site scripting is the targeted exploitation of security vulnerabilities in websites. Malicious scripts are injected into a trusted context (your website!). Similar to a stowaway on a ship, this malicious code uses your website as a vehicle to pursue its own goals.

In the worst case, confidential information is thus obtained, or even access to the computer of the victimized user. Such attacks are not exactly rare: A good half of the vulnerabilities in plugins found by the security provider Wordfence in 2015 and 2016 were cross-site scripting vulnerabilities. Often, an XSS attack then forms the basis for further attacks, such as spam, phishing or even DDoS attacks. That's why I'll show you today how exactly Cross Site Scripting works, what types of attacks there are and how dangerous the attacks are.

Cross Site Scripting has a basic principle

Cross-site scripting works on the basic principle of exploiting a loophole and injecting malicious code onto your website. It is a danger whenever a web application forwards entered data to the web browser without checking for possible script code. A good example of such a web application is a support chat.

The malicious scripts can reach the server via the web application itself. From there, the malicious code sooner or later ends up on the affected clients. A good example of such an XSS vulnerability is the bug discovered in July 2016 in the image meta-infos in WooCommerce 2.6.2. Due to a bug, it was possible to inject HTML code into the image meta-descriptions from the outside. Any device on which the affected image was now viewed more closely (e.g. by clicking on the image) would be at risk of being attacked. Thus, among other things, the computers on which this image was viewed could have been infected with a virus.

"*" indicates required fields

I would like to subscribe to the newsletter to be informed about new blog articles, ebooks, features and news about WordPress. I can withdraw my consent at any time. Please note our Privacy Policy.
This field is for validation and should not be changed.

Popular trick for cross site scripting - manipulated forms

XSS can also make it possible to replace harmless forms with manipulated ones. These forms then collect the victims' data (on your website!). By the way, even SSL encryption cannot protect against this. HTTPS "only" means that the connection between server and client is encrypted. However, if the form itself is manipulated, even an encrypted connection is useless.

As with other types of attacks, the goal in most cases is monetization. In concrete terms, this means that either data is stolen and later sold, or infected websites are integrated into a so-called botnet, which is then rented out.

3 types of XSS

Cross site scripting attacks can be roughly divided into three types:

  • reflected cross site scripting
  • persistent cross site scripting
  • DOM-based or local cross site scripting

Roughly speaking, XSS attacks work as follows: Malicious code is injected where input is expected from the client (for example, during a page-internal search). As part of the server's response, the malicious code is then executed on the client, i.e. in the browser. And that is exactly where the damage is done, for example, data is stolen.

Reflective cross site scripting

Some input, such as search queries, is reflected by the server. This means, for example, that after you enter "test" in the search box, the website outputs "You searched for test". So the entered text becomes part of the server's response.

Exactly this is exploited cleverly: If a malicious script is sent to the web server instead of a search term, the website can be manipulated to ultimately execute it. This type of attack is also known as non-persistent. This means that the malicious code is only temporarily injected into the website in question, but is not stored.

In July 2017, such a vulnerability was found in plugin WP Statistics (and already fixed on the same day!). An input value on the site 'wps_visitors_page' was forwarded unchecked, resulting in a vulnerability due to reflected XSS. Thus, if an admin had previously clicked on a suitably manipulated link, a website could be hacked.

Cross Site Scripting Reflected XSS
This is what a reflected cross-site scripting attack can look like.

It works like this: links with manipulated parameters are spread to potential victims. Without knowing it, the victim clicks on the link and sends a "manipulated" request to the server, and the malicious code is executed along with the server's response. Since the code - unlike persistent XSS - is not stored anywhere, it must be distributed en masse to potential victims. This can happen, for example, via e-mails or social networks.

Persistent cross site scripting

In persistent XSS, the malicious scripts are stored on the web server and delivered each time they are called by a client. Predestined for this are web applications that store user data on the server side and then output it without verification or coding (including forums). This type of scripting can be particularly dangerous for highly frequented blogs and forums, as the malware can spread quickly here due to the large number of users.

This graphic shows a possible sequence of a persistent cross-site scripting attack.
Sequence of a persistent cross site scripting attack. Source: Blog SAP

Example: In a forum, posted posts are stored in a database. It is not uncommon for these to be stored unchecked and unencrypted. This opportunity is readily exploited and allows a malicious script to be added to a completely normal forum post (in a simple manner using a comment). Users either receive the respective link to the post via email or accidentally get to the corresponding entry and execute the script by calling the post. Now, for example, affected clients could be "spied on" or added to a botnet for further attacks.

DOM-based or local cross site scripting

Unlike persistent and reflected XSS, DOM (Document Object Model) based cross site scripting works by executing client-side scripts. This means that the server is not aware of such an attack and server-side security measures do not help either.

A well-known example of such a gap was the case of the genericon package. The genericon package is an icon set that is used by many plugins. It was possible to inject malicious code via an HTML file in this icon set.

After entering this URL, a javascript alert appeared. This is proof that the javascript code entered could be used to manipulate the respective site  .
After entering this URL, a JavaScript alert appeared. This is proof that JavaScript code entered could be used to manipulate the website in question. Source:

However, a prerequisite for a DOM-based XSS attack is that users click on a manipulated URL. By calling this URL, the malicious code can be executed through a gap in a client-side script. Among other things, the fact that a link must be clicked first makes DOM-based XSS a somewhat more difficult and therefore less likely type of attack.

Cross Site Scripting Local XSS
Example of a local cross-site scripting attack.

Example: The manipulated URL is clicked and sends a request to the web application. The application responds by passing the script code (which is incorrect but not manipulated) to the browser to start execution of the script. The manipulated parameters from the URL are now interpreted in the client's browser as part of the script and executed. The website displayed in the browser is thus changed and users now see the manipulated website without realizing it.

Measures against Cross Site Scripting

The best measures against cross-site scripting attacks are simple to implement. It is best to rely on regular updates, firewalls and whitelists. Secondarily, the output of the server can also be secured.

Regular updates

The vulnerabilities through which the malicious code is infiltrated are either in the WordPress core, in plugins or in themes. This is exactly why regular updates of all these components are so important. Because in these updates, the vulnerabilities that have been found so far are fixed.

It also makes sense to regularly read the details of updates to get a feel for which security vulnerabilities are regularly closed via the updates. For the maintenance and security updates of the WordPress core, this information is documented for example in the WordPress blog.

Firewalls and whitelists against simple XSS attacks

Another simple protective measure against XSS attacks are so-called web application firewalls, or WAF. These firewalls are the heart of large security plugins and are fed with the latest vulnerabilities by the respective research team of the manufacturer. In general, a WAF is a procedure that protects web applications from attacks via the Hypertext Transfer Protocol (HTTP).

However, even these protection mechanisms have their limits. This is because in some XSS attacks, the attack takes place via the database. Therefore, checking user input for malicious code is one of the central security mechanisms in the fight against XSS attacks. For example, the content of comments is scanned for suspicious character strings and sorted out if necessary.

The data output should also be secured

Regelmäßige Updates schließen vorhandene XSS Sicherheitslücken und Firewalls sowie Whitelists versuchen Schadcode auszufiltern, bevor dieser den Webserver erreicht und die Website infizieren kann. Doch sollte auch die Datenausgabe entsprechend gesichert werden. Die meisten Programmier- und Skriptsprachen, wie PHP, Perl oder JavaScript, besitzen hierfür bereits vordefinierte Funktionen zur Zeichenersetzung bzw. -maskierung. Diese sorgen dafür, dass „problematische“ HTML Metazeichen wie <> und & durch harmlose Zeichenreferenzen ersetzt werden. So wird verhindert, dass der Schadcode aktiv werden kann. Auch sollte der Code mithilfe von sogenannten sanitization libraries bereinigt werden. Hierfür wird ein Plugin auf dem Server installiert und zusätzlicher Code in den Quellcode deiner Website eingebunden. Der folgende Codeschnipsel sorgt dann zum Beispiel dafür, dass <class> zu den erlaubten Attributen hinzugefügt wird:

var sanitizer = new HtmlSanitizer();
var sanitized = sanitizer.Sanitize(html);

Programming skills are required to implement this. This data output protection is easy to implement for someone with this knowledge.

A healthy dose of scepticism: How users protect themselves

But not only the website itself, also the clients (i.e. your web browser) are affected by XSS attacks. Many XSS attacks can already be prevented by a critical and careful handling in connection with "foreign" links. Among other things, there is the possibility to use NoScript addons. These prevent the execution of scripts, i.e. the harmful lines of code that steal data, among other things.

If you want to be on the safe side, you can also avert client-side cross-site scripting simply by disabling JavaScript support in the browser. Because if this so-called active scripting is deactivated, certain types of XSS attacks no longer have a chance, since the malicious applications are not even started. However, most modern websites then no longer "work" properly - or in the worst case, no longer work at all. So here you have to weigh up the aspects of security and usability. If you are interested in this option, you can find it in your browser settings.


XSS vulnerabilities are among the most frequent gateways for malicious code. And often a corresponding attack forms the basis for further attacks, such as spam, phishing or DDoS attacks. Your website is hijacked and misused for other purposes. XSS is therefore not without danger, which is why appropriate protection is important.

Reflected and persistent XSS are particularly common, as local cross-site scripting is more complex and difficult to implement. Websites that forward entered user data to the web browser without checking for possible malicious code are particularly at risk. Finding such gaps, however, is not that easy. In principle, this is precisely the task of security providers such as sucuri and Co, who are constantly developing their security measures.

But of course, there is also a way for normal WordPress to protect itself from these attacks. Updates of all WordPress components are among others a simple but very effective measure. If you keep your plugins and themes up to date and use a WAF, you've already taken a big step in the right direction. If you also use whitelists for incoming and outgoing code, you have already secured your website excellently. However, the last two measures in particular are not easy to implement without programming knowledge.

Compared to the rather primitive brute force attacks, the more complex XSS attacks are unfortunately still relatively often successful. However, there are significantly fewer of these so-called complex attacks than there are brute force attacks on WordPress websites. Nevertheless, you should make it as difficult as possible for these attacks. A successful hack not only costs time and money for the removal of the scripts, but can also endanger your position in search engines.

Did you like the article?

With your rating you help us to improve our content even further.

Write a comment

Your e-mail address will not be published. Required fields are marked with *