File Coverage

blib/lib/Plack/Middleware/BlockHeaderInjection.pm
Criterion Covered Total %
statement 33 33 100.0
branch 6 6 100.0
condition 1 2 50.0
subroutine 9 9 100.0
pod 1 2 50.0
total 50 52 96.1


line stmt bran cond sub pod time code
1             package Plack::Middleware::BlockHeaderInjection;
2              
3             # ABSTRACT: block header injections in responses
4              
5 3     3   2116 use v5.12;
  3         18  
6 3     3   17 use warnings;
  3         8  
  3         87  
7              
8 3     3   443 use parent qw( Plack::Middleware );
  3         307  
  3         16  
9              
10 3     3   12882 use Plack::Util;
  3         7  
  3         70  
11 3     3   16 use Plack::Util::Accessor qw( logger status );
  3         6  
  3         18  
12              
13             our $VERSION = 'v1.1.1';
14              
15              
16             sub call {
17 6     6 1 57146 my ( $self, $env ) = @_;
18              
19             # cache the logger
20       2     $self->logger( $env->{'psgix.logger'} || sub { } )
21 6 100 50     22 unless defined $self->logger;
22              
23 6 100       160 $self->status(500) unless $self->status;
24              
25 6         53 my $res = $self->app->($env);
26              
27             Plack::Util::response_cb(
28             $res,
29             sub {
30 6     6   134 my $res = shift;
31              
32             # Sanity check headers
33              
34 6         13 my $hdrs = $res->[1];
35              
36 6         11 my $i = 0;
37 6         11 while ( $i < @{$hdrs} ) {
  16         65  
38 10         23 my $val = $hdrs->[ $i + 1 ];
39 10 100       36 if ( $val =~ /[\n\r]/ ) {
40 2         5 my $key = $hdrs->[$i];
41 2         11 $self->log( error => "possible header injection detected in ${key}" );
42 2         9 $res->[0] = $self->status;
43 2         13 Plack::Util::header_remove( $hdrs, $key );
44             }
45 10         70 $i += 2;
46             }
47              
48             }
49 6         2163 );
50              
51             }
52              
53             # Note: ideas borrowed from XSRFBlock
54              
55              
56             sub log {
57 2     2 0 5 my ( $self, $level, $msg ) = @_;
58 2         29 $self->logger->(
59             {
60             level => $level,
61             message => "BlockHeaderInjection: ${msg}",
62             }
63             );
64             }
65              
66              
67             1;
68              
69             __END__