Cross-origin resource sharing (CORS)
1. What is CORS?
Cross-Origin Resource Sharing (CORS) is a security mechanism implemented by web browsers to control how web pages from one origin/domain can request resources from another origin/domain. It's a set of HTTP headers that allow or restrict cross-origin requests made by client-side JavaScript code.
2. What is SOP (Same-Origin Policy)?
The Same-Origin Policy (SOP) is a fundamental security concept in web browsers that restricts how documents or scripts from one origin/domain can interact with resources from another origin/domain. Under SOP, web browsers prevent cross-origin requests initiated by client-side scripts, which helps mitigate various security threats such as Cross-Site Scripting (XSS) and data theft.
3. Misconfiguration Types:
- Allowing All Origins ( * ): This misconfiguration allows any domain to access resources on the server, bypassing SOP restrictions.
- Allowing Specific Origins Without Proper Validation: Allowing specific domains without proper validation can lead to the exposure of sensitive data to unauthorized origins.
- Incorrect Handling of Credentials: Misconfiguring CORS to allow credentials (cookies, authorization headers, etc.) without proper validation can lead to security vulnerabilities.
4. Impact:
- Data Exposure: Misconfigured CORS policies can allow unauthorized domains to access sensitive data, leading to data breaches.
- Data Manipulation: Attackers can exploit misconfigured CORS to perform unauthorized actions or modify data on behalf of users.
- Information Leakage: Improper CORS configuration can leak sensitive information about the server or application, aiding attackers in crafting more sophisticated attacks.
5. Remediation:
- Proper CORS Configuration: Configure CORS headers on the server to restrict access to trusted origins only.
- Origin Whitelisting: Explicitly whitelist trusted origins and validate incoming requests against the whitelist.
- Use Credentials Carefully: Avoid allowing credentials for cross-origin requests unless necessary, and ensure proper validation of credentials.
- The malicious website sends a GET request to
vulnerable-website.com
for sensitive victim data.
- The vulnerable server responds with an
Access-Control-Allow-Origin
header allowing the malicious website domain (https://malicious-website.com
) to access the data.
- The server also allows credentials (
Access-Control-Allow-Credentials: true
) without proper validation, potentially exposing sensitive user session information.
Practice:
- mkdir cors
- cd cors
- npm init -y
- npm install express cors
- Create a server.js file, paste the below code, and save
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.get('/', (req, res) => {
res.send('CORS misconfiguration Vulnerability Created By ABINESH | Pentester');
});
app.get('/api/data', (req, res) => {
const sampleData = [
{ id: 1, name: 'Abinesh', age: 21, email: 'abinesh@hacker.com' },
{ id: 2, name: 'Althaf', age: 21, email: 'althaf@hacker.com' },
{ id: 3, name: 'Vasa', age: 21, email: 'vasa@cloud.com' },
{ id: 4, name: 'U1', age: 20, email: 'uvanay@hacker.com' }
];
res.json(sampleData);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
- Run the server.js using node server.js
- Create one index.html page
<!DOCTYPE html>
<html>
<head>
<title>CORS Misconfiguration Test</title>
<style>
button {
padding: 12px 24px;
font-size: 16px;
font-weight: bold;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 5px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s ease;
}
button:hover {
background-color: #45a049;
}
.button-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
</style>
</head>
<body>
<div class="button-container">
<button onclick="fetchData()">Fetch Data</button>
</div>
<script>
async function fetchData() {
try {
const response = await fetch('http://localhost:3000/api/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
</script>
</body>
</html>
- Open the HTML page and click fetch
- Keep an eye on the network tab.
Remediation:
const express = require('express');
const cors = require('cors');
const app = express();
const allowedOrigins = ['https://abineshm.netlify.app/'];
const corsOptions = {
origin: function(origin, callback) {
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
callback(new Error('CORS Remediated, Only allowed for trusted domain.'));
}
}
};
app.use(cors(corsOptions));
app.get('/', (req, res) => {
res.send('CORS misconfiguration vulnerability remediated Created By ABINESH | Pentester');
});
app.get('/api/data', (req, res) => {
const sampleData = [
{ id: 1, name: 'Abinesh', age: 21, email: 'abinesh@hacker.com' },
{ id: 2, name: 'Althaf', age: 21, email: 'althaf@hacker.com' },
{ id: 3, name: 'Vasa', age: 21, email: 'vasa@cloud.com' },
{ id: 4, name: 'U1', age: 20, email: 'uvanay@hacker.com' }
];
res.json(sampleData);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});