You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
trustXForwardedFor:true, // Default: true. Whether to trust X-Forwarded-For headers. See warning below.
81
+
}
78
82
},
79
83
});
80
84
```
81
85
86
+
**Default Configuration Values:**
87
+
(These are applied by the module if not specified in your `nuxtApiShield` config)
88
+
```js
89
+
{
90
+
limit: {
91
+
max:12,
92
+
duration:108, // seconds
93
+
ban:3600, // seconds
94
+
},
95
+
delayOnBan:true,
96
+
errorMessage:"Too Many Requests",
97
+
retryAfterHeader:false,
98
+
log: {
99
+
path:"logs", // Logging is disabled if path is empty
100
+
attempts:100, // Logging per IP is disabled if attempts is 0
101
+
},
102
+
routes: [],
103
+
ipTTL:7*24*60*60, // 7 days in seconds
104
+
security: {
105
+
trustXForwardedFor:true,
106
+
}
107
+
}
108
+
```
109
+
110
+
**Security Warning: `trustXForwardedFor`**
111
+
112
+
The `security.trustXForwardedFor` option (default is `true`, set by the module) determines if the module uses the `X-Forwarded-For` HTTP header to identify the client's IP address.
113
+
- If set to `true`: The module will use the IP address provided in the `X-Forwarded-For` header. This is common when your Nuxt application is behind a trusted reverse proxy, load balancer, or CDN (like Nginx, Cloudflare, AWS ELB/ALB) that correctly sets this header with the real client IP.
114
+
-**WARNING:** If `trustXForwardedFor` is `true` and your application is directly internet-facing OR your proxy is not configured to strip incoming `X-Forwarded-For` headers from clients, malicious users can spoof their IP address by sending a fake `X-Forwarded-For` header. This would allow them to bypass rate limits or cause other users to be incorrectly rate-limited.
115
+
- If set to `false`: The module will use the direct IP address of the incoming connection (i.e., `event.node.req.socket.remoteAddress`). Use this setting if your application is directly internet-facing or if you are unsure about your proxy's configuration.
116
+
-**Recommendation:** Only enable `trustXForwardedFor: true` if you are certain your reverse proxy is correctly configured to set this header and strip any client-sent versions of it. Otherwise, set it to `false`.
117
+
82
118
### 3. Add `nitro/storage` to `nuxt.config.ts`
83
119
84
120
You can use any storage you want, but you have to use **shield** as the name of the storage.
@@ -112,7 +148,7 @@ If you use for example redis, you can use the following configuration, define th
112
148
}
113
149
```
114
150
115
-
### 4. Add `shield:clean` to `nuxt.config.ts`
151
+
### 4. Add Cleanup Task(s) to `nuxt.config.ts`
116
152
117
153
```json
118
154
{
@@ -121,37 +157,133 @@ If you use for example redis, you can use the following configuration, define th
121
157
"tasks": true
122
158
},
123
159
"scheduledTasks": {
124
-
"*/15 * * * *": ["shield:clean"] // clean the shield storage every 15 minutes
The `isActualBanTimestampExpired` utility is provided by `nuxt-api-shield` and should be available via `#imports`.
205
+
206
+
#### b) Task for Cleaning Old IP Tracking Data
131
207
132
-
In `server/tasks/shield/clean.ts` you should have something like this.
208
+
This task cleans up IP tracking entries (`ip:xxx.xxx.xxx.xxx`) that haven't been active (i.e., their `time` field hasn't been updated) for a certain period. This period is defined by the `ipTTL` configuration option in your `nuxt.config.ts` (under `nuxtApiShield`), which defaults to 7 days. This cleanup helps prevent your storage from growing indefinitely with IPs that make a few requests but are never banned.
209
+
210
+
In `server/tasks/shield/cleanIpData.ts`:
133
211
134
212
```ts
135
-
importtype { RateLimit } from"#imports";
213
+
importtype { RateLimit } from'#imports'; // Or from 'nuxt-api-shield/types' if made available by the module
214
+
import { useRuntimeConfig } from'#imports';
136
215
137
216
exportdefaultdefineTask({
138
217
meta: {
139
-
description: "Clean expired bans",
218
+
name: 'shield:cleanIpData', // Match the name in scheduledTasks
219
+
description: 'Clean old IP tracking data from nuxt-api-shield storage.',
// Check if entry exists and has a numeric 'time' property
242
+
if (entry&&typeofentry.time==='number') {
243
+
if ((currentTime-entry.time) >ipTTLms) {
244
+
awaitshieldStorage.removeItem(key);
245
+
cleanedCount++;
246
+
}
247
+
} else {
248
+
// Clean up entries that are null, not an object, or missing a numeric 'time'
148
249
awaitshieldStorage.removeItem(key);
250
+
cleanedCount++;
149
251
}
150
-
});
151
-
return { result: keys };
252
+
}
253
+
254
+
console.log(`[nuxt-api-shield] Cleaned ${cleanedCount} old/malformed IP data entries.`);
255
+
return { result: { cleanedCount } };
152
256
},
153
257
});
154
258
```
259
+
Make sure to configure `ipTTL` in your `nuxt.config.ts` under `nuxtApiShield` if you wish to use a value different from the default (7 days). Setting `ipTTL: 0` (or any non-positive number) in your config will disable this cleanup task. The `RateLimit` type should be available via `#imports` if your module exports it or makes it available to Nuxt's auto-import system.
260
+
261
+
## Important Considerations
262
+
263
+
### Data Privacy (IP Address Storage)
264
+
265
+
`nuxt-api-shield` functions by tracking IP addresses to monitor request rates and apply bans. This means IP addresses, which can be considered Personally Identifiable Information (PII) under regulations like GDPR, are stored by the module.
266
+
267
+
-**Data Stored:**
268
+
-`ip:<IP_ADDRESS>`: Stores `{ count: number, time: number }` for tracking request rates.
269
+
-`ban:<IP_ADDRESS>`: Stores a timestamp indicating when a ban on an IP address expires.
270
+
-**Compliance:** Ensure your usage complies with any applicable data privacy regulations. This may involve updating your privacy policy to inform users about this data processing.
271
+
-**Data Retention:**
272
+
- Ban entries are cleaned up by the `shield:cleanBans` task after expiry.
273
+
- IP tracking entries are cleaned up by the `shield:cleanIpData` task based on the `ipTTL` setting.
274
+
275
+
### Storage Security
276
+
277
+
-**Filesystem Driver (`driver: 'fs'`):** If you use the filesystem driver for `unstorage` (e.g., `driver: 'fs'`, `base: '.shield'`), ensure that the storage directory (and the `logs` directory if logging is enabled via `log.path`) is:
278
+
-**Not web-accessible:** Your web server should not be configured to serve files from these directories.
279
+
-**Properly permissioned:** The directories should have appropriate server-side file permissions to prevent unauthorized reading or writing.
280
+
-**Other Drivers (Redis, etc.):** If using database drivers like Redis, ensure your database server itself is secured (e.g., authentication, network access controls).
281
+
282
+
### Error Message (`errorMessage`)
283
+
284
+
The `errorMessage` option in the module configuration is returned in the body of a 429 response.
285
+
- It's recommended to use a plain text message.
286
+
- If you choose to use HTML in your `errorMessage`, ensure your client-side application correctly sanitizes it or renders it in a way that prevents XSS vulnerabilities. The module itself does not sanitize this user-configured message.
0 commit comments