Changeset 10788
- Timestamp:
- Aug 26, 2011, 12:29:32 PM (12 years ago)
- Location:
- branches/0.12-stable/trac/util
- Files:
-
- 1 added
- 2 edited
-
html.py (modified) (3 diffs)
-
tests/__init__.py (modified) (2 diffs)
-
tests/html.py (added)
Legend:
- Unmodified
- Added
- Removed
-
branches/0.12-stable/trac/util/html.py
r10753 r10788 26 26 class TracHTMLSanitizer(HTMLSanitizer): 27 27 28 UNSAFE_CSS = set([ 29 'position', 30 # IE <http://trac.edgewall.org/ticket/10114> 31 'behavior', 32 # Opera <http://trac.edgewall.org/ticket/10115> 33 '-o-link', '-o-link-source', 28 SAFE_CSS = frozenset([ 29 # CSS 3 properties <http://www.w3.org/TR/CSS/#properties> 30 'background', 'background-attachment', 'background-color', 31 'background-image', 'background-position', 'background-repeat', 32 'border', 'border-bottom', 'border-bottom-color', 33 'border-bottom-style', 'border-bottom-width', 'border-collapse', 34 'border-color', 'border-left', 'border-left-color', 35 'border-left-style', 'border-left-width', 'border-right', 36 'border-right-color', 'border-right-style', 'border-right-width', 37 'border-spacing', 'border-style', 'border-top', 'border-top-color', 38 'border-top-style', 'border-top-width', 'border-width', 'bottom', 39 'caption-side', 'clear', 'clip', 'color', 'content', 40 'counter-increment', 'counter-reset', 'cursor', 'direction', 'display', 41 'empty-cells', 'float', 'font', 'font-family', 'font-size', 42 'font-style', 'font-variant', 'font-weight', 'height', 'left', 43 'letter-spacing', 'line-height', 'list-style', 'list-style-image', 44 'list-style-position', 'list-style-type', 'margin', 'margin-bottom', 45 'margin-left', 'margin-right', 'margin-top', 'max-height', 'max-width', 46 'min-height', 'min-width', 'opacity', 'orphans', 'outline', 47 'outline-color', 'outline-style', 'outline-width', 'overflow', 48 'padding', 'padding-bottom', 'padding-left', 'padding-right', 49 'padding-top', 'page-break-after', 'page-break-before', 50 'page-break-inside', 'position', 'quotes', 'right', 'table-layout', 51 'text-align', 'text-decoration', 'text-indent', 'text-transform', 52 'top', 'unicode-bidi', 'vertical-align', 'visibility', 'white-space', 53 'widows', 'width', 'word-spacing', 'z-index', 34 54 ]) 35 55 36 def __init__(self, safe_schemes=HTMLSanitizer.SAFE_SCHEMES): 56 def __init__(self, safe_schemes=HTMLSanitizer.SAFE_SCHEMES, 57 safe_css=SAFE_CSS): 37 58 safe_attrs = HTMLSanitizer.SAFE_ATTRS | frozenset(['style']) 38 59 safe_schemes = frozenset(safe_schemes) 39 60 super(TracHTMLSanitizer, self).__init__(safe_attrs=safe_attrs, 40 61 safe_schemes=safe_schemes) 62 self.safe_css = frozenset(safe_css) 63 64 # IE6 <http://heideri.ch/jso/#80> 65 _EXPRESSION_SEARCH = re.compile(u""" 66 [eE 67 \uFF25 # FULLWIDTH LATIN CAPITAL LETTER E 68 \uFF45 # FULLWIDTH LATIN SMALL LETTER E 69 ] 70 [xX 71 \uFF38 # FULLWIDTH LATIN CAPITAL LETTER X 72 \uFF58 # FULLWIDTH LATIN SMALL LETTER X 73 ] 74 [pP 75 \uFF30 # FULLWIDTH LATIN CAPITAL LETTER P 76 \uFF50 # FULLWIDTH LATIN SMALL LETTER P 77 ] 78 [rR 79 \u0280 # LATIN LETTER SMALL CAPITAL R 80 \uFF32 # FULLWIDTH LATIN CAPITAL LETTER R 81 \uFF52 # FULLWIDTH LATIN SMALL LETTER R 82 ] 83 [eE 84 \uFF25 # FULLWIDTH LATIN CAPITAL LETTER E 85 \uFF45 # FULLWIDTH LATIN SMALL LETTER E 86 ] 87 [sS 88 \uFF33 # FULLWIDTH LATIN CAPITAL LETTER S 89 \uFF53 # FULLWIDTH LATIN SMALL LETTER S 90 ]{2} 91 [iI 92 \u026A # LATIN LETTER SMALL CAPITAL I 93 \uFF29 # FULLWIDTH LATIN CAPITAL LETTER I 94 \uFF49 # FULLWIDTH LATIN SMALL LETTER I 95 ] 96 [oO 97 \uFF2F # FULLWIDTH LATIN CAPITAL LETTER O 98 \uFF4F # FULLWIDTH LATIN SMALL LETTER O 99 ] 100 [nN 101 \u0274 # LATIN LETTER SMALL CAPITAL N 102 \uFF2E # FULLWIDTH LATIN CAPITAL LETTER N 103 \uFF4E # FULLWIDTH LATIN SMALL LETTER N 104 ] 105 """, re.VERBOSE).search 106 107 # IE6 <http://openmya.hacker.jp/hasegawa/security/expression.txt> 108 # 7) Particular bit of Unicode characters 109 _URL_FINDITER = re.compile( 110 u'[Uu][Rr\u0280][Ll\u029F]\s*\(([^)]+)').finditer 41 111 42 112 def sanitize_css(self, text): … … 54 124 continue 55 125 is_evil = False 56 if 'expression' in decl:126 if self._EXPRESSION_SEARCH(decl): 57 127 is_evil = True 58 for match in re.finditer(r'url\s*\(([^)]+)',decl):128 for match in self._URL_FINDITER(decl): 59 129 if not self.is_safe_uri(match.group(1)): 60 130 is_evil = True … … 87 157 considered safe for inclusion in the output. 88 158 """ 89 if prop in self.UNSAFE_CSS:159 if prop not in self.safe_css: 90 160 return False 161 # Position can be used for phishing, 'static' excepted 162 if prop == 'position': 163 return value.lower() == 'static' 91 164 # Negative margins can be used for phishing 92 elif prop.startswith('margin') and '-' in value:93 return False165 if prop.startswith('margin'): 166 return '-' not in value 94 167 return True 168 169 _NORMALIZE_NEWLINES = re.compile(r'\r\n').sub 170 _UNICODE_ESCAPE = re.compile( 171 r"""\\([0-9a-fA-F]{1,6})\s?|\\([^\r\n\f0-9a-fA-F'"{};:()#*])""", 172 re.UNICODE).sub 173 174 def _replace_unicode_escapes(self, text): 175 def _repl(match): 176 t = match.group(1) 177 if t: 178 return unichr(int(t, 16)) 179 t = match.group(2) 180 if t == '\\': 181 return r'\\' 182 else: 183 return t 184 return self._UNICODE_ESCAPE(_repl, 185 self._NORMALIZE_NEWLINES('\n', text)) 95 186 96 187 -
branches/0.12-stable/trac/util/tests/__init__.py
r10115 r10788 19 19 20 20 from trac import util 21 from trac.util.tests import concurrency, datefmt, presentation, text 21 from trac.util.tests import concurrency, datefmt, presentation, text, html 22 22 23 23 … … 146 146 suite.addTest(doctest.DocTestSuite(util)) 147 147 suite.addTest(text.suite()) 148 suite.addTest(html.suite()) 148 149 return suite 149 150
Note:
See TracChangeset
for help on using the changeset viewer.
