@@ -65,31 +65,56 @@ def sanitize_after_whitelisted_command(line, command):
65
65
# This means we should only return the part up to the whitelisted command
66
66
return line [:command_end_index + len (sanitized_rest )].strip ()
67
67
68
+ if not (PackageManager .check_package_installed ("defusedxml" )):
69
+ PackageManager .install_or_update ("defusedxml" )
68
70
69
- def sanitize_svg (svg_content ):
70
- try :
71
- parser = ET .XMLParser (remove_comments = True , remove_pis = True )
72
- tree = ET .fromstring (svg_content , parser = parser )
71
+ import defusedxml .ElementTree as ET
73
72
74
- # Remove any script elements
75
- for script in tree .xpath ('//svg:script' , namespaces = {'svg' : 'http://www.w3.org/2000/svg' }):
76
- parent = script .getparent ()
77
- if parent is not None :
78
- parent .remove (script )
73
+ from defusedxml import ElementTree as ET
74
+ from io import StringIO
79
75
80
- # Remove any 'on*' event attributes
81
- for element in tree .xpath ('//*[@*[starts-with(name(), "on")]]' ):
76
+ def sanitize_svg (svg_content ):
77
+ try :
78
+ # Use defusedxml's parse function with a StringIO object
79
+ tree = ET .parse (StringIO (svg_content ))
80
+ root = tree .getroot ()
81
+
82
+ # Define a list of allowed elements
83
+ allowed_elements = {
84
+ 'svg' , 'g' , 'path' , 'circle' , 'rect' , 'line' , 'polyline' , 'polygon' ,
85
+ 'text' , 'tspan' , 'defs' , 'filter' , 'feGaussianBlur' , 'feMerge' ,
86
+ 'feMergeNode' , 'linearGradient' , 'radialGradient' , 'stop'
87
+ }
88
+
89
+ # Define a list of allowed attributes
90
+ allowed_attributes = {
91
+ 'id' , 'class' , 'style' , 'fill' , 'stroke' , 'stroke-width' , 'cx' , 'cy' ,
92
+ 'r' , 'x' , 'y' , 'width' , 'height' , 'd' , 'transform' , 'viewBox' ,
93
+ 'xmlns' , 'xmlns:xlink' , 'version' , 'stdDeviation' , 'result' , 'in' ,
94
+ 'x1' , 'y1' , 'x2' , 'y2' , 'offset' , 'stop-color' , 'stop-opacity'
95
+ }
96
+
97
+ # Remove any disallowed elements
98
+ for element in root .iter ():
99
+ if element .tag .split ('}' )[- 1 ] not in allowed_elements :
100
+ parent = element .getparent ()
101
+ if parent is not None :
102
+ parent .remove (element )
103
+
104
+ # Remove any disallowed attributes
105
+ for element in root .iter ():
82
106
for attr in list (element .attrib ):
83
- if attr . startswith ( 'on' ) :
107
+ if attr not in allowed_attributes :
84
108
del element .attrib [attr ]
85
109
86
110
# Convert the tree back to an SVG string
87
- sanitized_svg = ET .tostring (tree , encoding = 'unicode' , method = 'xml' )
111
+ sanitized_svg = ET .tostring (root , encoding = 'unicode' , method = 'xml' )
88
112
return sanitized_svg
89
- except ET .XMLSyntaxError as e :
113
+ except ET .ParseError as e :
90
114
raise ValueError ("Invalid SVG content" ) from e
91
115
92
116
117
+
93
118
def sanitize_shell_code (code , whitelist = None ):
94
119
"""
95
120
Securely sanitizes a block of code by allowing commands from a provided whitelist,
0 commit comments