forked from indymedia/epicyon
Maximum size for rss/atom feeds
Prevents a hacked news source from implementing a denial of servicemain
parent
257a2d1e88
commit
c3dbec6181
|
@ -11951,7 +11951,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
|
||||||
tokensLookup[token] = nickname
|
tokensLookup[token] = nickname
|
||||||
|
|
||||||
|
|
||||||
def runDaemon(maxNewswirePostsPerSource: int,
|
def runDaemon(maxNewswireFeedSizeKb: int,
|
||||||
|
maxNewswirePostsPerSource: int,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
votingTimeMins: int,
|
votingTimeMins: int,
|
||||||
positiveVoting: bool,
|
positiveVoting: bool,
|
||||||
|
@ -12072,6 +12073,9 @@ def runDaemon(maxNewswirePostsPerSource: int,
|
||||||
# number of votes needed to remove a newswire item from the news timeline
|
# number of votes needed to remove a newswire item from the news timeline
|
||||||
# or if positive voting is anabled to add the item to the news timeline
|
# or if positive voting is anabled to add the item to the news timeline
|
||||||
httpd.newswireVotesThreshold = newswireVotesThreshold
|
httpd.newswireVotesThreshold = newswireVotesThreshold
|
||||||
|
# maximum overall size of an rss/atom feed read by the newswire daemon
|
||||||
|
# If the feed is too large then this is probably a DoS attempt
|
||||||
|
httpd.maxNewswireFeedSizeKb = maxNewswireFeedSizeKb
|
||||||
|
|
||||||
# For each newswire source (account or rss feed)
|
# For each newswire source (account or rss feed)
|
||||||
# this is the maximum number of posts to show for each.
|
# this is the maximum number of posts to show for each.
|
||||||
|
|
14
epicyon.py
14
epicyon.py
|
@ -116,6 +116,10 @@ parser.add_argument('--postsPerSource',
|
||||||
dest='maxNewswirePostsPerSource', type=int,
|
dest='maxNewswirePostsPerSource', type=int,
|
||||||
default=5,
|
default=5,
|
||||||
help='Maximum newswire posts per feed or account')
|
help='Maximum newswire posts per feed or account')
|
||||||
|
parser.add_argument('--maxFeedSize',
|
||||||
|
dest='maxNewswireFeedSizeKb', type=int,
|
||||||
|
default=2048,
|
||||||
|
help='Maximum newswire rss/atom feed size in K')
|
||||||
parser.add_argument('--postcache', dest='maxRecentPosts', type=int,
|
parser.add_argument('--postcache', dest='maxRecentPosts', type=int,
|
||||||
default=512,
|
default=512,
|
||||||
help='The maximum number of recent posts to store in RAM')
|
help='The maximum number of recent posts to store in RAM')
|
||||||
|
@ -1936,6 +1940,13 @@ if maxNewswirePostsPerSource:
|
||||||
if maxNewswirePostsPerSource.isdigit():
|
if maxNewswirePostsPerSource.isdigit():
|
||||||
args.maxNewswirePostsPerSource = maxNewswirePostsPerSource
|
args.maxNewswirePostsPerSource = maxNewswirePostsPerSource
|
||||||
|
|
||||||
|
# set the maximum size of a newswire rss/atom feed in Kilobytes
|
||||||
|
maxNewswireFeedSizeKb = \
|
||||||
|
getConfigParam(baseDir, 'maxNewswireFeedSizeKb')
|
||||||
|
if maxNewswireFeedSizeKb:
|
||||||
|
if maxNewswireFeedSizeKb.isdigit():
|
||||||
|
args.maxNewswireFeedSizeKb = maxNewswireFeedSizeKb
|
||||||
|
|
||||||
YTDomain = getConfigParam(baseDir, 'youtubedomain')
|
YTDomain = getConfigParam(baseDir, 'youtubedomain')
|
||||||
if YTDomain:
|
if YTDomain:
|
||||||
if '://' in YTDomain:
|
if '://' in YTDomain:
|
||||||
|
@ -1949,7 +1960,8 @@ if setTheme(baseDir, themeName, domain):
|
||||||
print('Theme set to ' + themeName)
|
print('Theme set to ' + themeName)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
runDaemon(args.maxNewswirePostsPerSource,
|
runDaemon(args.maxNewswireFeedSizeKb,
|
||||||
|
args.maxNewswirePostsPerSource,
|
||||||
args.dateonly,
|
args.dateonly,
|
||||||
args.votingtime,
|
args.votingtime,
|
||||||
args.positivevoting,
|
args.positivevoting,
|
||||||
|
|
|
@ -227,7 +227,8 @@ def runNewswireDaemon(baseDir: str, httpd,
|
||||||
try:
|
try:
|
||||||
newNewswire = \
|
newNewswire = \
|
||||||
getDictFromNewswire(httpd.session, baseDir,
|
getDictFromNewswire(httpd.session, baseDir,
|
||||||
httpd.maxNewswirePostsPerSource)
|
httpd.maxNewswirePostsPerSource,
|
||||||
|
httpd.maxNewswireFeedSizeKb)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('WARN: unable to update newswire ' + str(e))
|
print('WARN: unable to update newswire ' + str(e))
|
||||||
time.sleep(120)
|
time.sleep(120)
|
||||||
|
|
15
newswire.py
15
newswire.py
|
@ -196,7 +196,8 @@ def xmlStrToDict(xmlStr: str, moderated: bool,
|
||||||
|
|
||||||
|
|
||||||
def getRSS(session, url: str, moderated: bool,
|
def getRSS(session, url: str, moderated: bool,
|
||||||
maxPostsPerSource: int) -> {}:
|
maxPostsPerSource: int,
|
||||||
|
maxFeedSizeKb: int) -> {}:
|
||||||
"""Returns an RSS url as a dict
|
"""Returns an RSS url as a dict
|
||||||
"""
|
"""
|
||||||
if not isinstance(url, str):
|
if not isinstance(url, str):
|
||||||
|
@ -219,7 +220,11 @@ def getRSS(session, url: str, moderated: bool,
|
||||||
print('WARN: no session specified for getRSS')
|
print('WARN: no session specified for getRSS')
|
||||||
try:
|
try:
|
||||||
result = session.get(url, headers=sessionHeaders, params=sessionParams)
|
result = session.get(url, headers=sessionHeaders, params=sessionParams)
|
||||||
return xmlStrToDict(result.text, moderated, maxPostsPerSource)
|
if result:
|
||||||
|
if int(len(result) / 1024) < maxFeedSizeKb:
|
||||||
|
return xmlStrToDict(result.text, moderated, maxPostsPerSource)
|
||||||
|
else:
|
||||||
|
print('WARN: feed is too large: ' + url)
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
print('ERROR: getRSS failed\nurl: ' + str(url) + '\n' +
|
print('ERROR: getRSS failed\nurl: ' + str(url) + '\n' +
|
||||||
'headers: ' + str(sessionHeaders) + '\n' +
|
'headers: ' + str(sessionHeaders) + '\n' +
|
||||||
|
@ -396,7 +401,8 @@ def addBlogsToNewswire(baseDir: str, newswire: {},
|
||||||
os.remove(newswireModerationFilename)
|
os.remove(newswireModerationFilename)
|
||||||
|
|
||||||
|
|
||||||
def getDictFromNewswire(session, baseDir: str, maxPostsPerSource: int) -> {}:
|
def getDictFromNewswire(session, baseDir: str,
|
||||||
|
maxPostsPerSource: int, maxFeedSizeKb: int) -> {}:
|
||||||
"""Gets rss feeds as a dictionary from newswire file
|
"""Gets rss feeds as a dictionary from newswire file
|
||||||
"""
|
"""
|
||||||
subscriptionsFilename = baseDir + '/accounts/newswire.txt'
|
subscriptionsFilename = baseDir + '/accounts/newswire.txt'
|
||||||
|
@ -427,7 +433,8 @@ def getDictFromNewswire(session, baseDir: str, maxPostsPerSource: int) -> {}:
|
||||||
moderated = True
|
moderated = True
|
||||||
url = url.replace('*', '').strip()
|
url = url.replace('*', '').strip()
|
||||||
|
|
||||||
itemsList = getRSS(session, url, moderated, maxPostsPerSource)
|
itemsList = getRSS(session, url, moderated,
|
||||||
|
maxPostsPerSource, maxFeedSizeKb)
|
||||||
for dateStr, item in itemsList.items():
|
for dateStr, item in itemsList.items():
|
||||||
result[dateStr] = item
|
result[dateStr] = item
|
||||||
|
|
||||||
|
|
6
tests.py
6
tests.py
|
@ -288,7 +288,7 @@ def createServerAlice(path: str, domain: str, port: int,
|
||||||
onionDomain = None
|
onionDomain = None
|
||||||
i2pDomain = None
|
i2pDomain = None
|
||||||
print('Server running: Alice')
|
print('Server running: Alice')
|
||||||
runDaemon(5, False, 0, False, 1, False, False, False,
|
runDaemon(1024, 5, False, 0, False, 1, False, False, False,
|
||||||
5, True, True, 'en', __version__,
|
5, True, True, 'en', __version__,
|
||||||
"instanceId", False, path, domain,
|
"instanceId", False, path, domain,
|
||||||
onionDomain, i2pDomain, None, port, port,
|
onionDomain, i2pDomain, None, port, port,
|
||||||
|
@ -351,7 +351,7 @@ def createServerBob(path: str, domain: str, port: int,
|
||||||
onionDomain = None
|
onionDomain = None
|
||||||
i2pDomain = None
|
i2pDomain = None
|
||||||
print('Server running: Bob')
|
print('Server running: Bob')
|
||||||
runDaemon(5, False, 0, False, 1, False, False, False,
|
runDaemon(1024, 5, False, 0, False, 1, False, False, False,
|
||||||
5, True, True, 'en', __version__,
|
5, True, True, 'en', __version__,
|
||||||
"instanceId", False, path, domain,
|
"instanceId", False, path, domain,
|
||||||
onionDomain, i2pDomain, None, port, port,
|
onionDomain, i2pDomain, None, port, port,
|
||||||
|
@ -388,7 +388,7 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
|
||||||
onionDomain = None
|
onionDomain = None
|
||||||
i2pDomain = None
|
i2pDomain = None
|
||||||
print('Server running: Eve')
|
print('Server running: Eve')
|
||||||
runDaemon(5, False, 0, False, 1, False, False, False,
|
runDaemon(1024, 5, False, 0, False, 1, False, False, False,
|
||||||
5, True, True, 'en', __version__,
|
5, True, True, 'en', __version__,
|
||||||
"instanceId", False, path, domain,
|
"instanceId", False, path, domain,
|
||||||
onionDomain, i2pDomain, None, port, port,
|
onionDomain, i2pDomain, None, port, port,
|
||||||
|
|
Loading…
Reference in New Issue