csrf-shield 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +74 -0
- package/package.json +30 -0
- package/readme.md +137 -0
- package/readmeTR.md +137 -0
package/app.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const CryptoJS = require('crypto-js');
|
|
2
|
+
|
|
3
|
+
module.exports = function(options = {}) {
|
|
4
|
+
const {
|
|
5
|
+
secret = CryptoJS.lib.WordArray.random(32).toString(),
|
|
6
|
+
timeout = 1000 * 60 * 10,
|
|
7
|
+
} = options;
|
|
8
|
+
|
|
9
|
+
function generateToken(ip, userAgent) {
|
|
10
|
+
const timestamp = Date.now();
|
|
11
|
+
const data = JSON.stringify({ ip, userAgent, timestamp });
|
|
12
|
+
return CryptoJS.AES.encrypt(data, secret).toString();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parseToken(token) {
|
|
16
|
+
try {
|
|
17
|
+
const bytes = CryptoJS.AES.decrypt(token, secret);
|
|
18
|
+
const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
|
|
19
|
+
return JSON.parse(decryptedData);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
throw new Error('Invalid token');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function verifyToken(token, ip, userAgent) {
|
|
26
|
+
try {
|
|
27
|
+
const { ip: tokenIp, userAgent: tokenUserAgent, timestamp } = parseToken(token);
|
|
28
|
+
|
|
29
|
+
if (tokenIp !== ip || tokenUserAgent !== userAgent) {
|
|
30
|
+
return { valid: false, reason: 'Token mismatch' };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (Date.now() - timestamp > timeout) {
|
|
34
|
+
return { valid: false, reason: 'Token expired' };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return { valid: true };
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return { valid: false, reason: error.message };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
middleware: function(req, res, next) {
|
|
45
|
+
req.csrfToken = function() {
|
|
46
|
+
const ip = req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.ip;
|
|
47
|
+
const userAgent = req.headers['user-agent'];
|
|
48
|
+
return generateToken(ip, userAgent);
|
|
49
|
+
};
|
|
50
|
+
next();
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
verifyToken: function() {
|
|
54
|
+
return function(req, res, next) {
|
|
55
|
+
const token = req.body._csrf || req.query._csrf || req.headers['x-csrf-token'];
|
|
56
|
+
|
|
57
|
+
if (!token) {
|
|
58
|
+
return res.status(403).json({ status: false, message: 'CSRF token is missing' });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const ip = req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.ip;
|
|
62
|
+
const userAgent = req.headers['user-agent'];
|
|
63
|
+
|
|
64
|
+
const { valid, reason } = verifyToken(token, ip, userAgent);
|
|
65
|
+
|
|
66
|
+
if (!valid) {
|
|
67
|
+
return res.status(403).json({ status: false, message: `Invalid CSRF token: ${reason}` });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
next();
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "csrf-shield",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CSRF protection middleware for Express.js applications.",
|
|
5
|
+
"main": "app.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"start": "node app.js"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"csrf",
|
|
12
|
+
"protection",
|
|
13
|
+
"middleware",
|
|
14
|
+
"express"
|
|
15
|
+
],
|
|
16
|
+
"author": "Can",
|
|
17
|
+
"homepage": "https://github.com/fastuptime/csrf-shield#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/fastuptime/csrf-shield",
|
|
21
|
+
"license": "MIT"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"crypto-js": "^4.1.1"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# 🚀 `csrf-shield` - CSRF Protection Middleware
|
|
2
|
+
|
|
3
|
+
`csrf-shield` is a middleware for protecting web applications from Cross-Site Request Forgery (CSRF) attacks. It integrates easily with Express.js and ensures that your forms and requests are secure.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
Install `csrf-shield` via npm or Yarn.
|
|
8
|
+
|
|
9
|
+
### NPM
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install csrf-shield
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Yarn
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn add csrf-shield
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🛠️ Usage
|
|
22
|
+
|
|
23
|
+
### Basic Setup
|
|
24
|
+
|
|
25
|
+
Here’s a step-by-step guide on how to set up `csrf-shield` in an Express.js application:
|
|
26
|
+
|
|
27
|
+
1. **Create a basic Express.js application.**
|
|
28
|
+
|
|
29
|
+
2. **Integrate `csrf-shield` middleware for CSRF protection.**
|
|
30
|
+
|
|
31
|
+
3. **Use the CSRF token in your forms and validate it on the server side.**
|
|
32
|
+
|
|
33
|
+
### Example Code
|
|
34
|
+
|
|
35
|
+
Below is a complete example of how to use `csrf-shield` with an Express.js application:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const express = require('express');
|
|
39
|
+
const csrfProtection = require('csrf-shield')({
|
|
40
|
+
secret: 'your_secret_key', // Optional: Set a custom secret key for encryption
|
|
41
|
+
timeout: 1000 * 60 * 10, // Optional: Set token validity period (10 minutes)
|
|
42
|
+
});
|
|
43
|
+
const bodyParser = require('body-parser');
|
|
44
|
+
|
|
45
|
+
const app = express();
|
|
46
|
+
|
|
47
|
+
// Use body-parser middleware to parse form and JSON data
|
|
48
|
+
app.use(bodyParser.urlencoded({ extended: false }));
|
|
49
|
+
app.use(bodyParser.json());
|
|
50
|
+
|
|
51
|
+
// Use CSRF protection middleware
|
|
52
|
+
app.use(csrfProtection.middleware);
|
|
53
|
+
|
|
54
|
+
app.get('/', (req, res) => {
|
|
55
|
+
res.send(`
|
|
56
|
+
<form method="post" action="/login">
|
|
57
|
+
<input type="text" name="username" />
|
|
58
|
+
<input type="password" name="password" />
|
|
59
|
+
<input type="hidden" name="_csrf" value="${req.csrfToken()}" />
|
|
60
|
+
<button type="submit">Login</button>
|
|
61
|
+
</form>
|
|
62
|
+
`);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
app.post('/login', csrfProtection.verifyToken(), (req, res) => {
|
|
66
|
+
res.send('Logged in');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
app.listen(3000, () => {
|
|
70
|
+
console.log('Server started on http://localhost:3000');
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Key Points:
|
|
75
|
+
|
|
76
|
+
- **`secret`**: (Optional) The secret key used for encrypting and decrypting CSRF tokens. It's recommended to set a custom, secure key. If not provided, a random key will be generated automatically.
|
|
77
|
+
- **`timeout`**: (Optional) The validity period of tokens in milliseconds. Default is 10 minutes. Adjust this value according to your application's security needs.
|
|
78
|
+
|
|
79
|
+
### Generating CSRF Tokens
|
|
80
|
+
|
|
81
|
+
To generate CSRF tokens, use the following method:
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
app.use((req, res, next) => {
|
|
85
|
+
req.csrfToken = () => {
|
|
86
|
+
const ip = req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.ip;
|
|
87
|
+
const userAgent = req.headers['user-agent'];
|
|
88
|
+
return csrfProtection.generateToken(ip, userAgent);
|
|
89
|
+
};
|
|
90
|
+
next();
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Token Verification
|
|
95
|
+
|
|
96
|
+
Use the `verifyToken` middleware to verify tokens in your routes:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
app.post('/login', csrfProtection.verifyToken(), (req, res) => {
|
|
100
|
+
res.send('Logged in');
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 🔍 Features
|
|
105
|
+
|
|
106
|
+
- **Automatic Token Generation**: Generates a CSRF token for each request.
|
|
107
|
+
- **Token Verification**: Validates tokens in requests and checks their validity.
|
|
108
|
+
- **Customizable**: Set your own secret key and token validity period.
|
|
109
|
+
|
|
110
|
+
## ⚠️ Why Use This?
|
|
111
|
+
|
|
112
|
+
CSRF attacks exploit the trust a web application has in the user's browser. `csrf-shield` helps prevent these attacks by ensuring that every request with sensitive actions is accompanied by a valid CSRF token.
|
|
113
|
+
|
|
114
|
+
## 📄 API Reference
|
|
115
|
+
|
|
116
|
+
### `csrfShield(options)`
|
|
117
|
+
|
|
118
|
+
- **options.secret**: (Optional) The secret key used for encrypting tokens. A random key is used by default if not specified.
|
|
119
|
+
- **options.timeout**: (Optional) The validity period of tokens in milliseconds. Default is 10 minutes.
|
|
120
|
+
|
|
121
|
+
### `middleware(req, res, next)`
|
|
122
|
+
|
|
123
|
+
- **req.csrfToken()**: Generates a new CSRF token to be used in forms.
|
|
124
|
+
|
|
125
|
+
### `verifyToken()`
|
|
126
|
+
|
|
127
|
+
- **req.body._csrf**: (Optional) Token location in form data.
|
|
128
|
+
- **req.query._csrf**: (Optional) Token location in query parameters.
|
|
129
|
+
- **req.headers['x-csrf-token']**: (Optional) Token location in HTTP headers.
|
|
130
|
+
|
|
131
|
+
## 🛠️ Support & Contributing
|
|
132
|
+
|
|
133
|
+
For issues or contributions, please visit the [GitHub repository](https://github.com/fastuptime/csrf-shield).
|
|
134
|
+
|
|
135
|
+
## 📝 License
|
|
136
|
+
|
|
137
|
+
This project is licensed under the [MIT License](LICENSE.md).
|
package/readmeTR.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# 🚀 `csrf-shield` - CSRF Koruma Middleware'i
|
|
2
|
+
|
|
3
|
+
`csrf-shield`, web uygulamalarını Cross-Site Request Forgery (CSRF) saldırılarından koruyan bir middleware'dir. Express.js ile kolayca entegre edilir ve formlarınızın ve isteklerinizin güvenliğini sağlar.
|
|
4
|
+
|
|
5
|
+
## 📦 Kurulum
|
|
6
|
+
|
|
7
|
+
`csrf-shield` modülünü npm veya Yarn ile projenize ekleyebilirsiniz.
|
|
8
|
+
|
|
9
|
+
### NPM
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install csrf-shield
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Yarn
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn add csrf-shield
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🛠️ Kullanım
|
|
22
|
+
|
|
23
|
+
### Temel Kurulum
|
|
24
|
+
|
|
25
|
+
`csrf-shield`'i Express.js uygulamanıza nasıl entegre edeceğinizle ilgili adım adım bir kılavuz:
|
|
26
|
+
|
|
27
|
+
1. **Temel bir Express.js uygulaması oluşturun.**
|
|
28
|
+
|
|
29
|
+
2. **CSRF koruma middleware'ini entegre edin.**
|
|
30
|
+
|
|
31
|
+
3. **Formlarınızda CSRF token'ını kullanın ve sunucu tarafında doğrulayın.**
|
|
32
|
+
|
|
33
|
+
### Örnek Kod
|
|
34
|
+
|
|
35
|
+
Aşağıda, `csrf-shield`'in Express.js uygulamanızda nasıl kullanılacağına dair tam bir örnek verilmiştir:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const express = require('express');
|
|
39
|
+
const csrfProtection = require('csrf-shield')({
|
|
40
|
+
secret: 'your_secret_key', // Opsiyonel: Şifreleme için özel bir gizli anahtar belirleyin
|
|
41
|
+
timeout: 1000 * 60 * 10, // Opsiyonel: Token geçerlilik süresi (10 dakika)
|
|
42
|
+
});
|
|
43
|
+
const bodyParser = require('body-parser');
|
|
44
|
+
|
|
45
|
+
const app = express();
|
|
46
|
+
|
|
47
|
+
// Form ve JSON verilerini işlemek için body-parser middleware'ini kullanın
|
|
48
|
+
app.use(bodyParser.urlencoded({ extended: false }));
|
|
49
|
+
app.use(bodyParser.json());
|
|
50
|
+
|
|
51
|
+
// CSRF koruma middleware'ini uygulayın
|
|
52
|
+
app.use(csrfProtection.middleware);
|
|
53
|
+
|
|
54
|
+
app.get('/', (req, res) => {
|
|
55
|
+
res.send(`
|
|
56
|
+
<form method="post" action="/login">
|
|
57
|
+
<input type="text" name="username" />
|
|
58
|
+
<input type="password" name="password" />
|
|
59
|
+
<input type="hidden" name="_csrf" value="${req.csrfToken()}" />
|
|
60
|
+
<button type="submit">Login</button>
|
|
61
|
+
</form>
|
|
62
|
+
`);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
app.post('/login', csrfProtection.verifyToken(), (req, res) => {
|
|
66
|
+
res.send('Giriş yapıldı');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
app.listen(3000, () => {
|
|
70
|
+
console.log('Sunucu http://localhost:3000 adresinde çalışıyor');
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Ana Noktalar:
|
|
75
|
+
|
|
76
|
+
- **`secret`**: (Opsiyonel) CSRF token'larını şifrelemek için kullanılan gizli anahtar. Güvenli bir anahtar belirlemeniz önerilir. Belirtilmezse, varsayılan olarak rastgele bir anahtar oluşturulur.
|
|
77
|
+
- **`timeout`**: (Opsiyonel) Token'ların geçerlilik süresi milisaniye cinsinden. Varsayılan olarak 10 dakikadır. Güvenlik ihtiyaçlarınıza göre bu değeri ayarlayabilirsiniz.
|
|
78
|
+
|
|
79
|
+
### CSRF Token'ları Oluşturma
|
|
80
|
+
|
|
81
|
+
CSRF token'larını oluşturmak için aşağıdaki yöntemi kullanabilirsiniz:
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
app.use((req, res, next) => {
|
|
85
|
+
req.csrfToken = () => {
|
|
86
|
+
const ip = req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.ip;
|
|
87
|
+
const userAgent = req.headers['user-agent'];
|
|
88
|
+
return csrfProtection.generateToken(ip, userAgent);
|
|
89
|
+
};
|
|
90
|
+
next();
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Token Doğrulama
|
|
95
|
+
|
|
96
|
+
Token'ları doğrulamak için `verifyToken` middleware'ini kullanabilirsiniz:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
app.post('/login', csrfProtection.verifyToken(), (req, res) => {
|
|
100
|
+
res.send('Giriş yapıldı');
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 🔍 Özellikler
|
|
105
|
+
|
|
106
|
+
- **Otomatik Token Oluşturma**: Her istek için geçerli bir CSRF token oluşturur.
|
|
107
|
+
- **Token Doğrulama**: İsteklerdeki token'ları doğrular ve geçerlilik süresini kontrol eder.
|
|
108
|
+
- **Özelleştirilebilir**: Kendi gizli anahtarınızı ve token geçerlilik sürenizi ayarlayabilirsiniz.
|
|
109
|
+
|
|
110
|
+
## ⚠️ Neden Kullanmalısınız?
|
|
111
|
+
|
|
112
|
+
CSRF saldırıları, kötü niyetli kullanıcıların bir kullanıcının oturumunu kullanarak istenmeyen işlemler yapmasına olanak tanır. `csrf-shield`, bu tür saldırılara karşı güçlü bir koruma sağlar ve web uygulamanızın güvenliğini artırır.
|
|
113
|
+
|
|
114
|
+
## 📄 API Referansı
|
|
115
|
+
|
|
116
|
+
### `csrfShield(options)`
|
|
117
|
+
|
|
118
|
+
- **options.secret**: (Opsiyonel) Token'ları şifrelemek için kullanılan gizli anahtar. Belirtilmezse, varsayılan olarak rastgele bir anahtar kullanılır.
|
|
119
|
+
- **options.timeout**: (Opsiyonel) Token'ların geçerlilik süresi milisaniye cinsinden. Varsayılan olarak 10 dakikadır.
|
|
120
|
+
|
|
121
|
+
### `middleware(req, res, next)`
|
|
122
|
+
|
|
123
|
+
- **req.csrfToken()**: Yeni bir CSRF token'ı oluşturur.
|
|
124
|
+
|
|
125
|
+
### `verifyToken()`
|
|
126
|
+
|
|
127
|
+
- **req.body._csrf**: (Opsiyonel) Token'ın form verilerinde bulunduğu yer.
|
|
128
|
+
- **req.query._csrf**: (Opsiyonel) Token'ın query parametrelerinde bulunduğu yer.
|
|
129
|
+
- **req.headers['x-csrf-token']**: (Opsiyonel) Token'ın HTTP başlıklarında bulunduğu yer.
|
|
130
|
+
|
|
131
|
+
## 🛠️ Destek & Katkı
|
|
132
|
+
|
|
133
|
+
Herhangi bir sorunla karşılaşırsanız veya katkıda bulunmak isterseniz, lütfen [GitHub deposunu](https://github.com/fastuptime/csrf-shield) ziyaret edin.
|
|
134
|
+
|
|
135
|
+
## 📝 Lisans
|
|
136
|
+
|
|
137
|
+
Bu proje [MIT Lisansı](LICENSE) altında lisanslanmıştır.
|