HTML-Defang-1.09/0000755000000000000000000000000015235211710012064 5ustar rootrootHTML-Defang-1.09/Makefile.PL0000644000000000000000000000111115235073534014042 0ustar rootrootuse 5.008008; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'HTML::Defang', VERSION_FROM => 'lib/HTML/Defang.pm', # finds $VERSION LICENSE => 'perl', PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/HTML/Defang.pm', # retrieve abstract from module AUTHOR => 'Rob Mueller ') : ()), ); HTML-Defang-1.09/README0000644000000000000000000000116715235211642012755 0ustar rootrootHTML-Defang version 1.09 ======================== This module accepts an input HTML and/or CSS string and removes any executable code including scripting, embedded objects, applets, etc., and neutralises any XSS attacks. A whitelist based approach is used which means only HTML known to be safe is allowed through. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES None COPYRIGHT AND LICENCE Copyright (C) 2003-2025 by Fastmail Pty Ltd This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. HTML-Defang-1.09/MANIFEST0000644000000000000000000000055715235211710013224 0ustar rootrootChanges lib/HTML/Defang.pm Makefile.PL MANIFEST This list of files README t/01_basic.t t/02_xss.t t/03_styles.t t/04_imports.t t/05_callbacks.t t/06_unicode.t t/07_rcdata.t t/08_comments.t t/09_attrs.t META.yml Module meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) HTML-Defang-1.09/lib/0000755000000000000000000000000015235211710012632 5ustar rootrootHTML-Defang-1.09/lib/HTML/0000755000000000000000000000000015235211710013376 5ustar rootrootHTML-Defang-1.09/lib/HTML/Defang.pm0000644000000000000000000024004215235211622015124 0ustar rootrootpackage HTML::Defang; =head1 NAME HTML::Defang - Cleans HTML as well as CSS of scripting and other executable contents, and neutralises XSS attacks. =head1 SYNOPSIS my $InputHtml = ""; my $Defang = HTML::Defang->new( context => $Self, fix_mismatched_tags => 1, tags_to_callback => [ br embed img ], tags_callback => \&DefangTagsCallback, url_callback => \&DefangUrlCallback, css_callback => \&DefangCssCallback, attribs_to_callback => [ qw(border src) ], attribs_callback => \&DefangAttribsCallback, content_callback => \&ContentCallback, ); my $SanitizedHtml = $Defang->defang($InputHtml); # Callback for custom handling specific HTML tags sub DefangTagsCallback { my ($Self, $Defang, $OpenAngle, $lcTag, $IsEndTag, $AttributeHash, $CloseAngle, $HtmlR, $OutR) = @_; # Explicitly defang this tag, eventhough safe return DEFANG_ALWAYS if $lcTag eq 'br'; # Explicitly whitelist this tag, eventhough unsafe return DEFANG_NONE if $lcTag eq 'embed'; # I am not sure what to do with this tag, so process as HTML::Defang normally would return DEFANG_DEFAULT if $lcTag eq 'img'; } # Callback for custom handling URLs in HTML attributes as well as style tag/attribute declarations sub DefangUrlCallback { my ($Self, $Defang, $lcTag, $lcAttrKey, $AttrValR, $AttributeHash, $HtmlR) = @_; # Explicitly allow this URL in tag attributes or stylesheets return DEFANG_NONE if $$AttrValR =~ /safesite.com/i; # Explicitly defang this URL in tag attributes or stylesheets return DEFANG_ALWAYS if $$AttrValR =~ /evilsite.com/i; } # Callback for custom handling style tags/attributes sub DefangCssCallback { my ($Self, $Defang, $Selectors, $SelectorRules, $Tag, $IsAttr) = @_; my $i = 0; foreach (@$Selectors) { my $SelectorRule = $$SelectorRules[$i]; foreach my $KeyValueRules (@$SelectorRule) { foreach my $KeyValueRule (@$KeyValueRules) { my ($Key, $Value) = @$KeyValueRule; # Comment out any '!important' directive $$KeyValueRule[2] = DEFANG_ALWAYS if $Value =~ '!important'; # Comment out any 'position=fixed;' declaration $$KeyValueRule[2] = DEFANG_ALWAYS if $Key =~ 'position' && $Value =~ 'fixed'; } } $i++; } } # Callback for custom handling HTML tag attributes sub DefangAttribsCallback { my ($Self, $Defang, $lcTag, $lcAttrKey, $AttrValR, $HtmlR) = @_; # Change all 'border' attribute values to zero. $$AttrValR = '0' if $lcAttrKey eq 'border'; # Defang all 'src' attributes return DEFANG_ALWAYS if $lcAttrKey eq 'src'; return DEFANG_NONE; } # Callback for all content between tags (except ") if !$ClosingStyleTagPresent; return $Defang; } =item I Defang some raw css data and return the defanged content =over 4 =item B =over 4 =item I<$Content> The input style string that is defanged. =item I<$IsAttr> True if $Content is from an attribute, otherwise from a EOF $R = $D->defang($H); like($R, qr{^$}, "Remote style sheet part 2 - XXX Style"); $H = < EOF $R = $D->defang($H); like($R, qr{^$}, "Remote style sheet part 3"); $H = <BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")} EOF $R = $D->defang($H); like($R, qr{^\s$}, "Remote style sheet part 4 - XXX Style"); $H = < EOF $R = $D->defang($H); like($R, qr{^$}, "Local htc file"); $H = <li {list-style-image: url("javascript:alert('XSS')");}