fix: security hardening — XSS, push spoofing, metadata leaks, deletion bugs#98
Merged
fix: security hardening — XSS, push spoofing, metadata leaks, deletion bugs#98
Conversation
- High: fix stored XSS in linkifyText() — HTML entities in URLs could break out of href attribute; now percent-encode quotes in href context - Medium: restrict /internal/push to loopback only (127.0.0.1, ::1); private LAN ranges are spoofable behind reverse proxies - Medium: filter /api/stats per_chat_message_counts and /api/folders chat_count by user's allowed_chat_ids to prevent metadata leaks - Medium: use delete_message_by_id_any_chat() for deletions without chat_id to avoid cross-chat message ID collisions - Low: fix _reset_reactions_sequence() using nonexistent db_type property; use _is_sqlite instead
|
🐳 Dev images published!
The dev/test instance will pick up these changes automatically (Portainer GitOps). To test locally: docker pull drumsergio/telegram-archive:dev
docker pull drumsergio/telegram-archive-viewer:dev |
- XSS: handle raw " and ' in URLs (escapeHtml doesn't encode quotes) - Stats: fix JSON string keys vs int user_chat_ids type mismatch - Stats: remove media_files/total_size_mb for restricted users - Deletion: resolve chat_id from DB first, apply rate limiter, notify viewer - Deletion: skip ambiguous message IDs found in multiple chats - Folders: filter out folders with 0 visible chats for restricted users - Push endpoint: accept private IPs for split-container SQLite mode
|
🐳 Dev images published!
The dev/test instance will pick up these changes automatically (Portainer GitOps). To test locally: docker pull drumsergio/telegram-archive:dev
docker pull drumsergio/telegram-archive-viewer:dev |
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.
Summary
Addresses 5 findings from a security hardening review.
High: Stored XSS via
linkifyText()escapeHtml()converts"to", but when the regex inserts the URL intohref="$1", the browser decodes"back to", allowing attribute breakout. Fix: percent-encode%22,%27,%3C,%3Ein the href context while keeping HTML-escaped display text.Medium:
/internal/pushIP spoofingWas accepting all RFC1918 ranges (
172.*,10.*,192.168.*). Behind Docker/LAN proxies, external requests arrive from these IPs. Now restricted to loopback only (127.0.0.1,::1) — SQLite push is always same-container.Medium: Stats/folders metadata leak to restricted viewers
/api/statsreturnedper_chat_message_countsfor ALL chats, and/api/foldersreturned unfiltered chat counts. Now both filter byget_user_chat_ids().Medium: Cross-chat message deletion
When Telegram sends a delete event without
chat_id, the listener resolved it viaget_chat_id_for_message()which returns the first arbitrary match. Now usesdelete_message_by_id_any_chat()which correctly handles all matching chats.Low: Broken reactions sequence reset
_reset_reactions_sequence()referencedself.db_manager.db_typewhich doesn't exist. Fixed to useself.db_manager._is_sqlite.Test plan