yinzerflow 0.4.4 → 0.5.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.
@@ -1,189 +0,0 @@
1
- # CORS Security
2
-
3
- YinzerFlow provides built-in CORS support to handle cross-origin requests securely and efficiently.
4
-
5
- For an overview of all security features, see [Security Overview](./security-overview.md).
6
-
7
- ## Configuration
8
-
9
- Configure CORS in your YinzerFlow setup:
10
-
11
- ```typescript
12
- import { YinzerFlow } from 'yinzerflow';
13
-
14
- const app = new YinzerFlow({
15
- cors: {
16
- enabled: true,
17
- origin: 'https://myapp.com',
18
- credentials: true,
19
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
20
- allowedHeaders: ['Content-Type', 'Authorization'],
21
- exposedHeaders: ['X-Total-Count'],
22
- maxAge: 86400,
23
- optionsSuccessStatus: 204,
24
- preflightContinue: false,
25
- }
26
- });
27
- ```
28
-
29
- ## Configuration Options
30
-
31
- | Option | Type | Default | Description |
32
- |--------|------|---------|-------------|
33
- | `enabled` | `boolean` | `false` | Enable/disable CORS |
34
- | `origin` | `string \| string[] \| RegExp \| function \| '*'` | `'*'` | Allowed origins |
35
- | `credentials` | `boolean` | `false` | Allow credentials (cookies, auth headers) |
36
- | `methods` | `string[]` | `['GET', 'POST', 'PUT', 'DELETE']` | Allowed HTTP methods |
37
- | `allowedHeaders` | `string \| string[]` | `['Content-Type', 'Authorization']` | Allowed request headers |
38
- | `exposedHeaders` | `string[]` | `[]` | Headers exposed to client |
39
- | `maxAge` | `number` | `86400` | Preflight cache duration (seconds) |
40
- | `optionsSuccessStatus` | `number` | `204` | Status code for successful OPTIONS |
41
- | `preflightContinue` | `boolean` | `false` | Pass control to next handler after preflight |
42
-
43
- ## Common Use Cases
44
-
45
- - **Secure Web Applications**: Configure CORS for authenticated browser apps with specific domains and credentials
46
- - **Public APIs**: Enable broad access for public data APIs while maintaining security controls
47
- - **Development Environments**: Set up flexible CORS for local development with multiple frontend ports
48
- - **Microservices**: Configure cross-service communication with controlled origin validation
49
- - **Mobile App Backends**: Handle native mobile app requests with appropriate CORS settings
50
- - **Third-Party Integrations**: Allow controlled access from partner domains with validation functions
51
-
52
- ## Origin Configuration Examples
53
-
54
- ### Wildcard (Public APIs)
55
- ```typescript
56
- cors: {
57
- enabled: true,
58
- }
59
- ```
60
-
61
- ### Single Domain
62
- ```typescript
63
- cors: {
64
- enabled: true,
65
- origin: 'https://myapp.com',
66
- credentials: true,
67
- }
68
- ```
69
-
70
- ### Multiple Domains
71
- ```typescript
72
- cors: {
73
- enabled: true,
74
- origin: [
75
- 'https://myapp.com',
76
- 'https://admin.myapp.com',
77
- 'https://mobile.myapp.com'
78
- ],
79
- credentials: true,
80
- }
81
- ```
82
-
83
- ### RegExp Pattern
84
- ```typescript
85
- cors: {
86
- enabled: true,
87
- origin: /^https:\/\/.*\.myapp\.com$/,
88
- credentials: true,
89
- }
90
- ```
91
-
92
- ### Dynamic Function
93
- ```typescript
94
- cors: {
95
- enabled: true,
96
- origin: (origin, request): boolean => {
97
- // Custom validation logic
98
- const allowedDomains = ['myapp.com', 'partner.com'];
99
- if (!origin) return false; // Reject: no origin header
100
-
101
- try {
102
- const url = new URL(origin);
103
- return allowedDomains.includes(url.hostname); // true = allow, false = reject
104
- } catch {
105
- return false; // Reject: malformed URL
106
- }
107
- },
108
- credentials: true,
109
- }
110
- ```
111
-
112
- **Function Return Values:**
113
- - `true` - Allow the origin (request proceeds with CORS headers)
114
- - `false` - Reject the origin (403 Forbidden response)
115
-
116
- ## Request Flow
117
-
118
- ### Simple Requests
119
- For simple requests (GET, POST with basic content types), CORS headers are added directly:
120
-
121
- ```
122
- Client Request:
123
- Origin: https://myapp.com
124
-
125
- Server Response:
126
- Access-Control-Allow-Origin: https://myapp.com
127
- Access-Control-Allow-Credentials: true
128
- ```
129
-
130
- ### Preflight Requests
131
- For complex requests, browsers send an OPTIONS preflight:
132
-
133
- ```
134
- Client Preflight:
135
- OPTIONS /api/data HTTP/1.1
136
- Origin: https://myapp.com
137
- Access-Control-Request-Method: PUT
138
- Access-Control-Request-Headers: Content-Type, Authorization
139
-
140
- Server Preflight Response:
141
- HTTP/1.1 204 No Content
142
- Access-Control-Allow-Origin: https://myapp.com
143
- Access-Control-Allow-Methods: GET, POST, PUT, DELETE
144
- Access-Control-Allow-Headers: Content-Type, Authorization
145
- Access-Control-Allow-Credentials: true
146
- Access-Control-Max-Age: 86400
147
- ```
148
-
149
- ## Error Handling
150
-
151
- YinzerFlow automatically handles CORS errors
152
-
153
- ## Security Considerations
154
-
155
- YinzerFlow implements several security measures to prevent common CORS vulnerabilities:
156
-
157
- ### 🛡️ Origin Validation Enforcement
158
- - **Problem**: Many frameworks validate origins but don't enforce the validation result
159
- - **YinzerFlow Solution**: Origin validation results are actually used - unauthorized requests get 403 Forbidden
160
-
161
- ### 🛡️ No Origin Echo-back for Wildcards
162
- - **Problem**: Some implementations echo back the request origin when using wildcards, defeating CORS protection
163
- - **YinzerFlow Solution**: Wildcard origins always return literal `'*'`, never echo back request origins
164
-
165
- ### 🛡️ Spec Compliance Enforcement
166
- - **Problem**: CORS spec forbids `origin: '*'` with `credentials: true`, but many frameworks allow this dangerous combination
167
- - **YinzerFlow Solution**: This combination throws a security error at startup, preventing deployment of vulnerable configurations
168
-
169
- ### 🛡️ Proper Preflight Rejection
170
- - **Problem**: Some frameworks set CORS headers even for rejected requests, or let request handlers override CORS rejections
171
- - **YinzerFlow Solution**: Unauthorized preflight requests get 403 with no CORS headers, and the rejection cannot be overridden
172
-
173
- ### 🛡️ Case-Insensitive Origin Matching
174
- - **Problem**: Inconsistent case handling can lead to bypass attempts
175
- - **YinzerFlow Solution**: All origin validation is case-insensitive but preserves original case in responses
176
-
177
- ### 🛡️ Malformed Origin Protection
178
- - **Problem**: Malformed origins (like `javascript:`, `data:`, or invalid URLs) can cause security issues
179
- - **YinzerFlow Solution**: All malformed origins are safely rejected with 403 status
180
-
181
- ### 🛡️ Function Validation Safety
182
- - **Problem**: Custom origin validation functions might throw errors or behave unpredictably
183
- - **YinzerFlow Solution**: Function results are safely coerced to boolean, preventing exceptions from bypassing security
184
-
185
- ### 🛡️ No Information Leakage
186
- - **Problem**: Error responses might leak information about internal origins or configurations
187
- - **YinzerFlow Solution**: Rejection responses only include the rejected origin, no internal configuration details
188
-
189
- These security measures ensure YinzerFlow's CORS implementation follows security best practices and prevents common attack vectors while maintaining spec compliance. If you come up with any other security implementation's that hadn't been addressed, Please open a PR and follow our contribution guides.
@@ -1,234 +0,0 @@
1
- # IP Security
2
-
3
- YinzerFlow provides comprehensive IP address validation and security protection against IP spoofing attacks, supporting multiple header formats with trusted proxy validation.
4
-
5
- For an overview of all security features, see [Security Overview](./security-overview.md).
6
-
7
- ## Configuration
8
-
9
- Configure IP security settings in your YinzerFlow application:
10
-
11
- ```typescript
12
- const app = new YinzerFlow({
13
- port: 3000,
14
- ipSecurity: {
15
- trustedProxies: ['127.0.0.1', '::1', '192.168.1.10'],
16
- allowPrivateIps: true,
17
- headerPreference: ['x-forwarded-for', 'x-real-ip', 'cf-connecting-ip'],
18
- maxChainLength: 10,
19
- detectSpoofing: true
20
- }
21
- });
22
- ```
23
-
24
- ### Configuration Options
25
-
26
- | Option | Type | Default | Description |
27
- |-----|---|---|---|
28
- | `trustedProxies` | `string[]` | `['127.0.0.1', '::1']` | List of trusted proxy IP addresses |
29
- | `allowPrivateIps` | `boolean` | `true` | Allow private IP addresses (RFC 1918, etc.) |
30
- | `headerPreference` | `string[]` | `['x-forwarded-for', 'x-real-ip', 'cf-connecting-ip', 'x-client-ip', 'true-client-ip']` | Header preference order |
31
- | `maxChainLength` | `number` | `10` | Maximum IP chain length |
32
- | `detectSpoofing` | `boolean` | `true` | Enable spoofing pattern detection |
33
-
34
- ## Examples
35
-
36
- ### Basic Example
37
-
38
- Access client IP address with automatic security validation:
39
-
40
- ```typescript
41
- app.get('/api/user-info', ({ request }) => {
42
- const clientIp = request.ipAddress;
43
-
44
- return {
45
- message: `Hello from ${clientIp}`,
46
- userAgent: request.headers['user-agent']
47
- };
48
- });
49
- ```
50
-
51
- ### Advanced Example
52
-
53
- Configure IP security for your application:
54
-
55
- ```typescript
56
- app.post('/api/secure-endpoint', ({ request }) => {
57
- // YinzerFlow automatically applies IP security configuration
58
- const clientIp = request.ipAddress; // Uses configured IP security rules
59
-
60
- if (!clientIp) {
61
- return {
62
- error: 'Unable to determine client IP address',
63
- message: 'Request may be from untrusted proxy or invalid source'
64
- };
65
- }
66
-
67
- return {
68
- clientIp,
69
- message: 'Secure endpoint accessed successfully'
70
- };
71
- });
72
- ```
73
-
74
- ## Common Use Cases
75
-
76
- - **Load Balancer Integration**: Configure trusted proxies to get real client IPs behind Nginx, HAProxy, or cloud load balancers
77
- - **CDN Support**: Handle Cloudflare and other CDN headers like `CF-Connecting-IP` with proper validation
78
- - **Reverse Proxy Security**: Validate proxy chains to prevent IP spoofing in complex network topologies
79
- - **Complex Infrastructure**: Use wildcard (`'*'`) for Kubernetes ingress, unknown CDN configurations, or dynamic proxy setups
80
- - **Rate Limiting**: Get accurate client IPs for rate limiting and abuse prevention systems
81
- - **Geolocation Services**: Ensure IP addresses are valid before passing to geolocation APIs
82
- - **Security Logging**: Log real client IPs for security monitoring and incident response
83
-
84
- ### Load Balancer Behind Nginx
85
-
86
- ```typescript
87
- const app = new YinzerFlow({
88
- port: 3000,
89
- ipSecurity: {
90
- trustedProxies: ['192.168.1.10'], // Your Nginx server
91
- headerPreference: ['x-forwarded-for'],
92
- detectSpoofing: true
93
- }
94
- });
95
- ```
96
-
97
- ### Cloudflare CDN Integration
98
-
99
- ```typescript
100
- const app = new YinzerFlow({
101
- port: 3000,
102
- ipSecurity: {
103
- trustedProxies: [
104
- // Cloudflare IP ranges
105
- '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22'
106
- ],
107
- headerPreference: ['cf-connecting-ip', 'x-forwarded-for'],
108
- allowPrivateIps: false // Only real client IPs
109
- }
110
- });
111
- ```
112
-
113
- ### High-Security Environment
114
-
115
- ```typescript
116
- const app = new YinzerFlow({
117
- port: 3000,
118
- ipSecurity: {
119
- trustedProxies: ['10.0.1.100'], // Only specific proxy
120
- maxChainLength: 2, // Short chains only
121
- detectSpoofing: true,
122
- allowPrivateIps: false
123
- }
124
- });
125
- ```
126
-
127
- ### Complex Infrastructure (Unknown Proxies)
128
-
129
- ```typescript
130
- const app = new YinzerFlow({
131
- port: 3000,
132
- ipSecurity: {
133
- trustedProxies: ['*'], // Trust any proxy - useful for Kubernetes, unknown CDNs
134
- detectSpoofing: true, // Still detect attack patterns
135
- maxChainLength: 10,
136
- allowPrivateIps: false
137
- }
138
- });
139
- ```
140
-
141
- ## Error Handling
142
-
143
- YinzerFlow handles IP parsing errors gracefully and applies security validation automatically:
144
-
145
- **Common behaviors:**
146
- - Invalid IP formats result in empty `request.ipAddress`
147
- - Untrusted proxy chains are rejected when strict validation is enabled
148
- - Spoofing patterns are detected and suspicious headers are ignored automatically
149
- - Private IPs are filtered when `allowPrivateIps: false` is configured
150
-
151
- ```typescript
152
- app.get('/api/user-location', ({ request }) => {
153
- const clientIp = request.ipAddress;
154
-
155
- if (!clientIp) {
156
- // YinzerFlow couldn't determine a valid, trusted IP
157
- return {
158
- error: 'Unable to determine client location',
159
- message: 'IP address validation failed'
160
- };
161
- }
162
-
163
- // Safe to use clientIp - YinzerFlow has validated it
164
- return await getLocationForIp(clientIp);
165
- });
166
- ```
167
-
168
- ## Security Considerations
169
-
170
- YinzerFlow implements several security measures to prevent IP spoofing attacks and ensure accurate client identification:
171
-
172
- ### 🛡️ Trusted Proxy Validation
173
- - **Problem**: Attackers can spoof `X-Forwarded-For` headers to hide their real IP address or impersonate other clients
174
- - **YinzerFlow Solution**: Only accepts forwarded headers from explicitly configured trusted proxy IPs, preventing spoofing from untrusted sources
175
-
176
- #### How Trusted Proxies Work
177
-
178
- When using `X-Forwarded-For` headers, YinzerFlow validates proxy chains by checking if the **rightmost IP** (the proxy that sent the request) is in your trusted proxies list:
179
-
180
- ```
181
- X-Forwarded-For: 203.0.113.1, 198.51.100.1, 127.0.0.1
182
- ^client IP ^proxy 1 ^proxy 2 (rightmost - must be trusted)
183
- ```
184
-
185
- **Key Points:**
186
- - **Only the rightmost IP needs to be trusted** - this is the proxy that directly sent the request to your server
187
- - **Client IP is extracted** - YinzerFlow extracts the leftmost IP (203.0.113.1) as the real client
188
- - **Chain validation** - If the rightmost IP isn't in your `trustedProxies` list, the entire header is rejected
189
- - **Wildcard support** - Use `['*']` to trust any proxy (useful for Kubernetes/unknown infrastructure)
190
-
191
- **Examples:**
192
- ```typescript
193
- // ✅ Valid: 127.0.0.1 is trusted, extracts 203.0.113.1 as client
194
- trustedProxies: ['127.0.0.1']
195
- X-Forwarded-For: 203.0.113.1, 127.0.0.1
196
-
197
- // ❌ Invalid: 192.168.1.1 is not trusted, header rejected
198
- trustedProxies: ['127.0.0.1']
199
- X-Forwarded-For: 203.0.113.1, 192.168.1.1
200
-
201
- // ✅ Valid: Wildcard trusts any proxy
202
- trustedProxies: ['*']
203
- X-Forwarded-For: 203.0.113.1, any.proxy.ip
204
- ```
205
-
206
- ### 🛡️ Multiple Header Support
207
- - **Problem**: Different proxies and CDNs use different headers (X-Real-IP, CF-Connecting-IP, etc.), making it hard to get consistent client IPs
208
- - **YinzerFlow Solution**: Configurable header preference order with validation for each header type based on its expected format and source
209
-
210
- ### 🛡️ IP Format Validation
211
- - **Problem**: Malformed IP addresses can cause application errors or bypass security controls
212
- - **YinzerFlow Solution**: Comprehensive IPv4 and IPv6 validation with named capture groups for precise format checking
213
-
214
- ### 🛡️ Spoofing Pattern Detection
215
- - **Problem**: Sophisticated attacks use patterns like duplicate IPs, overly long chains, or mixed valid/invalid IPs to confuse parsing
216
- - **YinzerFlow Solution**: Advanced pattern detection identifies suspicious IP chains and automatically rejects them
217
-
218
- ### 🛡️ Private IP Filtering
219
- - **Problem**: Internal network IPs might leak information about network topology or be used in certain attacks
220
- - **YinzerFlow Solution**: Configurable private IP filtering with RFC 1918, RFC 4193, and RFC 3927 range detection
221
-
222
- ### 🛡️ Chain Length Limits
223
- - **Problem**: Extremely long IP chains can cause DoS attacks through memory exhaustion or processing delays
224
- - **YinzerFlow Solution**: Configurable maximum chain length prevents amplification attacks while allowing legitimate proxy chains
225
-
226
- ### 🛡️ Fallback Protection
227
- - **Problem**: When strict validation fails, applications might fall back to unsafe IP extraction methods
228
- - **YinzerFlow Solution**: Controlled fallback behavior that maintains security when trusted proxies are configured
229
-
230
- ### 🛡️ IPv6 Security
231
- - **Problem**: IPv6 addresses have complex formats that can be exploited for parsing attacks or validation bypasses
232
- - **YinzerFlow Solution**: Robust IPv6 validation including compression rules, zone identifiers, and IPv4-mapped addresses
233
-
234
- These security measures ensure YinzerFlow's IP parsing implementation follows security best practices and prevents common attack vectors while maintaining compatibility with standard proxy configurations.