@pan-sec/notebooklm-mcp 1.4.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.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -0
  3. package/SECURITY.md +539 -0
  4. package/dist/auth/auth-manager.d.ts +137 -0
  5. package/dist/auth/auth-manager.d.ts.map +1 -0
  6. package/dist/auth/auth-manager.js +984 -0
  7. package/dist/auth/auth-manager.js.map +1 -0
  8. package/dist/auth/mcp-auth.d.ts +102 -0
  9. package/dist/auth/mcp-auth.d.ts.map +1 -0
  10. package/dist/auth/mcp-auth.js +286 -0
  11. package/dist/auth/mcp-auth.js.map +1 -0
  12. package/dist/config.d.ts +89 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +216 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/errors.d.ts +26 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +41 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/index.d.ts +32 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +371 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/library/notebook-library.d.ts +70 -0
  25. package/dist/library/notebook-library.d.ts.map +1 -0
  26. package/dist/library/notebook-library.js +279 -0
  27. package/dist/library/notebook-library.js.map +1 -0
  28. package/dist/library/types.d.ts +67 -0
  29. package/dist/library/types.d.ts.map +1 -0
  30. package/dist/library/types.js +8 -0
  31. package/dist/library/types.js.map +1 -0
  32. package/dist/resources/resource-handlers.d.ts +22 -0
  33. package/dist/resources/resource-handlers.d.ts.map +1 -0
  34. package/dist/resources/resource-handlers.js +216 -0
  35. package/dist/resources/resource-handlers.js.map +1 -0
  36. package/dist/session/browser-session.d.ts +108 -0
  37. package/dist/session/browser-session.d.ts.map +1 -0
  38. package/dist/session/browser-session.js +621 -0
  39. package/dist/session/browser-session.js.map +1 -0
  40. package/dist/session/session-manager.d.ts +77 -0
  41. package/dist/session/session-manager.d.ts.map +1 -0
  42. package/dist/session/session-manager.js +314 -0
  43. package/dist/session/session-manager.js.map +1 -0
  44. package/dist/session/session-timeout.d.ts +122 -0
  45. package/dist/session/session-timeout.d.ts.map +1 -0
  46. package/dist/session/session-timeout.js +281 -0
  47. package/dist/session/session-timeout.js.map +1 -0
  48. package/dist/session/shared-context-manager.d.ts +107 -0
  49. package/dist/session/shared-context-manager.d.ts.map +1 -0
  50. package/dist/session/shared-context-manager.js +447 -0
  51. package/dist/session/shared-context-manager.js.map +1 -0
  52. package/dist/tools/definitions/ask-question.d.ts +8 -0
  53. package/dist/tools/definitions/ask-question.d.ts.map +1 -0
  54. package/dist/tools/definitions/ask-question.js +211 -0
  55. package/dist/tools/definitions/ask-question.js.map +1 -0
  56. package/dist/tools/definitions/notebook-management.d.ts +3 -0
  57. package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
  58. package/dist/tools/definitions/notebook-management.js +243 -0
  59. package/dist/tools/definitions/notebook-management.js.map +1 -0
  60. package/dist/tools/definitions/session-management.d.ts +3 -0
  61. package/dist/tools/definitions/session-management.d.ts.map +1 -0
  62. package/dist/tools/definitions/session-management.js +41 -0
  63. package/dist/tools/definitions/session-management.js.map +1 -0
  64. package/dist/tools/definitions/system.d.ts +3 -0
  65. package/dist/tools/definitions/system.d.ts.map +1 -0
  66. package/dist/tools/definitions/system.js +143 -0
  67. package/dist/tools/definitions/system.js.map +1 -0
  68. package/dist/tools/definitions.d.ts +12 -0
  69. package/dist/tools/definitions.d.ts.map +1 -0
  70. package/dist/tools/definitions.js +26 -0
  71. package/dist/tools/definitions.js.map +1 -0
  72. package/dist/tools/handlers.d.ts +213 -0
  73. package/dist/tools/handlers.d.ts.map +1 -0
  74. package/dist/tools/handlers.js +813 -0
  75. package/dist/tools/handlers.js.map +1 -0
  76. package/dist/tools/index.d.ts +8 -0
  77. package/dist/tools/index.d.ts.map +1 -0
  78. package/dist/tools/index.js +8 -0
  79. package/dist/tools/index.js.map +1 -0
  80. package/dist/types.d.ts +82 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +5 -0
  83. package/dist/types.js.map +1 -0
  84. package/dist/utils/audit-logger.d.ts +140 -0
  85. package/dist/utils/audit-logger.d.ts.map +1 -0
  86. package/dist/utils/audit-logger.js +361 -0
  87. package/dist/utils/audit-logger.js.map +1 -0
  88. package/dist/utils/cert-pinning.d.ts +97 -0
  89. package/dist/utils/cert-pinning.d.ts.map +1 -0
  90. package/dist/utils/cert-pinning.js +328 -0
  91. package/dist/utils/cert-pinning.js.map +1 -0
  92. package/dist/utils/cleanup-manager.d.ts +133 -0
  93. package/dist/utils/cleanup-manager.d.ts.map +1 -0
  94. package/dist/utils/cleanup-manager.js +673 -0
  95. package/dist/utils/cleanup-manager.js.map +1 -0
  96. package/dist/utils/cli-handler.d.ts +16 -0
  97. package/dist/utils/cli-handler.d.ts.map +1 -0
  98. package/dist/utils/cli-handler.js +102 -0
  99. package/dist/utils/cli-handler.js.map +1 -0
  100. package/dist/utils/crypto.d.ts +175 -0
  101. package/dist/utils/crypto.d.ts.map +1 -0
  102. package/dist/utils/crypto.js +612 -0
  103. package/dist/utils/crypto.js.map +1 -0
  104. package/dist/utils/logger.d.ts +61 -0
  105. package/dist/utils/logger.d.ts.map +1 -0
  106. package/dist/utils/logger.js +92 -0
  107. package/dist/utils/logger.js.map +1 -0
  108. package/dist/utils/page-utils.d.ts +54 -0
  109. package/dist/utils/page-utils.d.ts.map +1 -0
  110. package/dist/utils/page-utils.js +405 -0
  111. package/dist/utils/page-utils.js.map +1 -0
  112. package/dist/utils/response-validator.d.ts +98 -0
  113. package/dist/utils/response-validator.d.ts.map +1 -0
  114. package/dist/utils/response-validator.js +352 -0
  115. package/dist/utils/response-validator.js.map +1 -0
  116. package/dist/utils/secrets-scanner.d.ts +126 -0
  117. package/dist/utils/secrets-scanner.d.ts.map +1 -0
  118. package/dist/utils/secrets-scanner.js +443 -0
  119. package/dist/utils/secrets-scanner.js.map +1 -0
  120. package/dist/utils/secure-memory.d.ts +130 -0
  121. package/dist/utils/secure-memory.d.ts.map +1 -0
  122. package/dist/utils/secure-memory.js +279 -0
  123. package/dist/utils/secure-memory.js.map +1 -0
  124. package/dist/utils/security.d.ts +83 -0
  125. package/dist/utils/security.d.ts.map +1 -0
  126. package/dist/utils/security.js +272 -0
  127. package/dist/utils/security.js.map +1 -0
  128. package/dist/utils/settings-manager.d.ts +37 -0
  129. package/dist/utils/settings-manager.d.ts.map +1 -0
  130. package/dist/utils/settings-manager.js +125 -0
  131. package/dist/utils/settings-manager.js.map +1 -0
  132. package/dist/utils/stealth-utils.d.ts +135 -0
  133. package/dist/utils/stealth-utils.d.ts.map +1 -0
  134. package/dist/utils/stealth-utils.js +398 -0
  135. package/dist/utils/stealth-utils.js.map +1 -0
  136. package/dist/utils/tool-validation.d.ts +93 -0
  137. package/dist/utils/tool-validation.d.ts.map +1 -0
  138. package/dist/utils/tool-validation.js +277 -0
  139. package/dist/utils/tool-validation.js.map +1 -0
  140. package/docs/SECURITY_IMPLEMENTATION_PLAN.md +437 -0
  141. package/docs/configuration.md +94 -0
  142. package/docs/tools.md +34 -0
  143. package/docs/troubleshooting.md +59 -0
  144. package/docs/usage-guide.md +245 -0
  145. package/package.json +82 -0
package/SECURITY.md ADDED
@@ -0,0 +1,539 @@
1
+ # Security Hardening Documentation
2
+
3
+ This is a security-hardened fork of [PleasePrompto/notebooklm-mcp](https://github.com/PleasePrompto/notebooklm-mcp), maintained by [Pantheon Security](https://pantheonsecurity.io).
4
+
5
+ **Version**: 1.4.0-secure
6
+ **Security Features**: 14 hardening layers
7
+
8
+ ## Security Features Overview
9
+
10
+ | Feature | Status | Description |
11
+ |---------|--------|-------------|
12
+ | Input Validation | ✅ | URL whitelisting, sanitization |
13
+ | Rate Limiting | ✅ | Per-session request throttling |
14
+ | Log Sanitization | ✅ | Credential masking |
15
+ | Audit Logging | ✅ | Tamper-evident event logging |
16
+ | Session Timeout | ✅ | Hard lifetime + inactivity limits |
17
+ | MCP Authentication | ✅ | Token-based auth with lockout |
18
+ | Response Validation | ✅ | Prompt injection detection |
19
+ | **Post-Quantum Encryption** | ✅ | ML-KEM-768 + ChaCha20-Poly1305 |
20
+ | **Secrets Scanning** | ✅ | Detect API keys, tokens, passwords |
21
+ | **Certificate Pinning** | ✅ | Google TLS MITM protection |
22
+ | **Memory Scrubbing** | ✅ | Zero sensitive data after use |
23
+ | **MEDUSA Integration** | ✅ | Automated security scanning |
24
+
25
+ ---
26
+
27
+ ## Post-Quantum Encryption (NEW)
28
+
29
+ ### Why Post-Quantum?
30
+
31
+ Recent events (including alleged quantum computer attacks on major infrastructure) highlight the urgency of preparing for "Q-Day" - when quantum computers can break classical encryption.
32
+
33
+ This MCP uses **hybrid post-quantum encryption** that combines:
34
+ - **ML-KEM-768 (Kyber)** - NIST-standardized post-quantum key encapsulation
35
+ - **ChaCha20-Poly1305** - Modern stream cipher (NOT AES-GCM)
36
+
37
+ ### Why ChaCha20-Poly1305 over AES-GCM?
38
+
39
+ | Property | ChaCha20-Poly1305 | AES-GCM |
40
+ |----------|-------------------|---------|
41
+ | Timing attacks | Immune (constant-time) | Vulnerable without AES-NI |
42
+ | Software speed | Fast everywhere | Slow without hardware |
43
+ | Complexity | Simple | Complex (GCM mode) |
44
+ | Adoption | Google, Cloudflare TLS | Legacy systems |
45
+
46
+ This provides **double protection**: even if one algorithm is broken, the other remains secure.
47
+
48
+ ### What's Encrypted
49
+
50
+ - Browser session state (cookies, localStorage)
51
+ - Session storage data
52
+ - Post-quantum key pairs (double-encrypted)
53
+
54
+ ### Encrypted File Format
55
+
56
+ Files are saved with `.pqenc` extension:
57
+ ```json
58
+ {
59
+ "version": 3,
60
+ "algorithm": "chacha20-poly1305",
61
+ "pqAlgorithm": "ML-KEM-768",
62
+ "encapsulatedKey": "<base64>",
63
+ "nonce": "<base64>",
64
+ "salt": "<base64>",
65
+ "ciphertext": "<base64 with Poly1305 tag appended>"
66
+ }
67
+ ```
68
+
69
+ ### Configuration
70
+
71
+ ```bash
72
+ # Enable/disable post-quantum encryption (default: enabled)
73
+ NLMCP_USE_POST_QUANTUM=true
74
+
75
+ # Provide your own classical key (optional)
76
+ NLMCP_ENCRYPTION_KEY=<base64-32-bytes>
77
+
78
+ # Disable encryption entirely (NOT recommended)
79
+ NLMCP_ENCRYPTION_ENABLED=false
80
+ ```
81
+
82
+ ### Automatic Migration
83
+
84
+ When you upgrade, existing unencrypted files are automatically:
85
+ 1. Loaded
86
+ 2. Re-encrypted with ML-KEM-768 + ChaCha20-Poly1305
87
+ 3. Old unencrypted files are deleted
88
+
89
+ ---
90
+
91
+ ## Secrets Scanning (NEW)
92
+
93
+ Real-time detection of credentials in logs and responses using patterns from TruffleHog and GitLeaks.
94
+
95
+ ### Detected Secret Types
96
+
97
+ | Category | Types |
98
+ |----------|-------|
99
+ | Cloud | AWS Access Keys, GCP API Keys, Azure Tokens |
100
+ | AI Services | OpenAI, Anthropic, Google AI API keys |
101
+ | Source Control | GitHub PATs, GitLab tokens |
102
+ | Communication | Slack tokens/webhooks |
103
+ | Payment | Stripe API keys |
104
+ | Auth | JWTs, Bearer tokens, Basic Auth |
105
+ | Databases | PostgreSQL, MongoDB, MySQL connection strings |
106
+ | Keys | RSA, EC, SSH, PGP private keys |
107
+
108
+ ### Configuration
109
+
110
+ ```bash
111
+ NLMCP_SECRETS_SCANNING=true # Enable scanning (default: true)
112
+ NLMCP_SECRETS_BLOCK=false # Block on detection (default: false, just warn)
113
+ NLMCP_SECRETS_REDACT=true # Auto-redact secrets (default: true)
114
+ NLMCP_SECRETS_MIN_SEVERITY=low # Minimum severity: critical, high, medium, low
115
+ NLMCP_SECRETS_IGNORE=pattern1,pattern2 # Ignore specific patterns
116
+ ```
117
+
118
+ ### Example Detection
119
+
120
+ ```
121
+ 🔐 Secrets detected: 1 critical, 0 high
122
+ - AWS Access Key ID at line 42
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Certificate Pinning (NEW)
128
+
129
+ Protects HTTPS connections to Google by validating server certificate chains against known-good SPKI hashes.
130
+
131
+ ### Why Certificate Pinning?
132
+
133
+ Prevents man-in-the-middle attacks even if:
134
+ - A rogue CA certificate is installed on the system
135
+ - Corporate proxies attempt SSL inspection
136
+ - DNS is compromised
137
+
138
+ ### Pinned Certificates
139
+
140
+ - **GTS Root R1-R4** - Google Trust Services roots
141
+ - **GlobalSign Root CA R2** - Backup root
142
+ - **DigiCert Global Root G2** - Backup root
143
+
144
+ ### Configuration
145
+
146
+ ```bash
147
+ NLMCP_CERT_PINNING=true # Enable pinning (default: true)
148
+ NLMCP_CERT_FAIL_OPEN=false # Allow on failure (default: false)
149
+ NLMCP_CERT_REPORT_ONLY=false # Log but don't block (default: false)
150
+ ```
151
+
152
+ ### Violation Response
153
+
154
+ ```
155
+ 🔒 Certificate pinning violation for notebooklm.google.com
156
+ Chain hashes: abc123...
157
+ Expected one of: hxqRlP..., Vfd95B...
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Memory Scrubbing (NEW)
163
+
164
+ Sensitive data is securely wiped from memory after use to prevent:
165
+ - Memory dump attacks
166
+ - Cold boot attacks
167
+ - Credential persistence in RAM
168
+
169
+ ### Features
170
+
171
+ | Feature | Description |
172
+ |---------|-------------|
173
+ | `zeroBuffer()` | Securely zero-fill Buffer objects |
174
+ | `SecureString` | String wrapper with `.wipe()` method |
175
+ | `SecureCredential` | Auto-expiring credential with timer |
176
+ | `SecureObject` | Object with dispose-and-wipe capability |
177
+ | `secureCompare()` | Timing-safe string comparison |
178
+
179
+ ### Auto-cleanup
180
+
181
+ Using `FinalizationRegistry`, secure buffers are automatically wiped when garbage collected.
182
+
183
+ ### Usage
184
+
185
+ ```typescript
186
+ import { SecureCredential, withSecureCredential } from './utils/secure-memory.js';
187
+
188
+ // Auto-wipe after 5 minutes
189
+ const cred = new SecureCredential(apiKey, 300000);
190
+
191
+ // Or use helper that auto-wipes after function completes
192
+ await withSecureCredential(apiKey, async (cred) => {
193
+ await makeRequest(cred.getValue());
194
+ });
195
+ // Credential is now wiped
196
+ ```
197
+
198
+ ---
199
+
200
+ ## MEDUSA Integration (NEW)
201
+
202
+ Automated security scanning using [MEDUSA](https://github.com/Pantheon-Security/medusa) - Multi-Language Security Scanner with 46+ analyzers.
203
+
204
+ ### Quick Scan
205
+
206
+ ```bash
207
+ npm run security-scan
208
+ # or
209
+ medusa scan . --fail-on high
210
+ ```
211
+
212
+ ### Configuration
213
+
214
+ See `.medusa.yml` in project root.
215
+
216
+ ### CI/CD Integration
217
+
218
+ ```yaml
219
+ # GitHub Actions
220
+ - name: Security Scan
221
+ run: npm run security-scan
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Audit Logging
227
+
228
+ All events are logged with cryptographic integrity:
229
+
230
+ ```
231
+ ~/.local/share/notebooklm-mcp/audit/
232
+ ├── audit-2025-11-28.jsonl
233
+ └── ...
234
+ ```
235
+
236
+ ### Log Format (JSONL with hash chain)
237
+
238
+ ```json
239
+ {"timestamp":"2025-11-28T10:30:00Z","type":"tool","event":"ask_question","success":true,"duration_ms":3420,"hash":"a1b2c3..."}
240
+ ```
241
+
242
+ Each entry's hash includes the previous entry, making tampering detectable.
243
+
244
+ ### Configuration
245
+
246
+ ```bash
247
+ NLMCP_AUDIT_ENABLED=true # Default: true
248
+ NLMCP_AUDIT_DIR=/path/to/audit # Default: ~/.local/share/notebooklm-mcp/audit
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Session Timeout
254
+
255
+ Sessions are protected by dual timeout enforcement:
256
+
257
+ | Timeout | Default | Purpose |
258
+ |---------|---------|---------|
259
+ | Max Lifetime | 8 hours | Hard limit regardless of activity |
260
+ | Inactivity | 30 minutes | Closes idle sessions |
261
+
262
+ ### Configuration
263
+
264
+ ```bash
265
+ NLMCP_SESSION_MAX_LIFETIME=28800 # 8 hours in seconds
266
+ NLMCP_SESSION_INACTIVITY=1800 # 30 minutes in seconds
267
+ ```
268
+
269
+ ---
270
+
271
+ ## MCP Authentication
272
+
273
+ Require authentication for all MCP requests.
274
+
275
+ ### Setup
276
+
277
+ On first run with auth enabled, a token is auto-generated:
278
+ ```
279
+ ╔════════════════════════════════════════════════════════════╗
280
+ ║ NEW MCP AUTHENTICATION TOKEN GENERATED ║
281
+ ╠════════════════════════════════════════════════════════════╣
282
+ ║ Token: <your-token> ║
283
+ ╠════════════════════════════════════════════════════════════╣
284
+ ║ Add to your MCP client config: ║
285
+ ║ NLMCP_AUTH_TOKEN=<token> ║
286
+ ╚════════════════════════════════════════════════════════════╝
287
+ ```
288
+
289
+ ### Claude Code Configuration
290
+
291
+ ```bash
292
+ claude mcp add notebooklm \
293
+ --env NLMCP_AUTH_ENABLED=true \
294
+ --env NLMCP_AUTH_TOKEN=<your-token> \
295
+ npx notebooklm-mcp-secure
296
+ ```
297
+
298
+ ### Rate Limiting for Failed Auth
299
+
300
+ - 5 failed attempts = 5 minute lockout
301
+ - Prevents brute force attacks
302
+
303
+ ---
304
+
305
+ ## Response Validation
306
+
307
+ All responses from NotebookLM are scanned for:
308
+
309
+ ### Prompt Injection Detection
310
+ - `ignore previous instructions`
311
+ - `you are now in [mode]`
312
+ - `system:` injections
313
+ - Chat template delimiters (`[INST]`, `<|im_start|>`)
314
+
315
+ ### Suspicious URL Detection
316
+ - URL shorteners (bit.ly, tinyurl)
317
+ - Paste services (pastebin)
318
+ - File/JavaScript protocols
319
+ - Raw IP addresses
320
+ - Webhook URLs
321
+
322
+ ### Encoded Payload Detection
323
+ - Long Base64 strings
324
+ - Hex encoded data
325
+ - Heavy URL encoding
326
+ - Unicode escape sequences
327
+
328
+ ### Configuration
329
+
330
+ ```bash
331
+ NLMCP_RESPONSE_VALIDATION=true
332
+ NLMCP_BLOCK_PROMPT_INJECTION=true
333
+ NLMCP_BLOCK_SUSPICIOUS_URLS=true
334
+ NLMCP_BLOCK_ENCODED_PAYLOADS=false # Just warn by default
335
+ ```
336
+
337
+ ---
338
+
339
+ ## Input Validation
340
+
341
+ All user inputs are validated:
342
+
343
+ | Input | Validation |
344
+ |-------|-----------|
345
+ | `notebook_url` | HTTPS only, domain whitelist (notebooklm.google.com variants) |
346
+ | `notebook_id` | Alphanumeric + dashes only, max 128 chars |
347
+ | `session_id` | Alphanumeric + dashes only, max 64 chars |
348
+ | `question` | Non-empty, max 32,000 chars |
349
+
350
+ ### URL Whitelisting
351
+
352
+ Allowed domains:
353
+ - `notebooklm.google.com`
354
+ - Regional variants (`.co.uk`, `.de`, `.fr`, etc.)
355
+
356
+ Blocked:
357
+ - `javascript:` URLs
358
+ - `data:` URLs
359
+ - `file:` URLs
360
+ - Non-HTTPS URLs
361
+ - Path traversal attempts
362
+
363
+ ---
364
+
365
+ ## Log Sanitization
366
+
367
+ Sensitive data is masked in all log output:
368
+ - Email: `j***n@example.com`
369
+ - Passwords: `[REDACTED]`
370
+ - API keys: `[REDACTED]`
371
+ - Tokens: `[REDACTED]`
372
+
373
+ ---
374
+
375
+ ## Rate Limiting
376
+
377
+ Built-in rate limiting prevents abuse:
378
+ - 100 requests per minute per session
379
+ - Configurable via `RateLimiter` class
380
+
381
+ ---
382
+
383
+ ## Remaining Considerations
384
+
385
+ ### Browser Automation Risks
386
+
387
+ This MCP uses browser automation (Patchright) which:
388
+ - May violate Google's Terms of Service
389
+ - Could be detected and blocked
390
+
391
+ **Recommendations:**
392
+ - Use a dedicated Google account (not your primary)
393
+ - Run in an isolated environment (VM or container)
394
+
395
+ ### Not Encrypted (Chrome Profile)
396
+
397
+ The Chrome profile directory itself is not fully encrypted:
398
+ - `~/.local/share/notebooklm-mcp/chrome_profile/`
399
+
400
+ The sensitive state files (cookies, session) ARE encrypted with post-quantum cryptography.
401
+
402
+ ---
403
+
404
+ ## Quick Start
405
+
406
+ ```bash
407
+ # Install
408
+ npm install notebooklm-mcp-secure
409
+
410
+ # Or with Claude Code
411
+ claude mcp add notebooklm npx notebooklm-mcp-secure@latest
412
+
413
+ # With all security features
414
+ claude mcp add notebooklm \
415
+ --env NLMCP_AUTH_ENABLED=true \
416
+ --env NLMCP_AUTH_TOKEN=$(openssl rand -base64 32) \
417
+ --env NLMCP_USE_POST_QUANTUM=true \
418
+ npx notebooklm-mcp-secure@latest
419
+ ```
420
+
421
+ ---
422
+
423
+ ## Security Module API
424
+
425
+ ```typescript
426
+ // Input validation & rate limiting
427
+ import {
428
+ validateNotebookUrl,
429
+ validateSessionId,
430
+ validateQuestion,
431
+ sanitizeForLogging,
432
+ maskEmail,
433
+ RateLimiter,
434
+ SecurityError,
435
+ } from './utils/security.js';
436
+
437
+ // Post-quantum encryption (ML-KEM-768 + ChaCha20-Poly1305)
438
+ import {
439
+ getSecureStorage,
440
+ SecureStorage,
441
+ encryptPQ,
442
+ decryptPQ,
443
+ generatePQKeyPair,
444
+ } from './utils/crypto.js';
445
+
446
+ // Response validation & prompt injection detection
447
+ import { getResponseValidator, validateResponse } from './utils/response-validator.js';
448
+
449
+ // Tamper-evident audit logging
450
+ import { getAuditLogger, audit } from './utils/audit-logger.js';
451
+
452
+ // MCP token authentication
453
+ import { getMCPAuthenticator, authenticateMCPRequest } from './auth/mcp-auth.js';
454
+
455
+ // Secrets scanning
456
+ import {
457
+ SecretsScanner,
458
+ scanForSecrets,
459
+ scanAndRedactSecrets,
460
+ } from './utils/secrets-scanner.js';
461
+
462
+ // Certificate pinning
463
+ import {
464
+ CertificatePinningManager,
465
+ getCertificatePinningManager,
466
+ validateCertificatePin,
467
+ } from './utils/cert-pinning.js';
468
+
469
+ // Memory security
470
+ import {
471
+ SecureString,
472
+ SecureCredential,
473
+ SecureObject,
474
+ zeroBuffer,
475
+ withSecureCredential,
476
+ secureCompare,
477
+ } from './utils/secure-memory.js';
478
+
479
+ // === USAGE EXAMPLES ===
480
+
481
+ // Post-quantum encrypted storage
482
+ const storage = getSecureStorage();
483
+ await storage.save('/path/to/file', sensitiveData);
484
+ const data = await storage.load('/path/to/file');
485
+
486
+ // Direct post-quantum encryption
487
+ const keyPair = generatePQKeyPair();
488
+ const encrypted = encryptPQ('secret data', keyPair.publicKey);
489
+ const decrypted = decryptPQ(encrypted, keyPair.secretKey);
490
+
491
+ // Secrets scanning
492
+ const secrets = scanForSecrets(responseText);
493
+ if (secrets.length > 0) {
494
+ console.log('Found secrets:', secrets.map(s => s.type));
495
+ }
496
+
497
+ // Auto-redact secrets
498
+ const { clean, secrets: found } = await scanAndRedactSecrets(responseText);
499
+
500
+ // Memory-safe credential handling
501
+ await withSecureCredential(apiKey, async (cred) => {
502
+ await makeRequest(cred.getValue());
503
+ }); // Auto-wiped after use
504
+
505
+ // Timing-safe comparison (prevents timing attacks)
506
+ if (secureCompare(userToken, storedToken)) {
507
+ // Authenticated
508
+ }
509
+
510
+ // Response validation
511
+ const result = await validateResponse(notebookLMResponse);
512
+ if (!result.safe) {
513
+ console.log('Blocked:', result.blocked);
514
+ }
515
+
516
+ // Audit logging
517
+ await audit.tool('ask_question', true, 3420, { question_length: 150 });
518
+ await audit.security('prompt_injection_detected', 'critical', { pattern: '...' });
519
+ ```
520
+
521
+ ---
522
+
523
+ ## Reporting Vulnerabilities
524
+
525
+ If you discover a security vulnerability:
526
+ - Email: support@pantheonsecurity.io
527
+ - Do NOT open a public GitHub issue for security vulnerabilities
528
+
529
+ ---
530
+
531
+ ## Credits
532
+
533
+ - Original implementation: [Gérôme Dexheimer](https://github.com/PleasePrompto)
534
+ - Security hardening: [Pantheon Security](https://pantheonsecurity.io)
535
+ - Post-quantum crypto: [@noble/post-quantum](https://www.npmjs.com/package/@noble/post-quantum)
536
+
537
+ ## License
538
+
539
+ MIT License (same as original)
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Authentication Manager for NotebookLM
3
+ *
4
+ * Handles:
5
+ * - Interactive login (headful browser for setup)
6
+ * - Auto-login with credentials (email/password from ENV)
7
+ * - Browser state persistence (cookies + localStorage + sessionStorage)
8
+ * - Cookie expiry validation
9
+ * - State expiry checks (24h file age)
10
+ * - Hard reset for clean start
11
+ *
12
+ * Based on the Python implementation from auth.py
13
+ */
14
+ import type { BrowserContext, Page } from "patchright";
15
+ import type { ProgressCallback } from "../types.js";
16
+ export declare class AuthManager {
17
+ private stateFilePath;
18
+ private sessionFilePath;
19
+ constructor();
20
+ /**
21
+ * Save entire browser state (cookies + localStorage)
22
+ * Uses post-quantum encrypted storage for sensitive auth data
23
+ */
24
+ saveBrowserState(context: BrowserContext, page?: Page): Promise<boolean>;
25
+ /**
26
+ * Check if saved browser state exists (encrypted or unencrypted)
27
+ */
28
+ hasSavedState(): Promise<boolean>;
29
+ /**
30
+ * Get path to saved browser state (checks encrypted versions too)
31
+ */
32
+ getStatePath(): string | null;
33
+ /**
34
+ * Get valid state path (checks expiry)
35
+ */
36
+ getValidStatePath(): Promise<string | null>;
37
+ /**
38
+ * Load sessionStorage from file (decrypts if encrypted)
39
+ */
40
+ loadSessionStorage(): Promise<Record<string, string> | null>;
41
+ /**
42
+ * Validate if saved state is still valid
43
+ */
44
+ validateState(context: BrowserContext): Promise<boolean>;
45
+ /**
46
+ * Validate if critical authentication cookies are still valid
47
+ */
48
+ validateCookiesExpiry(context: BrowserContext): Promise<boolean>;
49
+ /**
50
+ * Check if the saved state file is too old (>24 hours)
51
+ */
52
+ isStateExpired(): Promise<boolean>;
53
+ /**
54
+ * Perform interactive login
55
+ * User will see a browser window and login manually
56
+ *
57
+ * SIMPLE & RELIABLE: Just wait for URL to change to notebooklm.google.com
58
+ */
59
+ performLogin(page: Page, sendProgress?: ProgressCallback): Promise<boolean>;
60
+ /**
61
+ * Attempt to authenticate using configured credentials
62
+ */
63
+ loginWithCredentials(context: BrowserContext, page: Page, email: string, password: string): Promise<boolean>;
64
+ /**
65
+ * Wait for Google to redirect to NotebookLM after successful login (SIMPLE & RELIABLE)
66
+ *
67
+ * Just checks if URL changes to notebooklm.google.com - no complex UI element searching!
68
+ * Matches the simplified approach used in performLogin().
69
+ */
70
+ private waitForRedirectAfterLogin;
71
+ /**
72
+ * Wait for NotebookLM to load (SIMPLE & RELIABLE)
73
+ *
74
+ * Just checks if URL starts with notebooklm.google.com - no complex UI element searching!
75
+ * Matches the simplified approach used in performLogin().
76
+ */
77
+ private waitForNotebook;
78
+ /**
79
+ * Handle possible account chooser
80
+ */
81
+ private handleAccountChooser;
82
+ /**
83
+ * Fill email identifier field with human-like typing
84
+ */
85
+ private fillIdentifier;
86
+ /**
87
+ * Fill password field with human-like typing
88
+ */
89
+ private fillPassword;
90
+ /**
91
+ * Click text element
92
+ */
93
+ private clickText;
94
+ /**
95
+ * Load authentication state from a specific file path (decrypts if encrypted)
96
+ */
97
+ loadAuthState(context: BrowserContext, statePath: string): Promise<boolean>;
98
+ /**
99
+ * Perform interactive setup (for setup_auth tool)
100
+ * Opens a PERSISTENT browser for manual login
101
+ *
102
+ * CRITICAL: Uses the SAME persistent context as runtime!
103
+ * This ensures cookies are automatically saved to the Chrome profile.
104
+ *
105
+ * Benefits over temporary browser:
106
+ * - Session cookies persist correctly (Playwright bug workaround)
107
+ * - Same fingerprint as runtime
108
+ * - No need for addCookies() workarounds
109
+ * - Automatic cookie persistence via Chrome profile
110
+ *
111
+ * @param sendProgress Optional progress callback
112
+ * @param overrideHeadless Optional override for headless mode (true = visible, false = headless)
113
+ * If not provided, defaults to true (visible) for setup
114
+ */
115
+ performSetup(sendProgress?: ProgressCallback, overrideHeadless?: boolean): Promise<boolean>;
116
+ /**
117
+ * Clear ALL authentication data for account switching
118
+ *
119
+ * CRITICAL: This deletes EVERYTHING to ensure only ONE account is active:
120
+ * - All state files (encrypted .pqenc, .enc, and unencrypted .json)
121
+ * - sessionStorage files
122
+ * - Chrome profile directory (browser fingerprint, cache, etc.)
123
+ * - Post-quantum key pairs
124
+ *
125
+ * Use this BEFORE authenticating a new account!
126
+ */
127
+ clearAllAuthData(): Promise<void>;
128
+ /**
129
+ * Clear all saved authentication state (including encrypted versions)
130
+ */
131
+ clearState(): Promise<boolean>;
132
+ /**
133
+ * HARD RESET: Completely delete ALL authentication state
134
+ */
135
+ hardResetState(): Promise<boolean>;
136
+ }
137
+ //# sourceMappingURL=auth-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../../src/auth/auth-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAmBpD,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;;IAWhC;;;OAGG;IACG,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAmD9E;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAKvC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAQ7B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAejD;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAuBlE;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAoC9D;;OAEG;IACG,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDtE;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAsBxC;;;;;OAKG;IACG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmFjF;;OAEG;IACG,oBAAoB,CACxB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC;IA2InB;;;;;OAKG;YACW,yBAAyB;IA4BvC;;;;;OAKG;YACW,eAAe;IAsB7B;;OAEG;YACW,oBAAoB;IA+BlC;;OAEG;YACW,cAAc;IA2H5B;;OAEG;YACW,YAAY;IA+F1B;;OAEG;YACW,SAAS;IAuBvB;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BjF;;;;;;;;;;;;;;;;OAgBG;IACG,YAAY,CAAC,YAAY,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAoEjG;;;;;;;;;;OAUG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CvC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBpC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAgDzC"}