Sorry for the OT ness of this thread---

I spent the better part of the past 2 days trying to do a 1pass content filtering on xss attacks-- including flash. breaking down every piece of user input 2x wasn't nice on my server load.

I liked HTML::TagFilter, but it was making broken tags and I couldn't push the new tag defaults into it.

So thanks to Clinton Gormley for helping me decide on HTML::StripScripts::Parser -- which does facilitate tag defaults-- albeit in an awkward manner.

Clinton also made a nice skeleton of a wrapper for me to get a feeling for, saving me a large bit of the learning curve.

In any event, what follows is code that will rewrite user input of 'embed' tags for flash and replace in allowScriptAccess='never' and allowNetworking='internal' (object tags are not whitelisted for this )

if you let people embed flash onto your site, you will probably want to read the code below.

==========

use strict;
use warnings;

package Wrapper::StripScriptsParser;
use base 'HTML::StripScripts::Parser';
use HTML::Entities();

sub new {
    my $proto = shift;
    my $self = $proto->SUPER::new({
        Context=> 'Flow',
                AllowHref=> 1,
                AllowSrc=> 1,
    });
    $self->attr_encoded(0);
    return $self;
}
#override the context whitelist, and stick embed in there. we'll allow it.
sub init_context_whitelist {
        my      ( $self )= @_;
        my      $context_whitelist= $self->SUPER::init_context_whitelist() ;
                $context_whitelist->{'Flow'}{'embed'}= 'Inline';
                $context_whitelist->{'Context'}{'embed'}= 'Inline';
        return $context_whitelist;
}
        #override the attribute whitelist, and add custom cases for embed tags
sub init_attrib_whitelist {
        my      ( $self )= @_;
        my      $attrib_whitelist= $self->SUPER::init_attrib_whitelist() ;
                $attrib_whitelist->{'embed'}= {
                        src=> 'href',
                        type=>'word',
                        width=>'number',
                        height=>'number',
                        flashvars=>'text',
                        allowscriptaccess=>'allowscriptaccess',
                        allownetworking=>'allownetworking'
                };
        return $attrib_whitelist
}
#override the attribute value whitelist, and add custom classes for allowscriptaccess and allownetworking
sub init_attval_whitelist {
        my      ( $self )= @_;
        my      $attval_whitelist= $self->SUPER::init_attval_whitelist() ;
                $attval_whitelist->{'allowscriptaccess'}= 
\&attval_allowscriptaccess;
                $attval_whitelist->{'allownetworking'}= 
\&attval_allownetworking;
        return $attval_whitelist;
}
        #custom attribute value class.  cleans up flash embeds
sub attval_allowscriptaccess {
    my ($filter, $tagname, $attrname, $attrval) = @_;
        if ( $tagname eq 'embed' ) {
                return 'never';
        };
        return undef;
}
        #custom attribute value class.  cleans up flash embeds
sub attval_allownetworking {
    my ($filter, $tagname, $attrname, $attrval) = @_;
        if ( $tagname eq 'embed' ) {
                return 'internal';
        };
        return undef;
}
sub filter {
    my ( $self , $text )= @_;
    $self->parse($text);
    $self->eof;
    return $self->filtered_document;
}
sub reject_start {
    $_[0]->output(HTML::Entities::encode($_[1]));
}
sub reject_end {
    $_[0]->output(HTML::Entities::encode($_[1]));
}
sub reject_text {
    $_[0]->output(HTML::Entities::encode($_[1]));
}
sub reject_declaration {}
sub reject_comment {}
sub reject_process {}
sub __dump__ {
        my      ( $self )= @_;
        use Data::Dumper();
        print STDERR Data::Dumper->Dump( [$self] , [qw(self)] );
}

###############################################################

package main;

sub defang_text_ {
        my ( $text )= @_;
        my      $hss= Wrapper::StripScriptsParser->new();
        return $hss->filter($text);
}

my      $kill= <<EOF;
<b>HI</b>
A
<i>Hello</i>
<a href="http://a.com"; > hi</a>
<embed flashvars="a=f" allowscriptaccess="a" allowNetworking="internal" type="application/x-shockwave-flash" src="http://a.com/a.swf";></embed>
A1
<embed flashvars="b=asd" allowScriptAccess="never" allowNetworking="internal" type="application/x-shockwave-flash" src="http://a.com/a.swf";></embed>
B
<embed flashvars="c=kajsdlk@" allowScriptAccess="always" allowNetworking="sameDomain" type="application/x-shockwave-flash" src="http://b.com/b.swf"; />
C
<span />
D
<div />
EOF

print defang_text_( $kill );



###############################################################
1;

Reply via email to