File Coverage

blib/lib/Plack/Middleware/BlockHeaderInjection.pm
Criterion Covered Total %
statement 36 36 100.0
branch 6 6 100.0
condition 1 2 50.0
subroutine 10 10 100.0
pod 1 2 50.0
total 54 56 96.4


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   2051 use v5.8;
  3         18  
6              
7 3     3   18 use strict;
  3         6  
  3         59  
8 3     3   13 use warnings;
  3         6  
  3         85  
9              
10 3     3   502 use parent qw( Plack::Middleware );
  3         318  
  3         20  
11              
12 3     3   13396 use Plack::Util;
  3         8  
  3         72  
13 3     3   45 use Plack::Util::Accessor qw( logger status );
  3         6  
  3         20  
14              
15             our $VERSION = 'v1.0.1';
16              
17              
18             sub call {
19 6     6 1 57028 my ( $self, $env ) = @_;
20              
21             # cache the logger
22       2     $self->logger($env->{'psgix.logger'} || sub { })
23 6 100 50     27 unless defined $self->logger;
24              
25 6 100       168 $self->status(500) unless $self->status;
26              
27 6         49 my $res = $self->app->($env);
28              
29             Plack::Util::response_cb(
30             $res,
31             sub {
32 6     6   94 my $res = shift;
33              
34             # Sanity check headers
35              
36 6         14 my $hdrs = $res->[1];
37              
38 6         14 my $i = 0;
39 6         12 while ($i < @{$hdrs}) {
  16         66  
40 10         23 my $val = $hdrs->[$i+1];
41 10 100       37 if ($val =~ /[\n\r]/) {
42 2         6 my $key = $hdrs->[$i];
43 2         13 $self->log(
44             error => "possible header injection detected in ${key}" );
45 2         8 $res->[0] = $self->status;
46 2         13 Plack::Util::header_remove($hdrs, $key);
47             }
48 10         88 $i+=2;
49             }
50              
51             }
52 6         2267 );
53              
54             }
55              
56             # Note: ideas borrowed from XSRFBlock
57              
58              
59             sub log {
60 2     2 0 28 my ($self, $level, $msg) = @_;
61 2         15 $self->logger->({
62             level => $level,
63             message => "BlockHeaderInjection: ${msg}",
64             });
65             }
66              
67              
68             1;
69              
70             __END__