From 8bbd9b617301e3b083c9c050b9453c9dadfe8d2d Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 31 Jan 2021 11:05:17 +0000 Subject: [PATCH] Check for dangerous markup in display name and clearly indicate adversaries --- content.py | 33 +-------------------------------- daemon.py | 2 +- inbox.py | 2 +- newsdaemon.py | 2 +- outbox.py | 2 +- posts.py | 6 ++++-- tests.py | 2 +- utils.py | 42 +++++++++++++++++++++++++++++++++++++++--- 8 files changed, 49 insertions(+), 42 deletions(-) diff --git a/content.py b/content.py index 28a2ac531..4f20267e8 100644 --- a/content.py +++ b/content.py @@ -14,6 +14,7 @@ from utils import getImageExtensions from utils import loadJson from utils import fileLastModified from utils import getLinkPrefixes +from utils import dangerousMarkup from petnames import getPetName @@ -154,38 +155,6 @@ def htmlReplaceQuoteMarks(content: str) -> str: return newContent -def dangerousMarkup(content: str, allowLocalNetworkAccess: bool) -> bool: - """Returns true if the given content contains dangerous html markup - """ - if '<' not in content: - return False - if '>' not in content: - return False - contentSections = content.split('<') - invalidPartials = () - if not allowLocalNetworkAccess: - invalidPartials = ('localhost', '127.0.', '192.168', '10.0.') - invalidStrings = ('script', 'canvas', 'style', 'abbr', - 'frame', 'iframe', 'html', 'body', - 'hr', 'allow-popups', 'allow-scripts') - for markup in contentSections: - if '>' not in markup: - continue - markup = markup.split('>')[0].strip() - for partialMatch in invalidPartials: - if partialMatch in markup: - return True - if ' ' not in markup: - for badStr in invalidStrings: - if badStr in markup: - return True - else: - for badStr in invalidStrings: - if badStr + ' ' in markup: - return True - return False - - def dangerousCSS(filename: str, allowLocalNetworkAccess: bool) -> bool: """Returns true is the css file contains code which can create security problems diff --git a/daemon.py b/daemon.py index 03b84ca40..6994b8515 100644 --- a/daemon.py +++ b/daemon.py @@ -217,10 +217,10 @@ from utils import urlPermitted from utils import loadJson from utils import saveJson from utils import isSuspended +from utils import dangerousMarkup from manualapprove import manualDenyFollowRequest from manualapprove import manualApproveFollowRequest from announce import createAnnounce -from content import dangerousMarkup from content import replaceEmojiFromTags from content import addHtmlTags from content import extractMediaInFormPOST diff --git a/inbox.py b/inbox.py index 1dbf18af1..c213e0d22 100644 --- a/inbox.py +++ b/inbox.py @@ -54,6 +54,7 @@ from blocking import isBlockedDomain from filters import isFiltered from utils import updateAnnounceCollection from utils import undoAnnounceCollectionEntry +from utils import dangerousMarkup from httpsig import messageContentDigest from posts import validContentWarning from posts import downloadAnnounce @@ -69,7 +70,6 @@ from media import replaceYouTube from git import isGitPatch from git import receiveGitPatch from followingCalendar import receivingCalendarEvents -from content import dangerousMarkup from happening import saveEventPost from delete import removeOldHashtags from follow import isFollowingActor diff --git a/newsdaemon.py b/newsdaemon.py index 0a6a8f5cc..84f2f4bc4 100644 --- a/newsdaemon.py +++ b/newsdaemon.py @@ -23,7 +23,6 @@ from newswire import getDictFromNewswire # from posts import sendSignedJson from posts import createNewsPost from posts import archivePostsForPerson -from content import dangerousMarkup from content import validHashTag from utils import removeHtml from utils import getFullDomain @@ -31,6 +30,7 @@ from utils import loadJson from utils import saveJson from utils import getStatusNumber from utils import clearFromPostCaches +from utils import dangerousMarkup from inbox import storeHashTags from session import createSession diff --git a/outbox.py b/outbox.py index ce0bf15d9..e50000386 100644 --- a/outbox.py +++ b/outbox.py @@ -17,6 +17,7 @@ from posts import sendToNamedAddresses from utils import getFullDomain from utils import removeIdEnding from utils import getDomainFromActor +from utils import dangerousMarkup from blocking import isBlockedDomain from blocking import outboxBlock from blocking import outboxUndoBlock @@ -36,7 +37,6 @@ from bookmarks import outboxUndoBookmark from delete import outboxDelete from shares import outboxShareUpload from shares import outboxUndoShareUpload -from content import dangerousMarkup def postMessageToOutbox(messageJson: {}, postToNickname: str, diff --git a/posts.py b/posts.py index 5c976a20f..eeaecbbe4 100644 --- a/posts.py +++ b/posts.py @@ -55,9 +55,9 @@ from utils import locateNewsVotes from utils import locateNewsArrival from utils import votesOnNewswireItem from utils import removeHtml +from utils import dangerousMarkup from media import attachMedia from media import replaceYouTube -from content import dangerousMarkup from content import tagExists from content import removeLongWords from content import addHtmlTags @@ -292,7 +292,9 @@ def getPersonBox(baseDir: str, session, wfRequest: {}, avatarUrl = personJson['icon']['url'] displayName = None if personJson.get('name'): - displayName = removeHtml(personJson['name']) + displayName = personJson['name'] + if dangerousMarkup(personJson['name'], False): + displayName = '*ADVERSARY*' # have they moved? if personJson.get('movedTo'): displayName += ' ⌂' diff --git a/tests.py b/tests.py index f2ef8b22d..3ff5eb714 100644 --- a/tests.py +++ b/tests.py @@ -49,6 +49,7 @@ from utils import saveJson from utils import getStatusNumber from utils import getFollowersOfPerson from utils import removeHtml +from utils import dangerousMarkup from follow import followerOfPerson from follow import unfollowAccount from follow import unfollowerOfAccount @@ -77,7 +78,6 @@ from inbox import validInboxFilenames from categories import guessHashtagCategory from content import htmlReplaceEmailQuote from content import htmlReplaceQuoteMarks -from content import dangerousMarkup from content import dangerousCSS from content import addWebLinks from content import replaceEmojiFromTags diff --git a/utils.py b/utils.py index 76e02f8ac..df27780b3 100644 --- a/utils.py +++ b/utils.py @@ -554,6 +554,38 @@ def urlPermitted(url: str, federationList: []): return False +def dangerousMarkup(content: str, allowLocalNetworkAccess: bool) -> bool: + """Returns true if the given content contains dangerous html markup + """ + if '<' not in content: + return False + if '>' not in content: + return False + contentSections = content.split('<') + invalidPartials = () + if not allowLocalNetworkAccess: + invalidPartials = ('localhost', '127.0.', '192.168', '10.0.') + invalidStrings = ('script', 'canvas', 'style', 'abbr', + 'frame', 'iframe', 'html', 'body', + 'hr', 'allow-popups', 'allow-scripts') + for markup in contentSections: + if '>' not in markup: + continue + markup = markup.split('>')[0].strip() + for partialMatch in invalidPartials: + if partialMatch in markup: + return True + if ' ' not in markup: + for badStr in invalidStrings: + if badStr in markup: + return True + else: + for badStr in invalidStrings: + if badStr + ' ' in markup: + return True + return False + + def getDisplayName(baseDir: str, actor: str, personCache: {}) -> str: """Returns the display name for the given actor """ @@ -561,9 +593,10 @@ def getDisplayName(baseDir: str, actor: str, personCache: {}) -> str: actor = actor.split('/statuses/')[0] if not personCache.get(actor): return None + nameFound = None if personCache[actor].get('actor'): if personCache[actor]['actor'].get('name'): - return personCache[actor]['actor']['name'] + nameFound = personCache[actor]['actor']['name'] else: # Try to obtain from the cached actors cachedActorFilename = \ @@ -572,8 +605,11 @@ def getDisplayName(baseDir: str, actor: str, personCache: {}) -> str: actorJson = loadJson(cachedActorFilename, 1) if actorJson: if actorJson.get('name'): - return(actorJson['name']) - return None + nameFound = actorJson['name'] + if nameFound: + if dangerousMarkup(nameFound, False): + nameFound = "*ADVERSARY*" + return nameFound def getNicknameFromActor(actor: str) -> str: