XSS Attack: How Does This Attack Happen on Websites?

XSS Attack: How Does This Attack Happen on Websites?

XSS Attack: How Does This Attack Happen on Websites?
38 min read

Modern websites do more than display information. They allow users to interact through different features, such as comment sections, search forms, profile pages, and login systems.

These features make websites more dynamic and easier to use. However, every feature that accepts user input can also become a security weakness if it is not handled properly.

One of the common security threats in web application development is Cross-Site Scripting (XSS).

XSS is a type of attack that allows attackers to inject malicious code, usually JavaScript, into a website. If the code runs in another visitor's browser, attackers may be able to misuse user sessions, access certain information, or manipulate the appearance of a web page.

The problem is that an XSS attack does not always look suspicious. A normal-looking comment, message, or link could become a way to execute malicious code.

In this article, we will explain what XSS is, how the attack works, its common types, the risks involved, and how developers can protect websites against it.

1. What Is XSS (Cross-Site Scripting)?

Cross-Site Scripting, commonly known as XSS, is a web application security vulnerability that allows attackers to inject malicious code into a website. The injected code is then executed by another user's browser.

This vulnerability usually takes advantage of weaknesses in how an application processes and displays data provided by users.

To understand XSS, we first need to look at how websites display user input.

For example, imagine a website with a comment section. Visitors can write comments, and the website stores and displays those comments to other visitors.

If the website does not handle the submitted data safely, someone could insert HTML or JavaScript code into a comment. When another visitor opens the page, their browser may execute the injected code.

Here is a simple JavaScript example:

alert('This website has an XSS vulnerability!');

If this code is inserted into a page and the browser treats it as JavaScript, an alert box will appear.

This example is only intended to demonstrate how XSS works. In real attacks, injected scripts may be used for more harmful purposes.

Why is it called Cross-Site Scripting?

The term describes an attack in which scripts are injected into a website and executed within the context of the website being visited.

XSS does not necessarily require attackers to take control of the web server directly. Many XSS attacks work through the browsers of website visitors.

2. How Does an XSS Attack Happen?

At its core, XSS happens when a website receives user input and displays that input without applying the appropriate security measures.

Here is a simplified explanation of how an XSS attack works:

  1. An attacker finds a website feature that accepts user input, such as a comment form.

  2. The attacker submits input containing malicious code.

  3. The website stores or forwards the input without proper protection.

  4. Another visitor opens a page that displays the submitted content.

  5. The browser executes the injected script because the page does not handle the input safely.

  6. The script may perform actions based on the context and permissions available to that page.

For example, imagine a website with a comment feature built using PHP.

Here is an unsafe implementation:

<?php

$comment = $_POST['comment'];

echo "<div class='comment'>";
echo $comment;
echo "</div>";

?>

In this example, the comment is displayed directly using echo.

The problem is that the application does not encode the data before inserting it into the HTML output.

If someone submits HTML or JavaScript code, the browser may interpret it as part of the page rather than ordinary text.

For example, someone could submit the following test input:

<script>
    alert('XSS Detected!');
</script>

If the website displays this input without protection, the browser may execute the JavaScript inside the page.

A safer PHP implementation would look like this:

<?php

$comment = $_POST['comment'] ?? '';

echo "<div class='comment'>";
echo htmlspecialchars(
    $comment,
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8'
);
echo "</div>";

?>

The htmlspecialchars() function converts special HTML characters into safe representations before displaying them as text.

This prevents the browser from interpreting the submitted input as executable HTML or JavaScript.

Keep in mind that this example applies to data displayed as text inside HTML. If data is inserted into JavaScript, URLs, HTML attributes, or other contexts, the appropriate encoding method must be used for that specific context.

3. Types of XSS Attacks

XSS attacks come in several forms, depending on how malicious code is introduced and executed.

There are three main types that developers should understand.

A. Stored XSS (Persistent XSS)

Stored XSS occurs when malicious code is stored on a server or in a database and later displayed to website visitors.

This type can be particularly dangerous because the injected code may be executed repeatedly whenever users open the affected page.

For example, imagine a website that allows visitors to post comments.

An attacker submits content containing malicious code. If the website stores the comment without proper protection, the code remains in the database.

When other visitors open the comment page, their browsers may execute the injected script.

Website features that may become targets of Stored XSS include:

  • Comment sections.

  • Discussion forums.

  • User messages.

  • User profiles.

  • Product reviews.

  • User-generated articles.

Example scenario:

An online store provides a product review feature. Customers can rate products and write comments.

If the application does not properly secure submitted content, an attacker may insert malicious code through a product review.

Every visitor who opens that product page could potentially be affected.

B. Reflected XSS (Non-Persistent XSS)

Reflected XSS occurs when data from a user's request is immediately returned by the server in a web page without proper processing.

Unlike Stored XSS, the malicious input is usually not permanently stored in a database.

This type of attack often uses URLs or request parameters that are displayed again by the website.

For example, imagine a website with a search feature:

https://example.com/search?q=website

The website displays the search term entered by the visitor.

If the search parameter is displayed directly without appropriate encoding, an attacker may create a link containing malicious input.

When a victim opens the link, the server may return the input in the page and cause the browser to execute the script.

Reflected XSS attacks often use links shared through:

  • Email.

  • Private messages.

  • Social media.

  • Online forums.

  • Websites with search features or URL parameters.

Because this attack depends on a request made by the victim, attackers generally need to convince someone to open a specific link.

C. DOM-Based XSS

DOM-Based XSS occurs when JavaScript running in the browser processes untrusted data in an unsafe way.

DOM stands for Document Object Model. In simple terms, it is the structure that browsers use to represent the elements of an HTML page.

Unlike the previous two types, DOM-Based XSS can happen entirely in the browser without requiring the server to return the malicious code.

Consider this risky JavaScript example:

const params = new URLSearchParams(
    window.location.search
);

const name = params.get('name');

document.getElementById('greeting').innerHTML =
    'Hello ' + name;

In this example, the name parameter from the URL is inserted directly into an HTML element using innerHTML.

If the parameter contains malicious HTML or script content, the browser may process it as part of the page.

A safer implementation would be:

const params = new URLSearchParams(
    window.location.search
);

const name = params.get('name');

document.getElementById('greeting').textContent =
    'Hello ' + name;

The difference is the use of textContent instead of innerHTML.

textContent displays the value as ordinary text, so the browser does not interpret the input as HTML.

DOM-Based XSS is commonly found in websites that use JavaScript to update page content dynamically.

4. What Are the Risks of XSS Attacks?

XSS is not just a technical issue that developers need to understand. It can create serious problems for website owners and visitors.

Here are some of the most common risks.

A. User Information Theft

Malicious scripts may be used to access information available on a web page.

For example, attackers may attempt to collect information displayed on the page, form data, or other information accessible to JavaScript.

This information could be misused for different purposes, including fraud and account abuse.

However, JavaScript cannot access every piece of browser information. Cookies protected with the HttpOnly attribute, for example, cannot be read directly through JavaScript.

B. Login Session Theft or Misuse

One of the risks of XSS is the misuse of an active user session.

If a website does not properly protect its session management and cookies, attackers may be able to abuse the victim's session to perform actions as that user.

This could result in unauthorized access to user accounts.

The risk becomes more serious when the affected account belongs to a website administrator.

C. Website Content Manipulation

XSS can be used to modify elements or the appearance of a web page opened by a victim.

For example, attackers may:

  • Display fake messages.

  • Change displayed information.

  • Hide certain content.

  • Display fake login forms.

  • Redirect visitors to other pages.

These changes may make visitors believe that false information comes from the legitimate website.

D. Phishing and Online Fraud

Attackers may use XSS to display fake content inside a website that visitors already trust.

For example, a website may display a fake login form that looks similar to its original login page.

Visitors may not realize that the form is not part of the legitimate system.

If users enter their login information, the data could potentially be sent to unauthorized parties.

E. Administrator Account Abuse

If an XSS attack affects a user with elevated permissions, such as a website administrator, the consequences may become more serious.

Attackers may be able to misuse the permissions available to that account to perform certain actions, such as changing website content or settings.

This shows that XSS is a threat not only to regular visitors but also to website administrators.

F. Loss of Visitor Trust

A website affected by a security attack may lose the trust of its visitors.

Users may become concerned about accessing the website, creating accounts, or making transactions.

For businesses, this may lead to:

  • Reduced customer trust.

  • Financial losses.

  • Business interruptions.

  • System recovery costs.

  • Damage to company reputation.

This is why website security should be an essential part of application development.

5. How to Prevent XSS Attacks

The good news is that XSS can be prevented by following secure web development practices.

Here are several important steps developers should implement.

A. Apply Output Encoding

Output encoding is one of the most important methods for preventing XSS.

It works by converting certain characters into safe representations before displaying data to users.

For example, the < character can be converted into &lt;, while the > character can be converted into &gt;.

This makes the browser display those characters as text instead of interpreting them as HTML tags.

Here is an example using PHP:

<?php

$userInput = $_POST['comment'] ?? '';

echo htmlspecialchars(
    $userInput,
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8'
);

?>

Using htmlspecialchars() helps protect output when data is displayed as text inside HTML.

However, different contexts require different encoding rules.

For example:

  • HTML body content requires HTML encoding.

  • HTML attributes require attribute encoding.

  • JavaScript values require appropriate JavaScript encoding.

  • URLs require URL encoding and scheme validation.

Do not assume that one encoding function can be used safely in every situation.

B. Validate and Sanitize User Input

Every value received from users should be checked before the application processes it.

Validation ensures that submitted data follows the expected format.

For example:

  • Names should only accept permitted characters.

  • Email addresses should follow a valid format.

  • Phone numbers should follow defined rules.

  • Comments should have a maximum length.

  • URLs should only accept permitted schemes.

If a website allows users to submit HTML content, such as formatted articles or descriptions, HTML sanitization is also necessary.

Sanitization is different from validation. Its purpose is to remove or restrict unsafe HTML elements and attributes.

For this purpose, developers should use a well-tested HTML sanitizer library instead of building their own HTML filtering system.

Remember that input validation alone is not enough to prevent XSS. Output encoding is still necessary whenever data is displayed.

C. Avoid Using innerHTML with Untrusted Data

In JavaScript, innerHTML allows developers to insert or modify HTML content inside an element.

However, using innerHTML becomes risky when the inserted value comes from users or other untrusted sources.

Here is an unsafe example:

const comment = userInput;

document.getElementById('comment').innerHTML =
    comment;

If userInput contains harmful HTML, the browser may process it as part of the page.

Use textContent when you only need to display text:

const comment = userInput;

document.getElementById('comment').textContent =
    comment;

This makes the browser treat the content as ordinary text.

If your application genuinely needs to display dynamic HTML, make sure the content is sanitized using a trusted library first.

D. Use Frameworks with XSS Protection

Modern frameworks generally provide built-in mechanisms that help developers avoid XSS.

Some examples include:

  • Laravel Blade.

  • Yii2 HTML Helper.

  • React.

  • Vue.js.

  • Angular.

For example, Laravel Blade automatically escapes output when using this syntax:

{{ $userInput }}

In Yii2, developers can use the HTML Helper:

<?= \yii\helpers\Html::encode($userInput) ?>

In React, text displayed through JSX is also escaped by default:

function Comment({ message }) {
    return <p>{message}</p>;
}

However, developers must still be careful when using features that bypass the default escaping mechanisms, such as React's dangerouslySetInnerHTML or raw HTML features in other frameworks.

Using a framework does not automatically make a website free from XSS. Developers still need to understand how the features they use work.

E. Implement Content Security Policy (CSP)

Content Security Policy, or CSP, is a browser security mechanism that helps restrict which resources a web page is allowed to load and execute.

With CSP, website owners can define permitted sources for JavaScript, CSS, images, and other resources.

For example, a website can restrict JavaScript so that it only comes from approved sources.

Here is a simple CSP header:

Content-Security-Policy: default-src 'self'; script-src 'self';

This configuration restricts resources by default to the website's own origin and only allows scripts from that origin.

CSP can help reduce the impact of certain XSS attacks, but it is not a replacement for output encoding and sanitization.

For production websites, CSP policies should be adjusted to match application requirements. Nonces or hashes can also be considered to allow specific scripts in a more controlled way.

F. Use Secure Cookie Settings

If your website has a login system, cookie configuration is important.

There are several cookie attributes that can help improve security.

HttpOnly

Prevents JavaScript from directly reading the cookie. This helps protect session cookies from being stolen through scripts.

Secure

Ensures that the cookie is only sent over HTTPS connections.

SameSite

Helps restrict when cookies are sent with cross-site requests and provides additional protection against certain attacks.

Here is an example of PHP cookie configuration:

<?php

session_set_cookie_params([
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Lax'
]);

session_start();

?>

Make sure the Secure attribute is used when the website runs over HTTPS.

Keep in mind that HttpOnly cookies do not make a website completely immune to XSS. A malicious script that successfully runs may still perform actions through the user's session, even if it cannot directly read the cookie.

G. Perform Regular Security Testing

Security testing should be performed before and after a website is published.

Developers should review every part of the website that accepts or displays user-provided data.

Important areas to check include:

  • Comment forms.

  • Search features.

  • User profile pages.

  • Registration forms.

  • Login systems.

  • Content submission features.

  • Administrator pages.

  • URLs that use request parameters.

Developers can also use security testing tools such as:

  • OWASP ZAP.

  • Burp Suite.

  • Browser Developer Tools.

Testing should only be performed on websites you own or systems for which you have official permission.

6. How to Identify a Website with an XSS Vulnerability

Not every XSS attack produces obvious warning signs.

However, several conditions may indicate that a website needs further security investigation.

A. User Input Is Displayed Without Encoding

If a website displays comments, names, or user-generated content directly without encoding, that area should be reviewed.

Make sure data from users is not treated as executable HTML or JavaScript.

B. The Website Uses innerHTML with Untrusted Sources

Review JavaScript code that uses innerHTML, outerHTML, or other functions that insert HTML into a page.

Using these functions is not always wrong, but they become risky when the data comes from untrusted sources and has not been sanitized.

C. Unexpected Content Appears on the Website

If a website displays unfamiliar HTML elements, messages, or unexpected visual changes, investigate the stored content and application code.

D. Users Report Unusual Behavior

Visitors may report that the website displays strange messages, opens other pages automatically, or shows unexpected visual changes.

These reports should be followed by a security investigation.

E. Security Testing Reports Vulnerabilities

Use security testing tools to inspect pages and features that accept user input.

In addition to automated testing, perform code reviews to identify unsafe output handling.

The absence of these warning signs does not guarantee that a website is secure. Code reviews and security testing are still necessary.

7. Understanding OWASP and the Importance of Website Security

OWASP (Open Worldwide Application Security Project) is an organization that provides guidelines, documentation, and learning resources related to application security.

One of its most popular references is the OWASP Top 10, a list of important web application security risk categories that developers should understand.

XSS is an example of a vulnerability covered by OWASP security guidance, particularly in relation to improper handling and display of untrusted data.

Developers can use several OWASP resources to learn how to prevent XSS attacks, including:

  • OWASP Top 10.

  • OWASP Cross Site Scripting Prevention Cheat Sheet.

  • OWASP Web Security Testing Guide.

  • OWASP Application Security Verification Standard (ASVS).

By understanding these guidelines, developers can improve application security from the planning and development stages through to testing.

Conclusion

XSS (Cross-Site Scripting) is an important security threat that developers should understand when building websites.

This attack occurs when an application fails to handle user-provided data properly, allowing a browser to execute malicious code inside a web page.

There are three common types of XSS: Stored XSS, Reflected XSS, and DOM-Based XSS. Each type works differently, but all of them can create risks for website visitors and owners.

To prevent these attacks, developers should apply output encoding, validate and sanitize user input, avoid using innerHTML with untrusted data, use framework security features, implement Content Security Policy, and perform regular security testing.

The most important thing to remember is that security should never be treated as an additional feature. It should be part of every stage of website development.

By applying secure coding practices from the beginning, developers can build websites that are safer, more reliable, and more trustworthy.

Build Secure Websites with Applicanity

Applicanity helps businesses build websites and digital applications with a focus on development quality, performance, and system security.

A good website is not only about attractive design and complete features. It should also have a strong technical foundation that protects data and supports long-term business needs.

Visit Applicanity to learn more about our website development and digital solution services.

Recommended for you