Repository navigation
Security hardening (OWASP Top 10 review) - #25
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A review of the local bridge and web editor against the OWASP Top 10 (2025) found one high-severity issue and three hardening gaps. One commit per finding.
1. Refuse cross-site requests (A01 Broken Access Control, high)
The Host check blocked DNS rebinding, but the bridge accepted POSTs from any website open in the same browser (cross-site request forgery). Responses were unreadable, but every action still ran, including ones that change banks stored on the device. Recent Chrome versions ask before a site can reach localhost; Safari and Firefox don't.
Handler._cross_site()on every POST: a browserOriginmust be exactly the bridge's own origin. Without one,Sec-Fetch-Site: cross-siteis refused.2. Forbid framing and MIME sniffing (A02 Security Misconfiguration)
Every response now sends
X-Frame-Options: DENY,Content-Security-Policy: frame-ancestors 'none'andX-Content-Type-Options: nosniff, so another site can't load the editor in a hidden frame and trick clicks onto RESTORE or a confirm dialog.3. Size limits (A10 Mishandling of Exceptional Conditions)
4. Verify the daemon's backup folder (A01, low)
The root daemon stores backups under
/Users/Shared, which every account can write to. It now creates the path with0755and checks every part of it: no symlinks, owned by root, not writable by others, sticky shared base. If anything's off, it logs a warning and uses a root-only folder under/Library/Application Supportinstead. Existing installs pass the check unchanged.Checked and fine
Path traversal (backup names, static files, zip slip), XSS (every device/file-derived name is escaped), DNS rebinding, loopback-only binding.
Testing
test_bridge.py(origin guards, security headers, body cap, zip import caps) and a newtest_daemon_dirs.pyapp.htmlwas blocked by the browser (frame-ancestors 'none')secure_dirreturnsTruefor the existing/Users/Shared/DehliMusikkinstall (run as root)