Last active
July 12, 2016 22:31
-
-
Save devd/1499684 to your computer and use it in GitHub Desktop.
Simple Tool to maybe rewrite extensions to be CSP compatible
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Run this on Extension Source code to make it inline-script-less | |
#perl ext2csp.pl <extdir>; | |
#where extdir is the directory with the manifest.json. | |
#This will make a inplace change: make a copy if you want it to work on a copy. | |
use strict; | |
use warnings; | |
use HTML::Parser (); | |
use HTML::Entities; | |
use File::Util; | |
use File::Basename; | |
use autodie; | |
use Digest::SHA qw(sha512_base64); | |
#TODO cleanup error handling and use GetOpt to make | |
# all these command line switches | |
#Change the last 0 to 1 if you want to use the hash src support | |
my ($extension_base_dir,$jsfolder,$jsbasename,$filectr,$newidbase,$usehashsrc) = ($ARGV[0],"js","addedForCSP",0,"_added_by_transform_",0); | |
my ($buffer,$idctr)=("",0); | |
die "No base directory specified" unless $extension_base_dir; | |
die "$extension_base_dir does not exist" unless (-d $extension_base_dir); | |
unless(-d "$extension_base_dir/$jsfolder"){ | |
mkdir "$extension_base_dir/$jsfolder"; | |
} | |
my $f = File::Util->new(); | |
my @hashsrcs=(); | |
foreach my $filename ($f->list_dir($extension_base_dir,"--recurse","--files-only")){ | |
next unless $filename =~ m/html?$/i; | |
$buffer="";$idctr=0; | |
my $parser = HTML::Parser->new(api_version=>3); | |
$parser->handler(default=>sub{$buffer.=$_[0];},"text"); | |
$parser->handler(start => \&startHandler,"tag,attr,text"); | |
$parser->parse_file($filename); | |
#ok now we remove the script tags | |
$buffer =~ s{<script\s*(?:type=['"]text/javascript['"])?\s*>(.+?)</script>}{scriptRewrite($1,$filename)}seg; | |
writeFile($filename,$buffer); | |
if (@hashsrcs) { | |
print "\n---- CSP hash src for $filename ----\n"; | |
print join(' ',@hashsrcs); | |
print "\n------------\n"; | |
@hashsrcs=(); | |
} | |
} | |
sub scriptRewrite{ | |
my ($contents,$origfile)=($_[0],basename($_[1])); | |
if ($usehashsrc) { | |
#TODO: testing needed | |
push @hashsrcs,"'sha512-".sha512_base64($contents)."'"; | |
return "<script type='text/javascript'>$contents</script>"; | |
} | |
$filectr++ while (-e "$extension_base_dir/$jsfolder/$jsbasename.$origfile.$filectr.js"); | |
my $newfilename="$jsfolder/$jsbasename.$origfile.$filectr.js"; | |
writeFile("$extension_base_dir/$newfilename",$contents); | |
return "<script type='text/javascript' src='/$newfilename'></script>"; | |
} | |
sub writeFile{ | |
my($filename,$contents)=($_[0],$_[1]); | |
open my $fh,">",$filename; | |
print $fh $contents; | |
close($fh); | |
} | |
sub startHandler{ | |
my ($tag,$attr,$origtext)=@_; | |
my $scriptcode=""; | |
my %attrhash = %$attr; | |
my %codehash=(); | |
my $id = ""; | |
{ | |
while(my ($key,$value) = each %attrhash){ | |
if($key =~ /^on(.*)$/i){ | |
$codehash{$1}=$value; | |
} | |
if($key =~ /^src$/i){ | |
if($value =~ /^http/){ | |
print "Found src in:",$origtext,"\n"; | |
} | |
} | |
$id = $value if($key eq 'id'); | |
} | |
} | |
unless(keys %codehash){ | |
#didn't find any inline handlers, bail out! | |
$buffer.=$origtext; return; | |
} | |
unless($id){ | |
# | |
$id="_added_by_transform_".$idctr++; | |
$attrhash{'id'}=$id; | |
} | |
{ | |
foreach my $key (keys %codehash){ | |
$scriptcode.="temp.addEventListener('".$key."',function(event){".$codehash{$key}."});\n"; | |
} | |
} | |
my $newtext=""; | |
if($scriptcode){ | |
$scriptcode = "<script>\n(function(){ var temp = document.getElementById('$id');\n".$scriptcode."\n})();\n</script>"; | |
$newtext = "<$tag "; | |
foreach my $key (keys %attrhash){ | |
next if $key =~ m/^on/; | |
$newtext .= " $key='".decode_entities($attrhash{$key})."' "; | |
} | |
$newtext.=" >"; | |
} | |
$buffer.="$newtext\n$scriptcode"; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment