Summary
Seven medium-severity security findings identified during deep audit on 2026-04-05. These cover multiple attack surfaces across content scripts, storage, API boundaries, and logging.
Findings
1. Predictable DOM Element IDs in Content Script Enable Clobbering
File: src/content/selection-overlay.ts lines 29, 44, 56
Elements are injected with well-known IDs (proofsnap-selection-overlay, proofsnap-selection-box, proofsnap-instructions). A malicious page can pre-create elements with these IDs to intercept events or manipulate cleanup logic.
Fix: Use cryptographic random suffixes: overlay.id = \proofsnap-overlay-${crypto.getRandomValues(new Uint32Array(1))[0].toString(36)}``, or use Shadow DOM isolation.
2. Unbounded Screenshot Storage in IndexedDB
Files: src/services/IndexedDBService.ts lines 95-106, src/background/service-worker.ts lines 300-317
Full base64 screenshot data URLs (multi-MB each) stored with no size limits, max count, or TTL. Failed uploads remain indefinitely. An attacker causing repeated upload failures triggers local DoS via storage exhaustion.
Fix: Implement a MAX_STORED_ASSETS limit (e.g., 50) and periodic cleanup removing failed assets older than 7 days.
3. API Responses Lack Runtime Schema Validation
Files: src/services/ApiClient.ts line 175, src/services/UploadService.ts line 330, src/services/AuthService.ts lines 52, 69, 144
All API responses are deserialized via response.json() and used directly. TypeScript generics provide no runtime protection. A MITM attacker could inject malformed responses that flow into storage, DOM, and URL construction unchecked.
Fix: Add runtime validation for critical API responses (login, upload, user profile) using manual type checks or a validation library.
4. Full OAuth Response URL Logged on Error Path
File: src/services/AuthService.ts line 126
console.error('No id_token found in response', responseUrl);
Logs the complete OAuth redirect response URL which may contain tokens, nonces, and account info.
Fix: console.error('No id_token found in Google Auth response URL') without the raw URL.
5. Unsanitized mimeType Used for Filename Extension
File: src/services/UploadService.ts line 306
const filename = `screenshot_${Date.now()}.${asset.mimeType.split('/')[1]}`;
If IndexedDB asset data is tampered, split('/')[1] could contain path traversal characters affecting server-side file handling.
Fix: Whitelist extensions: const ext = ['png','jpeg','jpg','webp'].includes(rawExt) ? rawExt : 'png'.
6. Unbounded Callback Accumulation in UploadService
File: src/services/UploadService.ts lines 158-161
onUploadComplete() adds callbacks to a Map with unique keys but never removes them. Over the service worker lifecycle, this causes memory growth and duplicate invocations.
Fix: Use a single-slot callback pattern instead of a Map.
7. No CSP for Offscreen Document and Share Page
File: manifest.template.json lines 27-29
CSP is defined only for extension_pages. The offscreen document and share page lack explicit CSP <meta> tags, reducing defense-in-depth.
Fix: Add <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'"> to offscreen.html and share.html.
Generated by Omni AI Deep Check on 2026-04-05
Summary
Seven medium-severity security findings identified during deep audit on 2026-04-05. These cover multiple attack surfaces across content scripts, storage, API boundaries, and logging.
Findings
1. Predictable DOM Element IDs in Content Script Enable Clobbering
File:
src/content/selection-overlay.tslines 29, 44, 56Elements are injected with well-known IDs (
proofsnap-selection-overlay,proofsnap-selection-box,proofsnap-instructions). A malicious page can pre-create elements with these IDs to intercept events or manipulate cleanup logic.Fix: Use cryptographic random suffixes:
overlay.id = \proofsnap-overlay-${crypto.getRandomValues(new Uint32Array(1))[0].toString(36)}``, or use Shadow DOM isolation.2. Unbounded Screenshot Storage in IndexedDB
Files:
src/services/IndexedDBService.tslines 95-106,src/background/service-worker.tslines 300-317Full base64 screenshot data URLs (multi-MB each) stored with no size limits, max count, or TTL. Failed uploads remain indefinitely. An attacker causing repeated upload failures triggers local DoS via storage exhaustion.
Fix: Implement a MAX_STORED_ASSETS limit (e.g., 50) and periodic cleanup removing failed assets older than 7 days.
3. API Responses Lack Runtime Schema Validation
Files:
src/services/ApiClient.tsline 175,src/services/UploadService.tsline 330,src/services/AuthService.tslines 52, 69, 144All API responses are deserialized via
response.json()and used directly. TypeScript generics provide no runtime protection. A MITM attacker could inject malformed responses that flow into storage, DOM, and URL construction unchecked.Fix: Add runtime validation for critical API responses (login, upload, user profile) using manual type checks or a validation library.
4. Full OAuth Response URL Logged on Error Path
File:
src/services/AuthService.tsline 126Logs the complete OAuth redirect response URL which may contain tokens, nonces, and account info.
Fix:
console.error('No id_token found in Google Auth response URL')without the raw URL.5. Unsanitized mimeType Used for Filename Extension
File:
src/services/UploadService.tsline 306If IndexedDB asset data is tampered,
split('/')[1]could contain path traversal characters affecting server-side file handling.Fix: Whitelist extensions:
const ext = ['png','jpeg','jpg','webp'].includes(rawExt) ? rawExt : 'png'.6. Unbounded Callback Accumulation in UploadService
File:
src/services/UploadService.tslines 158-161onUploadComplete()adds callbacks to a Map with unique keys but never removes them. Over the service worker lifecycle, this causes memory growth and duplicate invocations.Fix: Use a single-slot callback pattern instead of a Map.
7. No CSP for Offscreen Document and Share Page
File:
manifest.template.jsonlines 27-29CSP is defined only for
extension_pages. The offscreen document and share page lack explicit CSP<meta>tags, reducing defense-in-depth.Fix: Add
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'">tooffscreen.htmlandshare.html.Generated by Omni AI Deep Check on 2026-04-05