Add automatic update checking with SHA256 hash comparison#53
Conversation
Implements simple auto-update checking as requested in issue #21: - Fetches latest script version from GitHub raw - Compares SHA256 hashes of local vs remote versions - Shows alert notification when new version is detected - Includes direct link to releases page for downloading - Checks once per day to avoid excessive network calls - Gracefully handles network failures without false alerts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Nick Sweeting <pirate@users.noreply.github.com>
Pull Request ReviewThanks for implementing the auto-update checking feature! This is a well-structured implementation that addresses issue #21. Here's my detailed review: ✅ Strengths
🔍 Code Quality Issues1. Missing Configuration Flag (Priority: High)The README shows that all monitors have configuration flags (e.g., # In the xbar.var section (line ~31):
# <xbar.var>boolean(MONITOR_UPDATES=true): Check for updates once per day</xbar.var>
# In the config section (line ~73):
MONITOR_UPDATES = os.environ.get("MONITOR_UPDATES", "true").lower() == "true"
# In check_for_updates():
def check_for_updates(state: Dict[str, Any]) -> List[Tuple[str, str, str]]:
"""Check if a new version is available on GitHub."""
events = []
if not MONITOR_UPDATES:
return events
# ... rest of implementation2. Hardcoded Branch Name (Priority: Medium)The URL hardcodes Line 171: github_raw_url = "https://github.com/pirate/security-growler/raw/master/security-growler.30s.py"Consider making this a constant at the top of the file or using a more flexible approach (e.g., checking the 3. Potential Race Condition with Hash Comparison (Priority: Low)If the remote script is updated during the download, the hash comparison might detect a "new version" even when the user already has the latest. This is acceptable for the use case but worth noting. 🐛 Potential Bugs4. State Persistence Timing (Priority: Medium)The # Only update timestamp if no update was found
if local_hash == remote_hash:
state["last_update_check"] = datetime.now().isoformat()
else:
# Don't update timestamp so user gets reminded on next check
title = "UPDATE AVAILABLE"
body = "New version of Security Growler detected"
download_url = "https://github.com/pirate/security-growler/releases"
events.append(("alert", title, f"{body} - {download_url}"))This way, users get reminded on every run (every 30s as per xbar polling) until they update. 5. Script Path Resolution (Priority: Low)Using ⚡ Performance Considerations
🔒 Security Concerns6. No HTTPS Verification (Priority: High)While curl by default verifies certificates, it would be more secure to explicitly ensure this: result = subprocess.run(
["curl", "--max-time", "10", "--silent", "--location", "--fail", github_raw_url],
capture_output=True,
timeout=15
)Adding 7. URL Injection Not Possible ✅The GitHub URL is hardcoded, so there's no risk of URL injection attacks. 8. Hash Comparison Security ✅SHA256 is cryptographically secure for this use case. The implementation correctly uses secure hashing. 🧪 Test CoverageIssue: No tests exist for this feature (or the codebase in general based on the glob results). Recommendation: While the codebase doesn't have tests, consider manually testing:
📝 DocumentationThe PR description is excellent and the code is well-commented. Consider updating the README to document:
SummaryRequired Changes:
Recommended Changes:
Overall Assessment: This is a solid implementation that adds valuable functionality. With the required changes above, it will be ready to merge. Great work on handling edge cases gracefully! 🎉 Review generated with Claude Code |
Implements simple auto-update checking as requested in issue #21:
Closes #21
Generated with Claude Code