Skip to content

Security hardening across payment, networking and URL handling#46

Open
rm335 wants to merge 1 commit into
thomasdye12:mainfrom
rm335:feature/payment-and-network-hardening
Open

Security hardening across payment, networking and URL handling#46
rm335 wants to merge 1 commit into
thomasdye12:mainfrom
rm335:feature/payment-and-network-hardening

Conversation

@rm335

@rm335 rm335 commented Mar 12, 2026

Copy link
Copy Markdown

Security hardening across payment, networking and URL handling

Summary

  • Close critical payment bypass: the tdsvideopayment:// URL scheme previously unlocked the app by simply setting a UserDefaults boolean — any app (or Safari) could call it. Now requires a server-verified token before unlocking.
  • Add SSL certificate pinning: the existing pinnedPublicKeyHash was declared but never used. Implemented URLSessionDelegate to validate the server's public key SHA-256 hash on every API request.
  • Authenticate the HTTP screen-mirror server: the local Swifter server on port 8080 was open to anyone on the network. Each server start now generates a random UUID token; /frame and /mjpeg endpoints reject requests without a valid
    ?token= parameter.
  • Sanitize all URL inputs: tdsvideo:// deep links, shared UserDefaults URLs, and Darwin notification URLs now only accept http/https schemes — blocks file://, javascript:, and other dangerous schemes from loading in the CarPlay
    webview.
  • Move device UUID to Keychain: BackgroundAuthID was stored in UserDefaults (trivially readable/editable). Migrated to Keychain with kSecAttrAccessibleAfterFirstUnlock.
  • Centralise configuration: extracted hardcoded API URLs, ports, email, and payment URL into a single AppConfig.swift enum. Removed dead McDonald's API URLs (ManagmentURLS class) that leaked unrelated endpoint information.

Test plan

  • Verify payment flow: open tdsvideopayment:// without a token — app should NOT unlock
  • Verify payment flow: complete a real payment — server callback with valid token should unlock the app
  • Confirm API calls still work with SSL pinning enabled (check pinnedPublicKeyHash matches the production certificate)
  • Start the HTTP server and verify /frame and /mjpeg return 403 without the token query parameter
  • Open the HTML page at http://<ip>:8080/ and confirm the video stream loads (token is auto-injected)
  • Test tdsvideo://shared-url?url=file:///etc/passwd — should be rejected
  • Test tdsvideo://shared-url?url=https://example.com — should load normally in CarPlay
  • Verify device UUID persists across app reinstalls (Keychain survives uninstall on iOS)

Server-side prerequisite

A new POST /verifyPayment endpoint is needed on api.thomasdye.net that accepts { "token": "...", "deviceID": "..." } and returns HTTP 200 if valid. The payment callback URL should become
tdsvideopayment://?token=<server-generated-token>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant