HTML::...cripts(3pm)
β¨ NAME β¨
HTML::StripScripts β Strip scripting constructs out of HTML
(and yes bestie, this is the HTML::StripScripts(3pm) manual page, so get ready for a whole vibe π)
πΈ SYNOPSIS πΈ
use HTML::StripScripts;
my $hss = HTML::StripScripts->new({ Context => 'Inline' });
$hss->input_start_document;
$hss->input_start('<i>');
$hss->input_text('hello, world!');
$hss->input_end('</i>');
$hss->input_end_document;
print $hss->filtered_document;
π¦ DESCRIPTION π¦
okay so this module literally strips scripting constructs out of HTML, leaving as much non-scripting markup in place as possible. This allows web applications to display HTML originating from an untrusted source without introducing XSS (cross site scripting) vulnerabilities. no cap, it's a whole security vibe. π
You will probably use HTML::StripScripts::Parser rather than using this module directly. fr fr, that's the move.
The process is based on whitelists of tags, attributes and attribute values. This approach is the most secure against disguised scripting constructs hidden in malicious HTML documents. it's giving safety-first, periodt.
As well as removing scripting constructs, this module ensures that there is a matching end for each start tag, and that the tags are properly nested. so no messy tag soup, bestie.
Previously, in order to customise the output, you needed to subclass "HTML::StripScripts" and override methods. Now, most customisation can be done through the "Rules" option provided to "new()". (See examples/declaration/ and examples/tags/ for cases where subclassing is necessary.) okay so glow up, you can just use Rules now, iconic.
The HTML document must be parsed into start tags, end tags and text before it can be filtered by this module. Use either HTML::StripScripts::Parser or HTML::StripScripts::Regex instead if you want to input an unparsed HTML document. lowkey important, don't skip this.
See examples/direct/ for an example of how to feed tokens directly to HTML::StripScripts. iykyk.
π οΈ CONSTRUCTORS π οΈ
π new ( CONFIG ) π
Creates a new "HTML::StripScripts" filter object, bound to a particular filtering policy. If present, the CONFIG parameter must be a hashref. The following keys are recognized (unrecognized keys will be silently ignored). okay so it's literally the main character constructor.
$s = HTML::Stripscripts->new({
Context => 'Document|Flow|Inline|NoTags',
BanList => [qw( br img )] | {br => '1', img => '1'},
BanAllBut => [qw(p div span)],
AllowSrc => 0|1,
AllowHref => 0|1,
AllowRelURL => 0|1,
AllowMailto => 0|1,
EscapeFiltered => 0|1,
Rules => { See below for details },
});
Context
A string specifying the context in which the filtered document will be used. This influences the set of tags that will be allowed.
If present, the "Context" value must be one of:
"Document"β If"Context"is"Document"then the filter will allow a full HTML document, including the"HTML"tag and"HEAD"and"BODY"sections. it's giving full document energy."Flow"β If"Context"is"Flow"then most of the cosmetic tags that one would expect to find in a document body are allowed, including lists and tables but not including forms. so like, body vibes but no forms."Inline"β If"Context"is"Inline"then only inline tags such as"B"and"FONT"are allowed. tiny little inline cuties only."NoTags"β If"Context"is"NoTags"then no tags are allowed. absolutely zero tags, periodt.
The default "Context" value is "Flow". so if you don't specify, you get Flow.
BanList
If present, this option must be an arrayref or a hashref. Any tag that would normally be allowed (because it presents no XSS hazard) will be blocked if the lowercase name of the tag is in this list.
For example, in a guestbook application where "HR" tags are used to separate posts, you may wish to prevent posts from including "HR" tags, even though "HR" is not an XSS risk. so like, you can ban harmless tags too, just because you want to.
BanAllBut
If present, this option must be reference to an array holding a list of lowercase tag names. This has the effect of adding all but the listed tags to the ban list, so that only those tags listed will be allowed. it's the ultimate "only these, thanks" vibe.
AllowSrc
By default, the filter won't allow constructs that cause the browser to fetch things automatically, such as "SRC" attributes in "IMG" tags. If this option is present and true then those constructs will be allowed. so if you trust it, you can let the browser auto-fetch.
AllowHref
By default, the filter won't allow constructs that cause the browser to fetch things if the user clicks on something, such as the "HREF" attribute in "A" tags. Set this option to a true value to allow this type of construct. clickable links, but only if you say so.
AllowRelURL
By default, the filter won't allow relative URLs such as "../foo.html" in "SRC" and "HREF" attribute values. Set this option to a true value to allow them. "AllowHref" and / or "AllowSrc" also need to be set to true for this to have any effect. so it's a combo deal, bestie.
AllowMailto
By default, "mailto:" links are not allowed. If "AllowMailto" is set to a true value, then this construct will be allowed. This can be enabled separately from AllowHref. so you can have mailto without regular links, slay.
EscapeFiltered
By default, any filtered tags are outputted as "<!--filtered-->". If "EscapeFiltered" is set to a true value, then the filtered tags are converted to HTML entities.
For instance:
<br> --> <br>
Rules
The "Rules" option provides a very flexible way of customising the filter.
The focus is safety-first, so it is applied after all of the previous validation. This means that you cannot all malicious data should already have been cleared. (ngl this sentence is a little wild but we keep it exactly.)
Rules can be specified for tags and for attributes. Any tag or attribute not explicitly listed will be handled by the default "*" rules.
The following is a synopsis of all of the options that you can use to configure rules. Below, an example is broken into sections and explained.
Rules => {
tag => 0 | 1 | sub { tag_callback }
| {
attr => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback},
'*' => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback},
required => [qw(attrname attrname)],
tag => sub { tag_callback }
},
'*' => 0 | 1 | sub { tag_callback }
| {
attr => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback},
'*' => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback},
tag => sub { tag_callback }
}
}
EXAMPLE:
Rules => {
##########################
##### EXPLICIT RULES #####
##########################
## Allow <br> tags, reject <img> tags
br => 1,
img => 0,
## Send all <div> tags to a sub
div => sub { tag_callback },
## Allow <blockquote> tags,and allow the 'cite' attribute
## All other attributes are handled by the default C<*>
blockquote => {
cite => 1,
},
## Allow <a> tags, and
a => {
## Allow the 'title' attribute
title => 1,
## Allow the 'href' attribute if it matches the regex
href => '^http://yourdomain.com'
OR href => qr{^http://yourdomain.com},
## 'style' attributes are handled by a sub
style => sub { attr_callback },
## All other attributes are rejected
'*' => 0,
## Additionally, the <a> tag should be handled by this sub
tag => sub { tag_callback},
## If the <a> tag doesn't have these attributes, filter the tag
required => [qw(href title)],
},
##########################
##### DEFAULT RULES #####
##########################
## The default '*' rule - accepts all the same options as above.
## If a tag or attribute is not mentioned above, then the default
## rule is applied:
## Reject all tags
'*' => 0,
## Allow all tags and all attributes
'*' => 1,
## Send all tags to the sub
'*' => sub { tag_callback },
## Allow all tags, reject all attributes
'*' => { '*' => 0 },
## Allow all tags, and
'*' => {
## Allow the 'title' attribute
title => 1,
## Allow the 'href' attribute if it matches the regex
href => '^http://yourdomain.com'
OR href => qr{^http://yourdomain.com},
## 'style' attributes are handled by a sub
style => sub { attr_callback },
## All other attributes are rejected
'*' => 0,
## Additionally, all tags should be handled by this sub
tag => sub { tag_callback},
},
}
Tag Callbacks
sub tag_callback {
my ($filter,$element) = (@_);
$element = {
tag => 'tag',
content => 'inner_html',
attr => {
attr_name => 'attr_value',
}
};
return 0 | 1;
}
A tag callback accepts two parameters, the $filter object and the C$element>. It should return 0 to completely ignore the tag and its content (which includes any nested HTML tags), or 1 to accept and output the tag.
The $element is a hash ref containing the keys:
"tag"
This one's the tagname, all lowercase bestie β think "a", "br", "img". Iconic trio tbh. And here's the tea: if you set the tag value to an empty string, the tag itself does not get outputted, but its contents still do. Ghost tag energy β¨
"content"
This is basically DOM's innerHTML, no cap. It's holding the text content and any HTML tags nested inside this element. You can swap the content out, or yeet it to an empty string so it's not outputted at all. Your content, your rules π
"attr"
"attr" contains a hashref containing the attribute names and values. Simple. Clean. Ate.
So like, if you wanted to replace <b> tags with <span> tags (glow-up moment), you could do this:
sub b_callback {
my ($filter,$element) = @_;
$element->{tag} = 'span';
$element->{attr}{style} = 'font-weight:bold';
return 1;
}
Attribute Callbacks
sub attr_callback {
my ( $filter, $tag, $attr_name, $attr_val ) = @_;
return undef | '' | 'value';
}
Attribute callbacks accept four parameters: the $filter object, the $tag name, the $attr_name and the $attr_value. Four besties walk into a callback π«Ά
It should return either undef to reject the attribute, or the value to be used. An empty string keeps the attribute, but without a value. So like, present but silent. Relatable.
"BanList" vs "BanAllBut" vs "Rules"
Okay so real talk: it is not necessary to use "BanList" or "BanAllBut" β everything can be done via "Rules". Rules runs the whole show, she's the main character. But sometimes it may be simpler to just write:
BanAllBut => [qw(p div span)]
Look how short!! β¨
The logic works as follows:
- If
BanAllButexists, then ban everything but the tags in the list - Add to the ban list any elements in
BanList - Any tags mentioned explicitly in
Rules(ega => 0,br => 1) are added or removed from theBanList - A default rule of
{ '*' => 0 }would ban all tags except those mentioned inRules - A default rule of
{ '*' => 1 }would allow all tags except those disallowed in the ban list, or by explicit rules
Bestie pls read those bullets twice, the order totally matters π
β¨ METHODS β¨
This class provides the following methods:
hss_init ()
This method is called by new() and does the actual initialisation work for the new HTML::StripScripts object. She's the setup queen π
input_start_document ()
This method initializes the filter, and must be called once before starting on each HTML document to be filtered. Every doc gets a fresh start, periodt.
input_start ( TEXT )
Handles a start tag from the input document. TEXT must be the full text of the tag, including angle-brackets. Yeah, the whole thing, brackets and all π
input_end ( TEXT )
Handles an end tag from the input document. TEXT must be the full text of the end tag, including angle-brackets. Same deal, don't be shy with the brackets.
input_text ( TEXT )
Handles some non-tag text from the input document. Just vibes, no tags.
input_process ( TEXT )
Handles a processing instruction from the input document. Ooh, fancy.
input_comment ( TEXT )
Handles an HTML comment from the input document. Yes queen, even the comments.
input_declaration ( TEXT )
Handles an declaration from the input document. Declarations get their moment too β¨
input_end_document ()
Call this method to signal the end of the input document. That's a wrap, bestie π¬
filtered_document ()
Returns the filtered document as a string. THE payoff function, she delivers π
π¦ SUBCLASSING π¦
The only reason for subclassing this module now is to add to the list of accepted tags, attributes and styles (See "WHITELIST INITIALIZATION METHODS"). Everything else can be achieved with "Rules". Yeah β Rules really did eat and leave no crumbs.
The HTML::StripScripts class is subclassable. Filter objects are plain hashes and HTML::StripScripts reserves only hash keys that start with _hss. So don't go naming your stuff _hss-anything unless you mean it π The filter configuration can be set up by invoking the hss_init() method, which takes the same arguments as new().
π OUTPUT METHODS π
The filter outputs a stream of start tags, end tags, text, comments, declarations and processing instructions, via the following output_* methods. Subclasses may override these to intercept the filter output. Intercepting the output?? Main character energy fr.
The default implementations of the output_* methods pass the text on to the output() method. The default implementation of the output() method appends the text to a string, which can be fetched with the filtered_document() method once processing is complete. So it all funnels down to one string at the end π
Heads up bestie: If theoutput()method or the individualoutput_*methods are overridden in a subclass, thenfiltered_document()will not work in that subclass. No cap, it just won't.
output_start_document ()
This method gets called once at the start of each HTML document passed through the filter. The default implementation does nothing. She's off-duty.
output_end_document ()
This method gets called once at the end of each HTML document passed through the filter. The default implementation does nothing. Also off-duty, respectfully.
output_start ( TEXT )
This method is used to output a filtered start tag. Fresh start tag, filtered and cute.
output_end ( TEXT )
This method is used to output a filtered end tag. And the matching end tag, slay.
output_text ( TEXT )
This method is used to output some filtered non-tag text. Just the text, minding its business.
output_declaration ( TEXT )
This method is used to output a filtered declaration. Declarations, filtered edition β¨
output_comment ( TEXT )
This method is used to output a filtered HTML comment. Comments too, filtered and everything.
output_process ( TEXT )
This method is used to output a filtered processing instruction. Processing instructions, filtered π
output ( TEXT )
This method is invoked by all of the default output_* methods. The default implementation appends the text to the string that the filtered_document() method will return. She's the one holding the string together π«Ά
output_stack_entry ( TEXT )
This method is invoked when a tag plus all text and nested HTML content within the tag has been processed. It adds the tag plus its content to the content for its parent tag. Nesting, but make it cozy π§
π REJECT METHODS π
When the filter encounters something in the input document which it cannot transform into an acceptable construct, it invokes one of the following reject_* methods to put something in the output document to take the place of the unacceptable construct. Yeah, we're doing rejections now.
The TEXT parameter is the full text of the unacceptable construct.
The default implementations of these methods output an HTML comment containing the text "filtered". If "EscapeFiltered" is set to true, then the rejected text is HTML escaped instead. So either it gets commented out, or it gets escaped β depends on your settings β¨
BIG warning bestie: Subclasses may override these methods, but should exercise caution. The TEXT parameter is unfiltered input and may contain malicious constructs. Like, actually dangerous. Do not just echo it back, I'm begging π
reject_start ( TEXT )
reject_end ( TEXT )
reject_text ( TEXT )
reject_declaration ( TEXT )
reject_comment ( TEXT )
reject_process ( TEXT )
πΈ WHITELIST INITIALIZATION METHODS πΈ
The filter refers to various whitelists to determine which constructs are acceptable. To modify these whitelists, subclasses can override the following methods. Whitelists = the guest list. No invite, no entry π
Each method is called once at object initialization time, and must return a reference to a nested data structure. These references are installed into the object, and used whenever the filter needs to refer to a whitelist. Set it once, use it forever β¨
The default implementations of these methods can be invoked as class methods.
See examples/tags/ and examples/declaration/ for examples of how to override these methods. Go peek, they're right there π
init_context_whitelist ()
Returns a reference to the "Context" whitelist, which determines which tags may appear at each point in the document, and which other tags may be nested within them. Basically: who's allowed where, and who can hang out inside whom π¦
It is a hash, and the keys are context names, such as "Flow" and "Inline".
The values in the hash are hashrefs. The keys in these subhashes are lowercase tag names, and the values are context names, specifying the context that the tag provides to any other tags nested within it.
The special context "EMPTY" as a value in a subhash indicates that nothing can be nested within that tag. Empty means EMPTY, bestie. No plus-ones.
init_attrib_whitelist ()
Returns a reference to the "Attrib" whitelist, which determines which attributes each tag can have and the values that those attributes can take. Attribute permission slips, basically π
It is a hash, and the keys are lowercase tag names.
The values in the hash are hashrefs. The keys in these subhashes are lowercase attribute names, and the values are attribute value class names, which are short strings describing the type of values that the attribute can take, such as "color" or "number". Little class names doing big work β¨
init_attval_whitelist ()
Returns a reference to the "AttVal" whitelist, which is a hash that maps attribute value class names from the "Attrib" whitelist to coderefs to subs to validate (and optionally transform) a particular attribute value. Validate AND glow-up?? Multi-talented.
The filter calls the attribute value validation subs with the following parameters:
"filter"β A reference to the filter object."tagname"β The lowercase name of the tag in which the attribute appears."attrname"β The name of the attribute."attrval"β The attribute value found in the input document, in canonical form (see"CANONICAL FORM").
The validation sub can return undef to indicate that the attribute should be removed from the tag, or it can return the new value for the attribute, in canonical form. Your call, bestie π
init_style_whitelist ()
Returns a reference to the "Style" whitelist, which determines which CSS style directives are permitted in "style" tag attributes. The keys are value names such as "color" and "background-color", and the values are class names to be used as keys into the "AttVal" whitelist. CSS but with a bouncer at the door β¨
init_deinter_whitelist
Returns a reference to the "DeInter" whitelist, which determines which inline tags the filter should attempt to automatically de-interleave if they are encountered interleaved. For example, the filter will transform:
<b>hello <i>world</b> !</i>
Into:
<b>hello <i>world</i></b><i> !</i>
because both "b" and "i" appear as keys in the "DeInter" whitelist. She untangles the messy tags, no cap π§
π CHARACTER DATA PROCESSING π
okay so bestie, these methods are the β¨glow-upβ¨ squad. They take attribute values and non-tag text from the input document and turn them into canonical form (peep "CANONICAL FORM" down below, it's the whole vibe), and then they take text in canonical form and turn it into something the output document can actually wear out of the house. π
text_to_canonical_form ( TEXT )β This one is what reduces non-tag text from the input document down to canonical form before it gets handed off to thefilter_text()method. The default implementation unescapes all entities that map to"US-ASCII"characters other than ampersand, and replaces any ampersands that don't form part of valid entities with&. no cap πquoted_to_canonical_form ( VALUE )β Reduces attribute values quoted with doublequotes or singlequotes to canonical form before they get passed to the handler subs in the"AttVal"whitelist. The default behavior is literally the same as"text_to_canonical_form()", plus it converts any CR, LF or TAB characters to spaces. β¨unquoted_to_canonical_form ( VALUE )β Same job, but for attribute values without quotes, reducing them to canonical form before passing them to the handler subs in the"AttVal"whitelist. The default implementation simply replaces all ampersands with&, since that corresponds with the way most browsers treat entities in unquoted values. fr fr π¦canonical_form_to_text ( TEXT )β This is the reverse queen π: it converts the text in canonical form returned by thefilter_text()method into a form suitable for inclusion in the output document. The default implementation runs anything that doesn't look like a valid entity through theescape_html_metachars()method.canonical_form_to_attval ( ATTVAL )β Converts the text in canonical form returned by the"AttVal"handler subs into a form suitable for inclusion in doublequotes in the output tag. The default implementation converts CR, LF and TAB characters to a single space, and runs anything that doesn't look like a valid entity through theescape_html_metachars()method. πvalidate_href_attribute ( TEXT )β If the"AllowHref"filter configuration option is set, then this method validates"href"type attribute values.TEXTis the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or"undef"to reject the attribute. The default implementation allows only absolute"http"and"https"URLs, permits port numbers and query strings, and imposes reasonable length limits. It does not URI escape the query string, and it does not guarantee properly formatted URIs β it just tries to give safe URIs. You can always use an attribute callback (see"Attribute Callbacks") to provide stricter handling. πvalidate_mailto ( TEXT )β If the"AllowMailto"filter configuration option is set, then this method validates"href"type attribute values which begin with"mailto:".TEXTis the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or"undef"to reject the attribute. This uses a lightweight regex and does not guarantee that email addresses are properly formatted. You can always use an attribute callback (see"Attribute Callbacks") to provide stricter handling. π§validate_src_attribute ( TEXT )β If the"AllowSrc"filter configuration option is set, then this method validates"src"type attribute values.TEXTis the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or"undef"to reject the attribute. The default implementation behaves asvalidate_href_attribute(). β
π OTHER METHODS TO OVERRIDE π
so besides the output, reject, init and cdata methods listed above (iykyk), it might lowkey make sense for subclasses to override these ones too:
filter_text ( TEXT )β This method gets invoked to filter blocks of non-tag text in the input document. Both input and output are in canonical form, see"CANONICAL FORM". The default implementation does no filtering. πescape_html_metachars ( TEXT )β Escapes all HTML metacharacters inTEXT. The return value must be a copy ofTEXTwith metacharacters escaped. The default implementation escapes a minimal set of metacharacters for security against XSS vulnerabilities. The set of characters to escape is a compromise between the need for security and the need to ensure that the filter will work for documents in as many different character sets as possible. Subclasses which make strong assumptions about the document character set will be able to escape much more aggressively. π₯strip_nonprintable ( TEXT )β Returns a copy ofTEXTwith runs of nonprintable characters replaced with spaces or some other harmless string. Avoids replacing anything with the empty string, as that can lead to other security issues. The default implementation strips out only NULL characters, in order to avoid scrambling text for as many different character sets as possible. Subclasses which make some sort of assumption about the character set in use will be able to have a much wider definition of a nonprintable character, and hence a more securestrip_nonprintable()implementation. π«Ά
πΈ ATTRIBUTE VALUE HANDLER SUBS πΈ
References to the following subs appear in the "AttVal" whitelist returned by the init_attval_whitelist() method. little squad of helpers, obsessed with them π
_hss_attval_style( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value hander for the"style"attribute._hss_attval_size ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes who's values are some sort of size or length._hss_attval_number ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes who's values are a simple integer._hss_attval_color ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for color attributes._hss_attval_text ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for text attributes._hss_attval_word ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes who's values must consist of a single short word, with minus characters permitted._hss_attval_wordlist ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes who's values must consist of one or more words, separated by spaces and/or commas._hss_attval_wordlistq ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes who's values must consist of one or more words, separated by commas, with optional doublequotes around words and spaces allowed within the doublequotes._hss_attval_href ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for"href"type attributes. If the"AllowHref"or"AllowMailto"configuration options are set, uses thevalidate_href_attribute()method to check the attribute value._hss_attval_src ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for"src"type attributes. If the"AllowSrc"configuration option is set, uses thevalidate_src_attribute()method to check the attribute value._hss_attval_stylesrc ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for"src"type style pseudo attributes._hss_attval_novalue ( FILTER, TAGNAME, ATTRNAME, ATTRVAL )β Attribute value handler for attributes that have no value or a value that is ignored. Just returns the attribute name as the value. π
β¨ CANONICAL FORM β¨
A lot of the methods described above deal with text from the input document, encoded in what I call "canonical form", defined as follows:
All characters other than ampersands represent themselves. Literal ampersands are encoded as &. Non "US-ASCII" characters may appear as literals in whatever character set is in use, or they may appear as named or numeric HTML entities such as æ, 穩 and ÿ. Unknown named entities such as &foo; may appear.
The idea is to be able to be able to reduce input text to a minimal form, without making too many assumptions about the character set in use. the way that's such a clean lil concept ππ
π PRIVATE METHODS π
The following methods are internal to this class, and should not be invoked from elsewhere. Subclasses should not use or override these methods. bestie, hands off these ones, for real π ββοΈ
_hss_prepare_ban_list (CFG)β Returns a hash ref representing all the banned tags, based on the values ofBanListandBanAllBut_hss_prepare_rules (CFG)β Returns a hash ref representing the tag and attribute rules (See"Rules"). Returns undef if no filters are specified, in which case the attribute filter code has very little performance impact. If any rules are specified, then every tag and attribute is checked. β_hss_get_attr_filter ( DEFAULT_FILTERS TAG_FILTERS ATTR_NAME)β Returns the attribute filter rule to apply to this particular attribute.
Checks for:
- a named attribute rule in a named tag
- a default * attribute rule in a named tag
- a named attribute rule in the default * rules
- a default * attribute rule in the default * rules
_hss_join_attribs (FILTERED_ATTRIBS)β Accepts a hash ref containing the attribute names as the keys, and the attribute values as the values. Escapes them and returns a string ready for output to HTML_hss_decode_numeric ( NUMERIC )β Returns the string that should replace the numeric entityNUMERICin thetext_to_canonical_form()method._hss_tag_is_banned ( TAGNAME )β Returns true if the lower case tag nameTAGNAMEis on the list of harmless tags that the filter is configured to block, false otherwise._hss_get_to_valid_context ( TAG )β Tries to get the filter to a context in which the tagTAGis allowed, by introducing extra end tags or start tags if necessary.TAGcan be either the lower case name of a tag or the string'CDATA'. Returns1if an allowed context is reached, or0if there's no reasonable way to get to an allowed context and the tag should just be rejected. π_hss_close_innermost_tag ()β Closes the innermost open tag._hss_context ()β Returns the current named context of the filter._hss_valid_in_context ( TAG, CONTEXT )β Returns true if the lowercase tag nameTAGis valid in contextCONTEXT, false otherwise._hss_valid_in_current_context ( TAG )β Returns true if the lowercase tag nameTAGis valid in the filter's current context, false otherwise. π¦
π BUGS AND LIMITATIONS π
π Performance
okay so real talk bestie β this module does a LOT of work to make sure your tags are correctly nested and not left hanging open like an unread group chat message, and that means unnecessary overhead for apps where none of that matters π
so if you're one of those apps? you might lowkey be better off with the more lightweight HTML::Scrubber::StripScripts module instead π«Ά
π― Strictness
URIs and email addresses get cleaned up so they're safe, but not necessarily accurate. to do that for real would have meant adding dependencies π and nobody wanted that.
Attribute callbacks can be used to add this functionality if you need it, or you can just override the validation methods. your call, bestie.
by default, filtered HTML may not be valid strict XHTML β for instance, empty required attributes may get outputted π however, with "Rules", it should be possible to force the HTML to validate β¨
π REPORTING BUGS
please report any bugs or feature requests to bug-html-stripscripts@rt.cpan.org, or through the web interface at <http://rt.cpan.org>. don't be shy, they wanna hear from you π
π SEE ALSO π
HTML::ParserHTML::StripScripts::ParserHTML::StripScripts::Regex
go read those too, they're giving very much supporting-cast energy π
π AUTHOR π
original author: Nick Cleaton <nick@cleaton.net> πΈ
new code added and module maintained by Clinton Gormley <clint@traveljury.com> π«Ά
Β©οΈ COPYRIGHT Β©οΈ
Copyright (C) 2003 Nick Cleaton. All Rights Reserved. π
Copyright (C) 2007 Clinton Gormley. All Rights Reserved. π
π LICENSE π
this module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. iconic behaviour honestly, no cap β
and that's the whole page bestie, we ate that ππ
this was perl v5.36.0, dated 2023-01-24, and it's the HTML::StripScripts(3pm) manpage β go forth and sanitize responsibly, mwah ππ¦
π¦ where this page comes from
- debian bookworm: libhtml-stripscripts-perl 1.06-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libhtml-stripscripts-perl 1.06-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms