App-HTTP_Proxy_IMP
view release on metacpan or search on metacpan
lib/App/HTTP_Proxy_IMP/IMP/CSRFprotect.pm view on Meta::CPAN
# PoC for CSRF protection
# see pod at the end for detailed description of the idea and references
use strict;
use warnings;
package App::HTTP_Proxy_IMP::IMP::CSRFprotect;
use base 'Net::IMP::HTTP::Request';
use fields (
'target', # target domain from request header
'origin', # domain from origin/referer request header
);
use Net::IMP qw(:DEFAULT :log);
use Net::IMP::Debug;
use Net::IMP::HTTP;
sub RTYPES { return (
IMP_REPLACE, # remove Cookie/Authorization header
IMP_LOG, # log if we removed something
IMP_DENY, # bad requests/responses
IMP_PASS,
)}
sub new_analyzer {
my ($class,%args) = @_;
my $self = $class->SUPER::new_analyzer(%args);
$self->run_callback(
# we will not modify response, but need to look at the response
# header to detect redirects. After the response header was seen
# this will be upgraded to IMP_PASS
[ IMP_PREPASS,1,IMP_MAXOFFSET]
);
return $self;
}
sub request_hdr {
my ($self,$hdr) = @_;
# modify if necessary, rest of request can be forwarded w/o inspection
my $len = length($hdr);
my @rv;
if ( defined( my $newhdr = _modify_rqhdr($self,$hdr))) {
push @rv, [ IMP_REPLACE,0,$len,$newhdr ];
}
$self->run_callback(@rv,[ IMP_PASS,0,IMP_MAXOFFSET ]);
}
sub response_hdr {
my ($self,$hdr) = @_;
# response header
_analyze_rphdr($self,$hdr);
$self->run_callback([ IMP_PASS,1,IMP_MAXOFFSET ]); # upgrade to IMP_PASS
}
{
# FIXME - should expire after a short time
# FIXME - for multi-process environments it needs to be shared
# between processes
# DELEGATION{FROM}{TO}: e.g. FROM delegated to TO by
# - having a POST request to TO with origin/referer FROM
# - having a redirect to TO in response from FROM
my %DELEGATION;
sub _delegate {
my ($origin,$target,$why) = @_;
if ( $DELEGATION{$origin}{$target} ) {
debug("refresh delegation $origin -> $target ($why)");
$DELEGATION{$origin}{$target} = 1;
} else {
debug("add delegation $origin -> $target ($why)");
$DELEGATION{$origin}{$target} = 1;
}
}
sub _delegation_exists {
my ($origin,$target) = @_;
return $DELEGATION{$origin}{$target};
}
}
# extract target and origin domain
# if they differ remove cookies and authorization infos unless we have
# an established trust between these domains
my $rx_host = qr{([\w\-.]+|\[[\da-fA-F:.]+\])};
my $rx_host_from_url = qr{^https?://$rx_host};
sub _modify_rqhdr {
( run in 0.865 second using v1.01-cache-2.11-cpan-d8267643d1d )