mirror of https://gitlab.com/bashrc2/epicyon
Don't allow svg files containing scripts
parent
cadb306b66
commit
192eeaff27
|
@ -11,6 +11,7 @@ import os
|
||||||
import email.parser
|
import email.parser
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
|
from utils import dangerousSVG
|
||||||
from utils import removeDomainPort
|
from utils import removeDomainPort
|
||||||
from utils import isValidLanguage
|
from utils import isValidLanguage
|
||||||
from utils import getImageExtensions
|
from utils import getImageExtensions
|
||||||
|
@ -1017,6 +1018,13 @@ def saveMediaInFormPOST(mediaBytes, debug: bool,
|
||||||
except BaseException:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# don't allow scripts within svg files
|
||||||
|
if detectedExtension == 'svg':
|
||||||
|
svgStr = mediaBytes[startPos:]
|
||||||
|
svgStr = svgStr.decode()
|
||||||
|
if dangerousSVG(svgStr, False):
|
||||||
|
return None, None
|
||||||
|
|
||||||
with open(filename, 'wb') as fp:
|
with open(filename, 'wb') as fp:
|
||||||
fp.write(mediaBytes[startPos:])
|
fp.write(mediaBytes[startPos:])
|
||||||
|
|
||||||
|
|
31
tests.py
31
tests.py
|
@ -70,6 +70,7 @@ from utils import getStatusNumber
|
||||||
from utils import getFollowersOfPerson
|
from utils import getFollowersOfPerson
|
||||||
from utils import removeHtml
|
from utils import removeHtml
|
||||||
from utils import dangerousMarkup
|
from utils import dangerousMarkup
|
||||||
|
from utils import dangerousSVG
|
||||||
from utils import acctDir
|
from utils import acctDir
|
||||||
from pgp import extractPGPPublicKey
|
from pgp import extractPGPPublicKey
|
||||||
from pgp import pgpPublicKeyUpload
|
from pgp import pgpPublicKeyUpload
|
||||||
|
@ -3412,6 +3413,35 @@ def _testDangerousCSS():
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def _testDangerousSVG() -> None:
|
||||||
|
print('testDangerousSVG')
|
||||||
|
svgContent = \
|
||||||
|
' <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">' + \
|
||||||
|
' <circle cx="5" cy="5" r="4" />' + \
|
||||||
|
'</svg>'
|
||||||
|
assert not dangerousSVG(svgContent, False)
|
||||||
|
svgContent = \
|
||||||
|
' <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">' + \
|
||||||
|
' <script>' + \
|
||||||
|
' // <![CDATA[' + \
|
||||||
|
" window.addEventListener('DOMContentLoaded', () => {" + \
|
||||||
|
' function attackScript () {' + \
|
||||||
|
' return `#${OWO}`' + \
|
||||||
|
' }' + \
|
||||||
|
'' + \
|
||||||
|
" document.querySelector('circle')." + \
|
||||||
|
"addEventListener('click', (e) => {" + \
|
||||||
|
' e.target.style.fill = attackScript()' + \
|
||||||
|
' })' + \
|
||||||
|
' })' + \
|
||||||
|
' // ]]>' + \
|
||||||
|
' </script>' + \
|
||||||
|
'' + \
|
||||||
|
' <circle cx="5" cy="5" r="4" />' + \
|
||||||
|
'</svg>'
|
||||||
|
assert dangerousSVG(svgContent, False)
|
||||||
|
|
||||||
|
|
||||||
def _testDangerousMarkup():
|
def _testDangerousMarkup():
|
||||||
print('testDangerousMarkup')
|
print('testDangerousMarkup')
|
||||||
allowLocalNetworkAccess = False
|
allowLocalNetworkAccess = False
|
||||||
|
@ -5516,6 +5546,7 @@ def runAllTests():
|
||||||
_translateOntology()
|
_translateOntology()
|
||||||
_testGetPriceFromString()
|
_testGetPriceFromString()
|
||||||
_testFunctions()
|
_testFunctions()
|
||||||
|
_testDangerousSVG()
|
||||||
_testCanReplyTo()
|
_testCanReplyTo()
|
||||||
_testDateConversions()
|
_testDateConversions()
|
||||||
_testAuthorizeSharedItems()
|
_testAuthorizeSharedItems()
|
||||||
|
|
37
utils.py
37
utils.py
|
@ -821,16 +821,10 @@ def isLocalNetworkAddress(ipAddress: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def dangerousMarkup(content: str, allowLocalNetworkAccess: bool) -> bool:
|
def _isDangerousString(content: str, allowLocalNetworkAccess: bool,
|
||||||
"""Returns true if the given content contains dangerous html markup
|
separators: [], invalidStrings: []) -> bool:
|
||||||
|
"""Returns true if the given string is dangerous
|
||||||
"""
|
"""
|
||||||
separators = (['<', '>'], ['<', '>'])
|
|
||||||
invalidStrings = (
|
|
||||||
'script', 'noscript',
|
|
||||||
'canvas', 'style', 'abbr',
|
|
||||||
'frame', 'iframe', 'html', 'body',
|
|
||||||
'hr', 'allow-popups', 'allow-scripts'
|
|
||||||
)
|
|
||||||
for separatorStyle in separators:
|
for separatorStyle in separators:
|
||||||
startChar = separatorStyle[0]
|
startChar = separatorStyle[0]
|
||||||
endChar = separatorStyle[1]
|
endChar = separatorStyle[1]
|
||||||
|
@ -860,6 +854,31 @@ def dangerousMarkup(content: str, allowLocalNetworkAccess: bool) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def dangerousMarkup(content: str, allowLocalNetworkAccess: bool) -> bool:
|
||||||
|
"""Returns true if the given content contains dangerous html markup
|
||||||
|
"""
|
||||||
|
separators = [['<', '>'], ['<', '>']]
|
||||||
|
invalidStrings = [
|
||||||
|
'script', 'noscript',
|
||||||
|
'canvas', 'style', 'abbr',
|
||||||
|
'frame', 'iframe', 'html', 'body',
|
||||||
|
'hr', 'allow-popups', 'allow-scripts'
|
||||||
|
]
|
||||||
|
return _isDangerousString(content, allowLocalNetworkAccess,
|
||||||
|
separators, invalidStrings)
|
||||||
|
|
||||||
|
|
||||||
|
def dangerousSVG(content: str, allowLocalNetworkAccess: bool) -> bool:
|
||||||
|
"""Returns true if the given svg file content contains dangerous scripts
|
||||||
|
"""
|
||||||
|
separators = [['<', '>'], ['<', '>']]
|
||||||
|
invalidStrings = [
|
||||||
|
'script'
|
||||||
|
]
|
||||||
|
return _isDangerousString(content, allowLocalNetworkAccess,
|
||||||
|
separators, invalidStrings)
|
||||||
|
|
||||||
|
|
||||||
def getDisplayName(baseDir: str, actor: str, personCache: {}) -> str:
|
def getDisplayName(baseDir: str, actor: str, personCache: {}) -> str:
|
||||||
"""Returns the display name for the given actor
|
"""Returns the display name for the given actor
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue