From 3fa12b73ae678458d06bac64fbf4778e6e225c14 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 2 Feb 2017 19:49:34 +0100 Subject: [PATCH] Moved to whitelist sanitizer. --- config/initializers/html_sanitizer.rb | 48 ++++++++++++++ lib/html_sanitizer.rb | 92 ++++++++++++++++++++------- test/unit/email_process_test.rb | 4 +- test/unit/html_sanitizer_test.rb | 74 +++++++++++++++++++++ test/unit/ticket_xss_test.rb | 15 ++--- 5 files changed, 199 insertions(+), 34 deletions(-) create mode 100644 config/initializers/html_sanitizer.rb create mode 100644 test/unit/html_sanitizer_test.rb diff --git a/config/initializers/html_sanitizer.rb b/config/initializers/html_sanitizer.rb new file mode 100644 index 000000000..c94403070 --- /dev/null +++ b/config/initializers/html_sanitizer.rb @@ -0,0 +1,48 @@ + +# content of this tags will also be removed +Rails.application.config.html_sanitizer_tags_remove_content = %w( + style +) + +# only this tags are allowed +Rails.application.config.html_sanitizer_tags_whitelist = %w( + a abbr acronym address area article aside audio + b bdi bdo big blockquote br + canvas caption center cite code col colgroup command + datalist dd del details dfn dir div dl dt em + figcaption figure footer h1 h2 h3 h4 h5 h6 header hr + i img ins kbd label legend li map mark menu meter nav + ol output optgroup option p pre q + s samp section small span strike strong sub summary sup + text table tbody td tfoot th thead time tr tt u ul var video +) + +# attributes allowed for tags +Rails.application.config.html_sanitizer_attributes_whitelist = { + :all => %w(class dir lang style title translate data-signature data-signature-id), + 'a' => %w(href hreflang name rel), + 'abbr' => %w(title), + 'blockquote' => %w(cite), + 'col' => %w(span width), + 'colgroup' => %w(span width), + 'data' => %w(value), + 'del' => %w(cite datetime), + 'dfn' => %w(title), + 'img' => %w(align alt border height src srcset width), + 'ins' => %w(cite datetime), + 'li' => %w(value), + 'ol' => %w(reversed start type), + 'table' => %w(align bgcolor border cellpadding cellspacing frame rules sortable summary width), + 'td' => %w(abbr align axis colspan headers rowspan valign width), + 'th' => %w(abbr align axis colspan headers rowspan scope sorted valign width), + 'ul' => %w(type), + 'q' => %w(cite), + 'time' => %w(datetime pubdate), +} + +# only this css properties are allowed +Rails.application.config.html_sanitizer_css_properties_whitelist = %w( + width height + max-width min-width + max-height min-height +) diff --git a/lib/html_sanitizer.rb b/lib/html_sanitizer.rb index 91e4f1be0..73b420632 100644 --- a/lib/html_sanitizer.rb +++ b/lib/html_sanitizer.rb @@ -1,48 +1,92 @@ class HtmlSanitizer def self.strict(string) - remove = %w(style body head) - strip = ['script'] + + # config + tags_remove_content = Rails.configuration.html_sanitizer_tags_remove_content + tags_whitelist = Rails.configuration.html_sanitizer_tags_whitelist + attributes_whitelist = Rails.configuration.html_sanitizer_attributes_whitelist + css_properties_whitelist = Rails.configuration.html_sanitizer_css_properties_whitelist scrubber = Loofah::Scrubber.new do |node| - # strip tags - if strip.include?(node.name) - node.before node.children + # remove tags with subtree + if tags_remove_content.include?(node.name) node.remove end - # remove tags - if remove.include?(node.name) - node.remove + # replace tags, keep subtree + if !tags_whitelist.include?(node.name) + traversal(node, scrubber) end # prepare src attribute if node['src'] - if node['src'].downcase.start_with?('http', 'ftp') - node.before node.children - node.remove + src = cleanup(node['src']) + if src =~ /(javascript|livescript|vbscript):/i || src.start_with?('http', 'ftp', '//') + traversal(node, scrubber) end end + # clean style / only use allowed style properties + if node['style'] + pears = node['style'].downcase.gsub(/\t|\n|\r/, '').split(';') + style = '' + pears.each { |pear| + prop = pear.split(':') + next if !prop[0] + key = prop[0].strip + next if !css_properties_whitelist.include?(key) + style += "#{pear};" + } + node['style'] = style + if style == '' + node.delete('style') + end + end + + # scan for invalid link content + %w(href style).each { |attribute_name| + next if !node[attribute_name] + href = cleanup(node[attribute_name]) + next if href !~ /(javascript|livescript|vbscript):/i + node.delete(attribute_name) + } + + # remove attributes if not whitelisted + node.each { |attribute, _value| + attribute_name = attribute.downcase + next if attributes_whitelist[:all].include?(attribute_name) || (attributes_whitelist[node.name] && attributes_whitelist[node.name].include?(attribute_name)) + node.delete(attribute) + } + # prepare links if node['href'] - if node['href'].downcase.start_with?('http', 'ftp') - node.set_attribute('rel', 'nofollow') - node.set_attribute('target', '_blank') - end - if node['href'] =~ /javascript/i - node.delete('href') - end + href = cleanup(node['href']) + next if !href.start_with?('http', 'ftp', '//') + node.set_attribute('rel', 'nofollow') + node.set_attribute('target', '_blank') end - - # remove on* attributes - node.each { |attribute, _value| - next if !attribute.downcase.start_with?('on') - node.delete(attribute) - } end Loofah.fragment(string).scrub!(scrubber).to_s end + def self.traversal(node, scrubber) + node.children.each { |child| + if child.class == Nokogiri::XML::CDATA + node.before Nokogiri::XML::Text.new(node.content, node.document) + else + node.before Loofah.fragment(child.to_s).scrub!(scrubber) + end + } + node.remove + end + + def self.cleanup(string) + string.downcase.gsub(/[[:space:]]|\t|\n|\r/, '').gsub(%r{/\*.*?\*/}, '').gsub(//, '').gsub(/\[.+?\]/, '') + end + + private_class_method :traversal + private_class_method :cleanup + end diff --git a/test/unit/email_process_test.rb b/test/unit/email_process_test.rb index fefc4220b..8c0a25f2a 100644 --- a/test/unit/email_process_test.rb +++ b/test/unit/email_process_test.rb @@ -148,7 +148,7 @@ Some Text", }, 1 => { content_type: 'text/html', - body: "_________________________________________________________________________________Please beth saw his head

9õhH3ÿoIÚõ´GÿiH±6u-û◊NQ4ùäU¹awAq¹JLZμÒIicgT1ζ2Y7⊆t 63‘Mñ36EßÝ→DAå†I048CvJ9A↑3iTc4ÉIΥvXO50ñNÁFJSð­r 154F1HPOÀ£CRxZp tLîT9öXH1b3Es±W mNàBg3õEbPŒSúfτTóY4 sUÖPÒζΔRFkcIÕ1™CÓZ3EΛRq!Cass is good to ask what that
86ËÏuÕC L I C K   H E R E28M (http://piufup.medicatingsafemart.ru)Luke had been thinking about that.
Shannon said nothing in fact they. Matt placed the sofa with amy smiled. Since the past him with more. Maybe he checked the phone. Neither did her name only. Ryan then went inside matt.
Maybe we can have anything you sure.
á•XMYÍÅEE£ÓN°kP'dÄÅS4⌉d √p¨HΣ>jE4y4ACüûLì“vT∧4tHXÆX:
x5VV\"¹tiçÂaaΦ3fg¦zèr«°haeJw n§Va879sÆ3j f¶ïlÞ9lo5F¾wν¶1 κψ›a9f4sLsL ùVo$v3x1¸nz.uȦ1H4s35Ô7 yoQCÄFMiMzda¯ZεlÝHNi¬cÚsù–ϖ DYhaã7Ns4Ö· n3dl1XÆo¯µ¶wpN↑ YQ7aé39s1qÓ QyL$fcÕ1ΝS5.5Wy62­d5ĶH
³7<V401i4æÂaθÀTg÷ÄGr9EûaΡBw →ÌÖSRSLu72lpL6Veº9Ær¾HL FEpAÕø9cP¬ltÒcDibäXvTtFel3®+bVM ø5ôaXWas4ºä μÕKl∏7mo√þ3wSg1 ι£Ca´´Xso18 ÅL2$…4¾2Jo↑.0Λa53iè55WÕ î3IV4◊9iFÊVaßÕóg8³9r℘buaf®2 fc7Pg3⊆rzç8oÜ−⋅fÿ≥ZeaPÑs5⇐TsiΨ∋i9ÌuoU8RnΨ⌉•aw1flfùë TQNaU›ésvDu BÇIl6Θlo∠HfwNX8 36Xa∼α»sT½d ŠHG$Îõ¬3QWÀ.‰›Y5Ôg80¦ao
LKNV0ÄwiM4xafsJgFJär27”a⇐MÔ ∠O5SQØMuté«p÷ÅÃe¨ûHrZ4Ä 1UΛF¨TsoûwXrú4Ickyçe½qY 074aÙl⌊sÐH1 4Ùplø4Xob0aw4FÔ 28∴a70lsA30 ßWF$Z¸v4AEG.Î6¨2t9p5¶¼Q M9¯Cε92i0qPa¹AölW5Pi5Vusi8ë ðO0SE2Euù∈èpòY3eTs6r6ý2 lªÌAyîjcQpet½3õiiqXvPVOe8­V+«“G ¤ó6a®Π7sJÕg ¡JÈl♥Š¾oÐolwBVà →AmaηÒ¯saÑÚ Häð$2Ef2∈n5.Œ8H95¨19⊃ƒõ
Up dylan in love and found herself. Sorry for beth smiled at some time Whatever you on one who looked. Except for another man and ready.
ÚúeACíøN˵UT3L♠ICë9-BŒfAoÓCL5ΒÉLHοNE5∂7RScdGX­ªIpΣuCCw∨/D¤6A´vâS0d⊂TÇ'BHfóΔMåß7A63B:
2UýV5¦Ueý¿×nRm2tæÓOoγ1øly¼Wi6pxnÀZ« câSa8ï¤sGï⊂ ΜJll1£„onbéw⌉ö1 vY8aΘmgs0Ú4 å¥G$·592KkU1®b0.½Âℜ54Èh0º´h Zf­A0j¸dc1ξv™Xpagl×ib8YrSf0 ¨WiaÀ4»sÁ×7 TAwll¨dom1Gw2¿z ΒÿÀaˆyÎsN8η 3oo$D012Λp³4cìz.PA∅9ϒ7354ú9
RãíNn¨2aYRøs≅←ÍoPÀynCΧ»efõoxÕ∪h E18aNÿÜsiÿ5 f47lÃ47oFÂjwGÎÉ ·08aºedsjÛS ¿e®$KèR1LDÍ7üoè.4·O99Ý£9íϖn ¶ú↵Sι3”pÝó‾iEuerΓy0iY30vΤA6a2\"Y 465a1m6sgÁs C∀ilΑÒΠor6yw7¿ð 1KΩaÐ32s∇Δ¤ 9Χ9$MWN2P0É8óËβ.Ö∩S93íñ0RQ’
Have anything but matty is taking care. Voice sounded in name only the others Mouth shut and while he returned with. Herself with one who is your life
ÿ²íGu8NEZ3FNFsôEÆRnRÇC9AK4xLÀ5Ç Ì5bH97CE«Ì0AÎq¢Lµk→TªJkHe3š:Taking care about matt li? ed ryan. Knowing he should be there.
Ks£TäbIr74EaãDZmœH¡a³7odÅ∪voÒozlP3S 23‹azy∝sÚ°Q 4â¹ll21ovh7w2D2 ©Qwa⇑cΒs¨wH Iµe$⇐J517Tñ.t5f36ÅB06ãΨ 5z℘Z4nGiý89t←f4hvnàrbŸTo1s9m¥Ëqand·xxO6 Iÿ∪ak½0sÙ£M ûΗ¡løȾorztw170 —♣≅ar6qsvDv 76T$3×D0erÍ.d¼07WoI5ÀKú
ϒa9P'¶¯rP74o2ψÈzχfþaÃàñc3qY →®7aaRgsN©k ¯‰ΣlÍpÃo7R⊂wÆðe 3Iha♣d˜s3g7 È3M$≡⋅ª0AY4.Uq√3Û±k5SUΜ Zr2A8Ö6cZŸdoΡeumpq¼pAoUlèI2ieYÒaK>∂ 3n6ax1Qs20b °Häl9¶ÑoÏ6aw≡dä ΗÅ2a¢Óvs⊃Á7 C⊆Ä$2Bz2sló.∫Pb5ØMx0oQd
ZΙμPCqmrµp0eAΦ♥dô‾Ωn∠2si4y2s÷8«o6∀ClDeÌoPbqnd¡Jelè× ÿˆ5aWl〈sbPÔ ï²çl8¢OoH¸ew’90 Υ66aÕÆdsh6K r6Ç$7Ey0WcÎ.£—012C857Aþ i·σS€53yxµèn80ntΡΠmhç≡hrB²doµS¥ih÷rdOKK 7½öa←ãIs2⌉V Cssl±´RoT1QwyÉΔ •∏∞aïYGsÂ8E 1πx$04ò0gMF.bTQ3Íx658ùς
Maybe even though she followed. Does this mean you talking about. Whatever else to sit on them back
←4BC3éhAGAWNrÛjAGυ»D¬f4Iðm√AHM9N〉1è ‚¬HDÁ9ÜRâ3∨U90IG¾99S¶∪”T¥ì3OË°cR0E⇑E2°1 4ÖaA″XΝDµ4ℑVAK8Aµd9NrÅDT¦12A5khGA3mE98ÔS9KC!5TU
AMm>EjL w∗LWυIaoKd¹rΘ22l2IΚdê5PwO4Hiây6dÖH⌊eÃìg j14Dr­5e700lH·ÐiJ±ùvY…öe¦mhr¸«4yrÆÔ!∑η2 ÷¬υOΔfδrKZwd4KVeB¶órℜ0Ç PΖ×341o+A7Y ¬æ6GM17oGOºos7∑d×7ûs¤8P ο♦QaRn–n5b2d0ìw ËrϒGIÑℑem0∀t³bæ 20rF4O7Rä2°EÇò⊆ESΥ4 KF0AÒÂßi5ïcrt⊆€mRJ7aNΛÿinÕ6l5bQ ¸ϒtSZbwh3¶3ig♠9p2″Ìp×¢êiK»´nsWsgdXW!tBO
m0W>YÙ b¬u1xΔd03¯¬0vHK%Þ¹ó 674Aj3öuQ←ÏtÈH¨houqeyªYnÑ21t⌋BZi¦V2c¬Tn >ZΓMöÜÊe3Å1dís5s2ø›!³0û 2¡ÌEmè1xéV2p1∨6iâdârB9ra72mtSzIiMlVo0NLngΒû ú2LD7⇑maNx3tUζ∪etcù 90ìo¶Ù3fv49 w≅»O0givÅýYeXïNryfT 3fP3xZÕ FñÃY8q¯eEÂÜaâyfrΜpls9âÂ!qκÊ
î5A>∀pƒ ZµÍSδ3éem2sc⊕7vu41JrÒ°weÊyh qaρOÏp¼nΣxZlrN¡i♠Êcnl4jeN¶Q y2≅Sb63h17〉ofµypÅAÆpþh0iÔcbnec4gIù1 h2Uw23‹i9çktSÅÏh6Vº g±sVŒóuipV¯seÈ⋅a4üV,T6D 2ý8MΡY©a⊃ºΕs5ùýt9IDeFDℑrXpOCe“μan·Mr¾1Kd¥ëð,eø7 DfmAæ¤NM9ïhEUË∨XσψG 4j0a°81nhTAdmTü «9öEνμr-U4fc¨Þ1h8ª¸eoycc9xjk⁄ko!ë9K
¬Û…>J6Á ¢〉8EÖ22a³41s¬17y3â8 °f2R6olewtzfw¹suýoQn⇓³³d×4Gs¢7« AlDa°H¶n9Ejdtg› ¯ôθ2ε¥⊇4¯″A/4Øv72z→ Ü3¥C6ú2u56Xs9⁄1t∑ΙioxÉjmØRùe1WÔrH25 o¥ßS≥gmuX2gp3yip·³2oD£3rc3μtks∪!sWK
When she were there you here. Lott to need for amy said.
Once more than ever since matt. Lott said turning o? ered. Tell you so matt kept going.
Homegrown dandelions by herself into her lips. Such an excuse to stop thinking about. Leave us and be right.




http://www.avast.com/
?????? ?????????????????? ???????????????? ???? ?????????????? ?? ???????????????????????? ???? ?????????????????? avast! Antivirus (http://www.avast.com/) ???????????? ??????????????.", + body: "_________________________________________________________________________________Please beth saw his head

9õhH3ÿoIÚõ´GÿiH±6u-û◊NQ4ùäU¹awAq¹JLZμÒIicgT1ζ2Y7⊆t 63‘Mñ36EßÝ→DAå†I048CvJ9A↑3iTc4ÉIΥvXO50ñNÁFJSð­r 154F1HPOÀ£CRxZp tLîT9öXH1b3Es±W mNàBg3õEbPŒSúfτTóY4 sUÖPÒζΔRFkcIÕ1™CÓZ3EΛRq!Cass is good to ask what that
86ËÏuÕC L I C K   H E R E28M (http://piufup.medicatingsafemart.ru)Luke had been thinking about that.
Shannon said nothing in fact they. Matt placed the sofa with amy smiled. Since the past him with more. Maybe he checked the phone. Neither did her name only. Ryan then went inside matt.
Maybe we can have anything you sure.
á•XMYÍÅEE£ÓN°kP'dÄÅS4⌉d √p¨HΣ>jE4y4ACüûLì“vT∧4tHXÆX:
x5VV\"¹tiçÂaaΦ3fg¦zèr«°haeJw n§Va879sÆ3j f¶ïlÞ9lo5F¾wν¶1 κψ›a9f4sLsL ùVo$v3x1¸nz.uȦ1H4s35Ô7 yoQCÄFMiMzda¯ZεlÝHNi¬cÚsù–ϖ DYhaã7Ns4Ö· n3dl1XÆo¯µ¶wpN↑ YQ7aé39s1qÓ QyL$fcÕ1ΝS5.5Wy62­d5ĶH
³7<V401i4æÂaθÀTg÷ÄGr9EûaΡBw →ÌÖSRSLu72lpL6Veº9Ær¾HL FEpAÕø9cP¬ltÒcDibäXvTtFel3®+bVM ø5ôaXWas4ºä μÕKl∏7mo√þ3wSg1 ι£Ca´´Xso18 ÅL2$…4¾2Jo↑.0Λa53iè55WÕ î3IV4◊9iFÊVaßÕóg8³9r℘buaf®2 fc7Pg3⊆rzç8oÜ−⋅fÿ≥ZeaPÑs5⇐TsiΨ∋i9ÌuoU8RnΨ⌉•aw1flfùë TQNaU›ésvDu BÇIl6Θlo∠HfwNX8 36Xa∼α»sT½d ŠHG$Îõ¬3QWÀ.‰›Y5Ôg80¦ao
LKNV0ÄwiM4xafsJgFJär27”a⇐MÔ ∠O5SQØMuté«p÷ÅÃe¨ûHrZ4Ä 1UΛF¨TsoûwXrú4Ickyçe½qY 074aÙl⌊sÐH1 4Ùplø4Xob0aw4FÔ 28∴a70lsA30 ßWF$Z¸v4AEG.Î6¨2t9p5¶¼Q M9¯Cε92i0qPa¹AölW5Pi5Vusi8ë ðO0SE2Euù∈èpòY3eTs6r6ý2 lªÌAyîjcQpet½3õiiqXvPVOe8­V+«“G ¤ó6a®Π7sJÕg ¡JÈl♥Š¾oÐolwBVà →AmaηÒ¯saÑÚ Häð$2Ef2∈n5.Œ8H95¨19⊃ƒõ
Up dylan in love and found herself. Sorry for beth smiled at some time Whatever you on one who looked. Except for another man and ready.
ÚúeACíøN˵UT3L♠ICë9-BŒfAoÓCL5ΒÉLHοNE5∂7RScdGX­ªIpΣuCCw∨/D¤6A´vâS0d⊂TÇ'BHfóΔMåß7A63B:
2UýV5¦Ueý¿×nRm2tæÓOoγ1øly¼Wi6pxnÀZ« câSa8ï¤sGï⊂ ΜJll1£„onbéw⌉ö1 vY8aΘmgs0Ú4 å¥G$·592KkU1®b0.½Âℜ54Èh0º´h Zf­A0j¸dc1ξv™Xpagl×ib8YrSf0 ¨WiaÀ4»sÁ×7 TAwll¨dom1Gw2¿z ΒÿÀaˆyÎsN8η 3oo$D012Λp³4cìz.PA∅9ϒ7354ú9
RãíNn¨2aYRøs≅←ÍoPÀynCΧ»efõoxÕ∪h E18aNÿÜsiÿ5 f47lÃ47oFÂjwGÎÉ ·08aºedsjÛS ¿e®$KèR1LDÍ7üoè.4·O99Ý£9íϖn ¶ú↵Sι3”pÝó‾iEuerΓy0iY30vΤA6a2\"Y 465a1m6sgÁs C∀ilΑÒΠor6yw7¿ð 1KΩaÐ32s∇Δ¤ 9Χ9$MWN2P0É8óËβ.Ö∩S93íñ0RQ’
Have anything but matty is taking care. Voice sounded in name only the others Mouth shut and while he returned with. Herself with one who is your life
ÿ²íGu8NEZ3FNFsôEÆRnRÇC9AK4xLÀ5Ç Ì5bH97CE«Ì0AÎq¢Lµk→TªJkHe3š:Taking care about matt li? ed ryan. Knowing he should be there.
Ks£TäbIr74EaãDZmœH¡a³7odÅ∪voÒozlP3S 23‹azy∝sÚ°Q 4â¹ll21ovh7w2D2 ©Qwa⇑cΒs¨wH Iµe$⇐J517Tñ.t5f36ÅB06ãΨ 5z℘Z4nGiý89t←f4hvnàrbŸTo1s9m¥Ëqand·xxO6 Iÿ∪ak½0sÙ£M ûΗ¡løȾorztw170 —♣≅ar6qsvDv 76T$3×D0erÍ.d¼07WoI5ÀKú
ϒa9P'¶¯rP74o2ψÈzχfþaÃàñc3qY →®7aaRgsN©k ¯‰ΣlÍpÃo7R⊂wÆðe 3Iha♣d˜s3g7 È3M$≡⋅ª0AY4.Uq√3Û±k5SUΜ Zr2A8Ö6cZŸdoΡeumpq¼pAoUlèI2ieYÒaK>∂ 3n6ax1Qs20b °Häl9¶ÑoÏ6aw≡dä ΗÅ2a¢Óvs⊃Á7 C⊆Ä$2Bz2sló.∫Pb5ØMx0oQd
ZΙμPCqmrµp0eAΦ♥dô‾Ωn∠2si4y2s÷8«o6∀ClDeÌoPbqnd¡Jelè× ÿˆ5aWl〈sbPÔ ï²çl8¢OoH¸ew’90 Υ66aÕÆdsh6K r6Ç$7Ey0WcÎ.£—012C857Aþ i·σS€53yxµèn80ntΡΠmhç≡hrB²doµS¥ih÷rdOKK 7½öa←ãIs2⌉V Cssl±´RoT1QwyÉΔ •∏∞aïYGsÂ8E 1πx$04ò0gMF.bTQ3Íx658ùς
Maybe even though she followed. Does this mean you talking about. Whatever else to sit on them back
←4BC3éhAGAWNrÛjAGυ»D¬f4Iðm√AHM9N〉1è ‚¬HDÁ9ÜRâ3∨U90IG¾99S¶∪”T¥ì3OË°cR0E⇑E2°1 4ÖaA″XΝDµ4ℑVAK8Aµd9NrÅDT¦12A5khGA3mE98ÔS9KC!5TU
AMm>EjL w∗LWυIaoKd¹rΘ22l2IΚdê5PwO4Hiây6dÖH⌊eÃìg j14Dr­5e700lH·ÐiJ±ùvY…öe¦mhr¸«4yrÆÔ!∑η2 ÷¬υOΔfδrKZwd4KVeB¶órℜ0Ç PΖ×341o+A7Y ¬æ6GM17oGOºos7∑d×7ûs¤8P ο♦QaRn–n5b2d0ìw ËrϒGIÑℑem0∀t³bæ 20rF4O7Rä2°EÇò⊆ESΥ4 KF0AÒÂßi5ïcrt⊆€mRJ7aNΛÿinÕ6l5bQ ¸ϒtSZbwh3¶3ig♠9p2″Ìp×¢êiK»´nsWsgdXW!tBO
m0W>YÙ b¬u1xΔd03¯¬0vHK%Þ¹ó 674Aj3öuQ←ÏtÈH¨houqeyªYnÑ21t⌋BZi¦V2c¬Tn >ZΓMöÜÊe3Å1dís5s2ø›!³0û 2¡ÌEmè1xéV2p1∨6iâdârB9ra72mtSzIiMlVo0NLngΒû ú2LD7⇑maNx3tUζ∪etcù 90ìo¶Ù3fv49 w≅»O0givÅýYeXïNryfT 3fP3xZÕ FñÃY8q¯eEÂÜaâyfrΜpls9âÂ!qκÊ
î5A>∀pƒ ZµÍSδ3éem2sc⊕7vu41JrÒ°weÊyh qaρOÏp¼nΣxZlrN¡i♠Êcnl4jeN¶Q y2≅Sb63h17〉ofµypÅAÆpþh0iÔcbnec4gIù1 h2Uw23‹i9çktSÅÏh6Vº g±sVŒóuipV¯seÈ⋅a4üV,T6D 2ý8MΡY©a⊃ºΕs5ùýt9IDeFDℑrXpOCe“μan·Mr¾1Kd¥ëð,eø7 DfmAæ¤NM9ïhEUË∨XσψG 4j0a°81nhTAdmTü «9öEνμr-U4fc¨Þ1h8ª¸eoycc9xjk⁄ko!ë9K
¬Û…>J6Á ¢〉8EÖ22a³41s¬17y3â8 °f2R6olewtzfw¹suýoQn⇓³³d×4Gs¢7« AlDa°H¶n9Ejdtg› ¯ôθ2ε¥⊇4¯″A/4Øv72z→ Ü3¥C6ú2u56Xs9⁄1t∑ΙioxÉjmØRùe1WÔrH25 o¥ßS≥gmuX2gp3yip·³2oD£3rc3μtks∪!sWK
When she were there you here. Lott to need for amy said.
Once more than ever since matt. Lott said turning o? ered. Tell you so matt kept going.
Homegrown dandelions by herself into her lips. Such an excuse to stop thinking about. Leave us and be right.




http://www.avast.com/
?????? ?????????????????? ???????????????? ???? ?????????????? ?? ???????????????????????? ???? ?????????????????? avast! Antivirus (http://www.avast.com/) ???????????? ??????????????.", sender: 'Customer', type: 'email', internal: false, @@ -165,7 +165,7 @@ Some Text", }, 1 => { content_type: 'text/html', - body: "Puzzled by judith bronte dave. Melvin will want her way through with.
Continued adam helped charlie cried. Soon joined the master bathroom. Grinned adam rubbed his arms she nodded.
Freemont and they talked with beppe.
Thinking of bed and whenever adam.
Mike was too tired man to hear.
I10PQSHEJl2Nwf&tilde;2113S173 &Icirc;1mEbb5N371L&piv;C7AlFnR1&diams;HG64B242&brvbar;M2242zk&Iota;N&rceil;7&rceil;TBN&ETH; T2xPI&ograve;gI2&Atilde;lL2&Otilde;ML&perp;22Sa&Psi;RBreathed adam gave the master bedroom door.
Better get charlie took the wall.
Charlotte clark smile he saw charlie.
Dave and leaned her tears adam.
Maybe we want any help me that.
Next morning charlie gazed at their father.
Well as though adam took out here. Melvin will be more money. Called him into this one last night.
Men joined the pickup truck pulled away. Chuck could make sure that.&dagger;p1C?L&thinsp;I?C&ensp;K?88&ensp;5 E R?EEOD ! (11115441111411?jmlfwnwe&ucwkiyyc)Chuckled adam leaned forward and le? charlie.
Just then returned to believe it here.
Freemont and pulling out several minutes.", + body: "Puzzled by judith bronte dave. Melvin will want her way through with.
Continued adam helped charlie cried. Soon joined the master bathroom. Grinned adam rubbed his arms she nodded.
Freemont and they talked with beppe.
Thinking of bed and whenever adam.
Mike was too tired man to hear.
I10PQSHEJl2Nwf&tilde;2113S173 &Icirc;1mEbb5N371L&piv;C7AlFnR1&diams;HG64B242&brvbar;M2242zk&Iota;N&rceil;7&rceil;TBN&ETH; T2xPI&ograve;gI2&Atilde;lL2&Otilde;ML&perp;22Sa&Psi;RBreathed adam gave the master bedroom door.
Better get charlie took the wall.
Charlotte clark smile he saw charlie.
Dave and leaned her tears adam.
Maybe we want any help me that.
Next morning charlie gazed at their father.
Well as though adam took out here. Melvin will be more money. Called him into this one last night.
Men joined the pickup truck pulled away. Chuck could make sure that.&dagger;p1C?L&thinsp;I?C&ensp;K?88&ensp;5 E R?EEOD ! (11115441111411?jmlfwnwe&ucwkiyyc)Chuckled adam leaned forward and le? charlie.
Just then returned to believe it here.
Freemont and pulling out several minutes.", sender: 'Customer', type: 'email', internal: false, diff --git a/test/unit/html_sanitizer_test.rb b/test/unit/html_sanitizer_test.rb new file mode 100644 index 000000000..003d5eb4a --- /dev/null +++ b/test/unit/html_sanitizer_test.rb @@ -0,0 +1,74 @@ +# encoding: utf-8 +require 'test_helper' + +class HtmlSanitizerTest < ActiveSupport::TestCase + + test 'xss' do + assert_equal(HtmlSanitizer.strict('123'), '123') + assert_equal(HtmlSanitizer.strict(''), '<b>123</b>') + assert_equal(HtmlSanitizer.strict(''), '<style><b>123</b></style>') + assert_equal(HtmlSanitizer.strict('123123'), '123123') + assert_equal(HtmlSanitizer.strict('123123abc'), '123123abc') + assert_equal(HtmlSanitizer.strict('123'), '123') + assert_equal(HtmlSanitizer.strict(''), 'alert("XSS!");') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict('">'), 'alert("XSS")">') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict(''), '') + assert_equal(HtmlSanitizer.strict('<'), '<alert("XSS");//<') + assert_equal(HtmlSanitizer.strict(''), 'alert(\'XSS\');') + assert_equal(HtmlSanitizer.strict('