Understanding Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS) Attacks: Examples and Best Practices.

DSL
5 min readDec 21, 2022

--

Image credited to https://gridinsoft.com/blogs/csrf-vs-xss/

Online security holes such as Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS) allow attackers to steal personal information or perform tasks on the victim’s behalf.

Cross-Site Request Forgery (CSRF)

A malicious website, email, or software can carry out an unanticipated action on a trusted website for which the user is currently authenticated by using a technique known as cross-site request forgery (CSRF).
An attacker could take advantage of this to carry out tasks like money transfers or account settings on the victim’s behalf.

For instance, the attacker might send the victim a link that appears to be a login form, but upon submission, demands a money transfer from the victim’s bank account to the attacker’s account.

The followings are example of CSRF attack through HTML and Javascript. Notice the input type is set to hidden in both examples.

<!-- Malicious form that transfers money from the victim's account to the attacker's account -->
<form action="https://bank.example.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker@example.com">
<input type="hidden" name="amount" value="1000">
<input type="submit" value="Transfer">
</form>
// Using the fetch() function
fetch("https://bank.example.com/transfer", {
method: "POST",
body: "to=attacker@example.com&amount=1000",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});

// Using a form element
const form = document.createElement("form");
form.action = "https://bank.example.com/transfer";
form.method = "POST";

const toInput = document.createElement("input");
toInput.type = "hidden";
toInput.name = "to";
toInput.value = "attacker@example.com";
form.appendChild(toInput);

const amountInput = document.createElement("input");
amountInput.type = "hidden";
amountInput.name = "amount";
amountInput.value = "1000";
form.appendChild(amountInput);

document.body.appendChild(form);
form.submit();

Websites can take precautions like requiring a unique token to be included with every sensitive activity to defend against CSRF attacks. The server examines this token, which is frequently referred to as a “CSRF token,” to make sure the request is valid. Other precautions include using same-site cookies and inspecting the origin and referrer headers of incoming requests.

Backend protection implementation

For example, here is an illustration of how a CSRF token could be used in a JavaScript backend application (using Node.js and Express):

const express = require("express");
const csrf = require("csurf"); // This module provides CSRF protection

const app = express();

// A csrf middleware to add a CSRF token to response
app.use(csrf());

// Generate a CSRF token
app.get("/form", (req, res) => {
const token = req.csrfToken();
res.render("form", { csrfToken: token });
});

// Validate the CSRF token for sensitive posting
app.post("/transfer", (req, res) => {
if (!req.body.csrfToken || req.body.csrfToken !== req.csrfToken()) {
// If the token is invalid, return an 400 error
return res.status(400).send("Invalid CSRF token");
}
// If the token is valid, proceed with the action successfully
transferFunds(req.body.to, req.body.amount);
res.send("Funds transferred");
});

Frontend protection implementation

The CSRF token can be used on the frontend as a hidden field or query parameter in a form or other sensitive operation. Here is an illustration of a form using the CSRF token:

<form action="/transfer" method="POST">
<input type="hidden" name="csrfToken" value="{{ csrfToken }}">
<label for="to">To:</label>
<input type="text" id="to" name="to">
<label for="amount">Amount:</label>
<input type="number" id="amount" name="amount">
<button type="submit">Transfer</button>
</form>

In this illustration, the CSRF token is placed in the form as a hidden field and passed as a template variable. The token is added to the request body and validated on the backend when the form is submitted.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) attacks involve injecting malicious code into a website or web application in order to execute it in the victim’s web browser. This can be accomplished by including a script element on the page or by inserting HTML that contains a script using the innerHTML attribute. XSS attacks can be used to steal sensitive information, such as login credentials, or to perform unauthorized actions on behalf of the victim.

Here is an illustration of an XSS attack in action:

// Inject a script into a website
document.body.innerHTML += `<script>
alert("This is an XSS attack!");
</script>`;

In this illustration, the script is added to the body element’s innerHTML attribute to be injected into the HTML of the webpage. An alert message is presented after the script has been run and the page has loaded.

Websites can sanitize user input by removing potentially harmful components, like script tags, before saving or displaying it on the page to defend against this kind of attack.

The following is an example of sanitation in Javascript. Keep in mind that this is only one of the many examples.

// This function sanitizes user input by removing any HTML tags
function sanitizeInput(input) {
// Use a regular expression to remove any HTML tags
return input.replace(/<[^>]*>/g, '');
}

// Example usage
const userInput = '<script>alert("XSS attack")</script>';
const sanitizedInput = sanitizeInput(userInput);
console.log(sanitizedInput); // Output: "alert("XSS attack")"

I hope this essay was helpful in explaining the ideas behind CSRF and XSS attacks and in providing some instances of how they might be executed and thwarted. Always use caution when disclosing critical information online, and keep an eye out on your accounts for any suspicious activity.

Conclusion

Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS) are two kinds of internet security flaws that could let attackers steal personal data or carry out tasks on the victim’s behalf on a reputable website. While XSS attacks entail introducing malicious code into a website to collect information or carry out operations, CSRF attacks take place when a victim is duped into sending a request to a trusted website.

Websites can use methods like using same-site cookies, needing a special token (sometimes known as a “CSRF token”) for sensitive operations, and checking the origin and referrer headers of incoming requests to defend against these kinds of attacks. In order to secure their users and websites, developers must be aware of these threats and take the necessary precautions.

Additional content

Here is a React-based demo app designed to demonstrate the concepts of Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS) attacks. This demo app, which can be found on GitHub at https://github.com/dsl2022/csrf-xss-demo, shows how these types of vulnerabilities can be exploited and the potential consequences for users and websites. You can also see a live demo of the app by visiting the link https://csrf-xss-demo.vercel.app/. I hope that this project will help others to better understand the importance of online security and the steps that can be taken to protect against these types of attacks.

--

--

DSL

Sr software engineer. Love in Go, JavaScript, Python, and serverless AWS. Follow me for tech insights and experiences. follow me on twitter @terraformia