jinaga-server 3.5.1 → 3.5.2

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.
@@ -0,0 +1,201 @@
1
+ # Diagnostic Logging for StreamFeed Push Notification Issues
2
+
3
+ This document describes the comprehensive diagnostic logging system implemented to identify why some clients fail to receive push notifications when multiple clients are simultaneously connected to streaming feeds.
4
+
5
+ ## Overview
6
+
7
+ The diagnostic logging has been added to track:
8
+ 1. **Listener Management** - Registration/deregistration of specification listeners
9
+ 2. **Event Broadcasting** - How events are distributed to listeners
10
+ 3. **Stream State Changes** - Stream lifecycle and data flow
11
+ 4. **Connection Management** - HTTP connection lifecycle and cleanup
12
+ 5. **Concurrent Access Patterns** - Race conditions and timing issues
13
+
14
+ ## Components Modified
15
+
16
+ ### 1. ObservableSource (`../jinaga.js/src/observable/observable.ts`)
17
+
18
+ **Added logging for:**
19
+ - Listener registration with counts and specification details
20
+ - Listener removal with timing and race condition detection
21
+ - Event notification sequences with performance metrics
22
+ - Race condition detection during listener array modifications
23
+
24
+ **Key log patterns to watch for:**
25
+ ```
26
+ [ObservableSource] RACE CONDITION DETECTED - Listener count changed during snapshot
27
+ [ObservableSource] Listener NOT FOUND during removal
28
+ [ObservableSource] SLOW notification - Duration: >100ms
29
+ ```
30
+
31
+ ### 2. Stream Class (`src/http/stream.ts`)
32
+
33
+ **Added logging for:**
34
+ - Stream creation with unique IDs
35
+ - Handler registration and data replay
36
+ - Feed operations with performance tracking
37
+ - Stream closure and cleanup
38
+ - Error handling in handlers
39
+
40
+ **Key log patterns to watch for:**
41
+ ```
42
+ [Stream:ID] Attempted to feed data to closed stream
43
+ [Stream:ID] SLOW handler - Duration: >50ms
44
+ [Stream:ID] ERROR in handler
45
+ ```
46
+
47
+ ### 3. StreamFeed Function (`src/http/router.ts`)
48
+
49
+ **Added logging for:**
50
+ - Connection establishment with unique IDs
51
+ - Initial data streaming progress
52
+ - Real-time listener setup
53
+ - Event processing and filtering
54
+ - Connection cleanup and resource management
55
+
56
+ **Key log patterns to watch for:**
57
+ ```
58
+ [StreamFeed:ID] EVENT RECEIVED - Results: X
59
+ [StreamFeed:ID] No matching results - skipping response
60
+ [StreamFeed:ID] SLOW event processing - Duration: >100ms
61
+ ```
62
+
63
+ ### 4. HTTP Connection Management (`src/http/router.ts`)
64
+
65
+ **Added logging for:**
66
+ - Client connection/disconnection events
67
+ - Message transmission with timing
68
+ - Timeout handling
69
+ - Socket management
70
+ - Error conditions
71
+
72
+ **Key log patterns to watch for:**
73
+ ```
74
+ [HttpConnection:ID] CLIENT DISCONNECTED
75
+ [HttpConnection:ID] TIMEOUT TRIGGERED
76
+ [HttpConnection:ID] SLOW write operation - Duration: >50ms
77
+ ```
78
+
79
+ ## How to Use the Diagnostic Logging
80
+
81
+ ### 1. Enable Logging
82
+
83
+ The logging uses both `console.log` and the existing `Trace` system. Ensure your application is configured to capture both:
84
+
85
+ ```javascript
86
+ // For console logs
87
+ process.env.NODE_ENV = 'development';
88
+
89
+ // For Trace logs (if using structured logging)
90
+ // Configure your trace system to capture info/warn/error levels
91
+ ```
92
+
93
+ ### 2. Run the Test Script
94
+
95
+ Use the provided test script to simulate concurrent connections:
96
+
97
+ ```bash
98
+ # Replace 'your-feed-hash' with an actual feed hash from your system
99
+ node test-concurrent-streams.js your-feed-hash-here
100
+ ```
101
+
102
+ The test script will:
103
+ - Create 5 concurrent streaming connections
104
+ - Stagger connections by 1 second each
105
+ - Monitor message distribution for 30 seconds
106
+ - Report statistics and detect potential issues
107
+
108
+ ### 3. Analyze the Logs
109
+
110
+ Look for these critical patterns in the logs:
111
+
112
+ #### Race Condition Indicators
113
+ ```
114
+ [ObservableSource] RACE CONDITION DETECTED - Listener count changed during snapshot
115
+ [ObservableSource] Listener NOT FOUND during removal
116
+ ```
117
+
118
+ #### Performance Issues
119
+ ```
120
+ [StreamFeed:ID] SLOW event processing - Duration: >100ms
121
+ [HttpConnection:ID] SLOW write operation - Duration: >50ms
122
+ [Stream:ID] SLOW handler - Duration: >50ms
123
+ ```
124
+
125
+ #### Connection Issues
126
+ ```
127
+ [HttpConnection:ID] Attempted to write to disconnected client
128
+ [Stream:ID] Attempted to feed data to closed stream
129
+ ```
130
+
131
+ #### Event Distribution Problems
132
+ ```
133
+ [StreamFeed:ID] No matching results - skipping response
134
+ [ObservableSource] Processing spec X/Y - Listeners: 0
135
+ ```
136
+
137
+ ### 4. Expected Behavior vs Issues
138
+
139
+ **Normal Operation:**
140
+ - All clients should receive similar message counts
141
+ - Event processing should be fast (<100ms)
142
+ - No race condition warnings
143
+ - Clean connection cleanup
144
+
145
+ **Problem Indicators:**
146
+ - Significant variance in message counts between clients
147
+ - Race condition warnings in ObservableSource
148
+ - Slow event processing times
149
+ - Errors during listener removal
150
+ - Messages sent to closed streams
151
+
152
+ ## Monitoring Recommendations
153
+
154
+ ### 1. Real-time Monitoring
155
+
156
+ Set up log aggregation to monitor these patterns in production:
157
+
158
+ ```bash
159
+ # Example: Monitor for race conditions
160
+ tail -f application.log | grep "RACE CONDITION DETECTED"
161
+
162
+ # Example: Monitor for slow operations
163
+ tail -f application.log | grep "SLOW"
164
+
165
+ # Example: Monitor connection issues
166
+ tail -f application.log | grep "CLIENT DISCONNECTED\|TIMEOUT TRIGGERED"
167
+ ```
168
+
169
+ ### 2. Metrics to Track
170
+
171
+ - **Message Distribution Variance**: Difference between max and min messages received by clients
172
+ - **Event Processing Time**: Average time to process and distribute events
173
+ - **Connection Cleanup Time**: Time taken to remove listeners during disconnection
174
+ - **Race Condition Frequency**: Number of race condition warnings per hour
175
+
176
+ ### 3. Alerting Thresholds
177
+
178
+ Consider setting up alerts for:
179
+ - Race condition warnings (any occurrence)
180
+ - Event processing time >500ms
181
+ - Message distribution variance >10 messages
182
+ - Connection cleanup time >1000ms
183
+
184
+ ## Next Steps
185
+
186
+ After collecting diagnostic data:
187
+
188
+ 1. **Identify Root Cause**: Use the logs to confirm which of the suspected issues is occurring
189
+ 2. **Implement Fixes**: Based on findings, implement appropriate synchronization mechanisms
190
+ 3. **Validate Fixes**: Re-run tests to confirm issues are resolved
191
+ 4. **Performance Tuning**: Optimize any slow operations identified
192
+
193
+ ## Suspected Issues Being Tracked
194
+
195
+ 1. **Race Conditions in Listener Management**: ObservableSource listener array modifications during concurrent access
196
+ 2. **Shared State Corruption**: Event broadcasting while listeners are being modified
197
+ 3. **Stream State Management**: Race conditions between stream closure and data feeding
198
+ 4. **Connection Cleanup Timing**: Double cleanup or cleanup during active operations
199
+ 5. **Async Event Processing**: Out-of-order bookmark updates causing missed notifications
200
+
201
+ The diagnostic logging will help confirm which of these issues is the primary cause of the selective push notification failures.
@@ -0,0 +1,407 @@
1
+ # Security and Reliability Audit: `/feeds/:hash` Handler - Streaming Path
2
+
3
+ ## Executive Summary
4
+
5
+ This document presents a comprehensive security and reliability audit of the `/feeds/:hash` handler in `src/http/router.ts`, specifically analyzing the execution path when the Accept header contains `application/x-jinaga-feed-stream`. The audit identifies critical security vulnerabilities, reliability issues, and provides detailed remediation strategies.
6
+
7
+ ## Scope of Analysis
8
+
9
+ **Target Handler**: `/feeds/:hash` GET endpoint
10
+ **Execution Path**: `application/x-jinaga-feed-stream` Accept header flow
11
+ **Key Methods Analyzed**:
12
+ - `getOrStream()` (lines 38-92)
13
+ - `streamFeed()` (lines 468-509)
14
+ - `streamAllInitialResults()` (lines 511-568)
15
+ - `streamFeedResponse()` (lines 570-583)
16
+
17
+ ## Critical Security Findings
18
+
19
+ ### 1. Authentication Bypass Vulnerability
20
+ **CVSS Score: 9.1 (Critical)**
21
+ **CWE-287: Improper Authentication**
22
+
23
+ **Location**: Lines 43, 468-472
24
+ **Issue**: The handler accepts null users without explicit authentication validation.
25
+
26
+ ```typescript
27
+ const user = <RequestUser>(req as any).user; // Line 43
28
+ // No authentication check before proceeding
29
+ ```
30
+
31
+ **Proof of Concept**:
32
+ ```bash
33
+ curl -H "Accept: application/x-jinaga-feed-stream" \
34
+ http://target/feeds/arbitrary_hash
35
+ ```
36
+
37
+ **Business Impact**:
38
+ - Unauthorized access to sensitive feed data
39
+ - Potential data exfiltration
40
+ - Compliance violations (GDPR, HIPAA)
41
+
42
+ **Remediation**:
43
+ ```typescript
44
+ // Add explicit authentication check
45
+ if (!user && requiresAuthentication(feedHash)) {
46
+ res.sendStatus(401);
47
+ return;
48
+ }
49
+ ```
50
+
51
+ ### 2. Hash Parameter Injection Vulnerability
52
+ **CVSS Score: 8.2 (High)**
53
+ **CWE-20: Improper Input Validation**
54
+
55
+ **Location**: Lines 469, 441
56
+ **Issue**: Hash parameter lacks validation and sanitization.
57
+
58
+ ```typescript
59
+ const feedHash = params["hash"]; // No validation
60
+ if (!feedHash) {
61
+ return null; // Only checks for existence
62
+ }
63
+ ```
64
+
65
+ **Attack Vectors**:
66
+ - Path traversal: `../../../sensitive_data`
67
+ - SQL injection via hash lookup
68
+ - Hash collision attacks
69
+ - Enumeration attacks
70
+
71
+ **Proof of Concept**:
72
+ ```bash
73
+ # Path traversal attempt
74
+ curl -H "Accept: application/x-jinaga-feed-stream" \
75
+ "http://target/feeds/../../../etc/passwd"
76
+
77
+ # Hash enumeration
78
+ for i in {1..1000}; do
79
+ curl -s -o /dev/null -w "%{http_code}" \
80
+ "http://target/feeds/hash_$i" | grep -v 404
81
+ done
82
+ ```
83
+
84
+ **Remediation**:
85
+ ```typescript
86
+ // Add hash validation
87
+ const HASH_PATTERN = /^[a-fA-F0-9]{64}$/;
88
+ if (!feedHash || !HASH_PATTERN.test(feedHash)) {
89
+ res.sendStatus(400);
90
+ return;
91
+ }
92
+ ```
93
+
94
+ ### 3. Timing Attack Vulnerability
95
+ **CVSS Score: 6.5 (Medium)**
96
+ **CWE-208: Observable Timing Discrepancy**
97
+
98
+ **Location**: Lines 474-477
99
+ **Issue**: Feed lookup timing reveals hash existence.
100
+
101
+ ```typescript
102
+ const feedDefinition = await this.feedCache.getFeed(feedHash);
103
+ if (!feedDefinition) {
104
+ return null; // Different timing for valid vs invalid hashes
105
+ }
106
+ ```
107
+
108
+ **Remediation**:
109
+ ```typescript
110
+ // Constant-time hash validation
111
+ const [feedDefinition, _] = await Promise.all([
112
+ this.feedCache.getFeed(feedHash),
113
+ this.addConstantTimeDelay()
114
+ ]);
115
+ ```
116
+
117
+ ### 4. Denial of Service Vulnerabilities
118
+ **CVSS Score: 7.5 (High)**
119
+ **CWE-400: Uncontrolled Resource Consumption**
120
+
121
+ #### 4.1 Memory Exhaustion
122
+ **Location**: Lines 485-509, 511-568
123
+ **Issue**: Unbounded stream creation and memory usage.
124
+
125
+ ```typescript
126
+ const stream = new Stream<FeedResponse>(); // No memory limits
127
+ // Continuous streaming without backpressure management
128
+ ```
129
+
130
+ #### 4.2 Connection Exhaustion
131
+ **Location**: Lines 58-60, 61-63
132
+ **Issue**: Inadequate connection management.
133
+
134
+ ```typescript
135
+ const timeout = setTimeout(() => {
136
+ response.close();
137
+ }, 5 * 60 * 1000); // 5-minute timeout may be too long
138
+ ```
139
+
140
+ **Attack Scenario**:
141
+ ```bash
142
+ # Connection exhaustion attack
143
+ for i in {1..10000}; do
144
+ curl -H "Accept: application/x-jinaga-feed-stream" \
145
+ "http://target/feeds/valid_hash" &
146
+ done
147
+ ```
148
+
149
+ **Remediation**:
150
+ ```typescript
151
+ // Add connection limits and backpressure
152
+ const MAX_CONCURRENT_STREAMS = 100;
153
+ const STREAM_TIMEOUT = 30000; // 30 seconds
154
+ const MAX_MEMORY_PER_STREAM = 10 * 1024 * 1024; // 10MB
155
+ ```
156
+
157
+ ### 5. Race Condition Vulnerabilities
158
+ **CVSS Score: 6.8 (Medium)**
159
+ **CWE-362: Concurrent Execution using Shared Resource**
160
+
161
+ **Location**: Lines 492-502, 523-565
162
+ **Issue**: Concurrent access to shared resources without proper synchronization.
163
+
164
+ ```typescript
165
+ // Multiple async operations without proper coordination
166
+ const listeners = inverses.map(inverse => this.factManager.addSpecificationListener(
167
+ inverse.inverseSpecification,
168
+ async (results) => {
169
+ // Race condition: bookmark updates
170
+ bookmark = await this.streamFeedResponse(...);
171
+ }
172
+ ));
173
+ ```
174
+
175
+ ### 6. Information Disclosure Vulnerabilities
176
+ **CVSS Score: 5.3 (Medium)**
177
+ **CWE-200: Information Exposure**
178
+
179
+ #### 6.1 Error Information Leakage
180
+ **Location**: Lines 722-738
181
+ **Issue**: Detailed error messages expose internal system information.
182
+
183
+ ```typescript
184
+ res.status(500).send(error.message); // Exposes internal errors
185
+ ```
186
+
187
+ #### 6.2 Timing-Based Information Disclosure
188
+ **Location**: Lines 523-565
189
+ **Issue**: Processing time reveals data characteristics.
190
+
191
+ ## Reliability and Performance Issues
192
+
193
+ ### 1. Infinite Loop Vulnerability
194
+ **Severity: High**
195
+ **Location**: Lines 523-565
196
+
197
+ ```typescript
198
+ while (hasMoreResults && pageCount < maxPages) {
199
+ // Potential infinite loop if bookmark doesn't change
200
+ if (newBookmark === bookmark) {
201
+ hasMoreResults = false; // Mitigation exists but insufficient
202
+ }
203
+ }
204
+ ```
205
+
206
+ **Issue**: Insufficient loop termination conditions.
207
+
208
+ ### 2. Resource Leak Vulnerabilities
209
+ **Severity: High**
210
+ **Location**: Lines 503-507
211
+
212
+ ```typescript
213
+ stream.done(() => {
214
+ for (const listener of listeners) {
215
+ this.factManager.removeSpecificationListener(listener);
216
+ }
217
+ });
218
+ ```
219
+
220
+ **Issue**: Listeners may not be cleaned up if stream.done() is not called.
221
+
222
+ ### 3. Database Connection Pool Exhaustion
223
+ **Severity: Medium**
224
+ **Location**: Lines 524, 571
225
+
226
+ Multiple concurrent database calls without connection pooling limits.
227
+
228
+ ## Detailed Remediation Strategy
229
+
230
+ ### Priority 1: Critical Security Fixes
231
+
232
+ 1. **Implement Authentication Validation**
233
+ ```typescript
234
+ // Add to getOrStream function
235
+ if (requiresAuth && !user) {
236
+ res.sendStatus(401);
237
+ return;
238
+ }
239
+ ```
240
+
241
+ 2. **Add Hash Parameter Validation**
242
+ ```typescript
243
+ const validateHash = (hash: string): boolean => {
244
+ return /^[a-fA-F0-9]{64}$/.test(hash) && hash.length === 64;
245
+ };
246
+ ```
247
+
248
+ 3. **Implement Rate Limiting**
249
+ ```typescript
250
+ const rateLimiter = rateLimit({
251
+ windowMs: 15 * 60 * 1000, // 15 minutes
252
+ max: 100 // limit each IP to 100 requests per windowMs
253
+ });
254
+ ```
255
+
256
+ ### Priority 2: DoS Prevention
257
+
258
+ 1. **Connection Management**
259
+ ```typescript
260
+ const connectionManager = new ConnectionManager({
261
+ maxConcurrentStreams: 100,
262
+ maxStreamDuration: 30000,
263
+ maxMemoryPerStream: 10 * 1024 * 1024
264
+ });
265
+ ```
266
+
267
+ 2. **Backpressure Implementation**
268
+ ```typescript
269
+ class BackpressureStream<T> extends Stream<T> {
270
+ private buffer: T[] = [];
271
+ private maxBufferSize = 1000;
272
+
273
+ feed(data: T) {
274
+ if (this.buffer.length >= this.maxBufferSize) {
275
+ this.pause();
276
+ }
277
+ super.feed(data);
278
+ }
279
+ }
280
+ ```
281
+
282
+ ### Priority 3: Monitoring and Logging
283
+
284
+ 1. **Security Event Logging**
285
+ ```typescript
286
+ const securityLogger = {
287
+ logSuspiciousActivity: (event: SecurityEvent) => {
288
+ // Log to SIEM system
289
+ },
290
+ logAccessAttempt: (user: string, resource: string, success: boolean) => {
291
+ // Audit trail
292
+ }
293
+ };
294
+ ```
295
+
296
+ 2. **Performance Monitoring**
297
+ ```typescript
298
+ const performanceMonitor = {
299
+ trackStreamDuration: (streamId: string, duration: number) => {},
300
+ trackMemoryUsage: (streamId: string, usage: number) => {},
301
+ trackConcurrentConnections: (count: number) => {}
302
+ };
303
+ ```
304
+
305
+ ## Supply Chain Security Analysis
306
+
307
+ ### Dependencies Review
308
+ - **express**: Check for known CVEs in routing
309
+ - **jinaga**: Internal dependency - requires separate audit
310
+ - **Stream class**: Custom implementation needs security review
311
+
312
+ ### Recommended Actions
313
+ 1. Implement dependency scanning in CI/CD
314
+ 2. Regular security updates
315
+ 3. Vendor security assessment for jinaga library
316
+
317
+ ## Compliance Considerations
318
+
319
+ ### GDPR Compliance
320
+ - Data minimization in streams
321
+ - Right to erasure implementation
322
+ - Consent management for streaming data
323
+
324
+ ### SOC 2 Compliance
325
+ - Access logging and monitoring
326
+ - Data encryption in transit
327
+ - Incident response procedures
328
+
329
+ ## Testing Strategy
330
+
331
+ ### Security Testing
332
+ 1. **Penetration Testing**
333
+ - Authentication bypass attempts
334
+ - Input validation testing
335
+ - DoS attack simulation
336
+
337
+ 2. **Automated Security Scanning**
338
+ - SAST tools integration
339
+ - Dependency vulnerability scanning
340
+ - Runtime security monitoring
341
+
342
+ ### Performance Testing
343
+ 1. **Load Testing**
344
+ - Concurrent stream handling
345
+ - Memory usage under load
346
+ - Database connection pooling
347
+
348
+ 2. **Chaos Engineering**
349
+ - Network partition simulation
350
+ - Database failure scenarios
351
+ - Memory pressure testing
352
+
353
+ ## Implementation Timeline
354
+
355
+ ### Phase 1 (Immediate - 1 week)
356
+ - Critical authentication fixes
357
+ - Input validation implementation
358
+ - Basic rate limiting
359
+
360
+ ### Phase 2 (Short-term - 2-4 weeks)
361
+ - DoS prevention measures
362
+ - Enhanced monitoring
363
+ - Security logging
364
+
365
+ ### Phase 3 (Medium-term - 1-3 months)
366
+ - Comprehensive testing
367
+ - Performance optimization
368
+ - Compliance implementation
369
+
370
+ ## Conclusion
371
+
372
+ The `/feeds/:hash` handler contains multiple critical security vulnerabilities that require immediate attention. The streaming functionality, while providing real-time capabilities, introduces significant attack surface that must be properly secured. Implementation of the recommended remediation strategies will significantly improve the security posture and reliability of the system.
373
+
374
+ **Risk Assessment**: **HIGH** - Immediate action required
375
+ **Business Impact**: **CRITICAL** - Potential for data breach and service disruption
376
+ **Remediation Complexity**: **MEDIUM** - Requires coordinated development effort
377
+
378
+ ## Appendix A: Security Checklist
379
+
380
+ - [ ] Authentication validation implemented
381
+ - [ ] Input sanitization and validation
382
+ - [ ] Rate limiting configured
383
+ - [ ] Connection management implemented
384
+ - [ ] Error handling sanitized
385
+ - [ ] Logging and monitoring deployed
386
+ - [ ] Security testing completed
387
+ - [ ] Performance testing completed
388
+ - [ ] Documentation updated
389
+ - [ ] Team training conducted
390
+
391
+ ## Appendix B: Monitoring Queries
392
+
393
+ ```sql
394
+ -- Suspicious hash access patterns
395
+ SELECT hash, COUNT(*), MIN(timestamp), MAX(timestamp)
396
+ FROM feed_access_log
397
+ WHERE timestamp > NOW() - INTERVAL '1 hour'
398
+ GROUP BY hash
399
+ HAVING COUNT(*) > 100;
400
+
401
+ -- Failed authentication attempts
402
+ SELECT ip_address, COUNT(*)
403
+ FROM security_events
404
+ WHERE event_type = 'auth_failure'
405
+ AND timestamp > NOW() - INTERVAL '1 hour'
406
+ GROUP BY ip_address
407
+ HAVING COUNT(*) > 10;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinaga-server",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "description": "Data management for web and mobile applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "express": "^4.21.2",
51
- "jinaga": "^6.7.0",
51
+ "jinaga": "^6.7.9",
52
52
  "pg": "^8.13.1"
53
53
  }
54
54
  }