File Coverage

blib/lib/Safe/Logs.pm
Criterion Covered Total %
statement 32 32 100.0
branch 1 2 50.0
condition n/a
subroutine 13 13 100.0
pod 0 1 0.0
total 46 48 95.8


line stmt bran cond sub pod time code
1             package Safe::Logs;
2              
3             require 5.005;
4 5     5   96973 use strict;
  5         12  
  5         202  
5 5     5   28 use warnings;
  5         78  
  5         179  
6 5     5   32 no warnings "redefine"; # We make this a few times
  5         9  
  5         200  
7              
8 5     5   115 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
  5         17  
  5         2027  
9              
10             $VERSION = '1.00';
11              
12             require Exporter;
13              
14             @ISA = qw(Exporter);
15              
16             %EXPORT_TAGS =
17             (
18             Carp => [ qw(carp croak confess cluck) ],
19             Syslog => [ qw(syslog) ],
20             );
21              
22             push @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}}
23             for grep { $_ ne 'all' } keys %EXPORT_TAGS;
24              
25             push @{$EXPORT_TAGS{all}}, 'protect';
26              
27             @EXPORT_OK = @{$EXPORT_TAGS{all}};
28              
29             =pod
30              
31             =head1 NAME
32              
33             Safe::Logs - Perl extension to avoid terminal emulator vulnerabilities
34              
35             =head1 SYNOPSIS
36              
37             use Safe::Logs; # Always override warn() and die()
38             use Safe::Logs qw(:all); # override eveything this module knows
39             use Safe::Logs qw(:Carp); # Only override Carp:: methods
40             use Safe::Logs qw(:Syslog); # Only override syslog()
41             use Safe::Logs qw(protect); # protect() for use on your own
42              
43             # Or combine a few
44             use Safe::Logs qw(:Syslog :Carp);
45              
46             =head1 DESCRIPTION
47              
48             As shown by the people at Digital Defense, there are a number of
49             vulnerabilities that can be remotely exploited in the terminal
50             emulators that are so common today. These vulnerabilities might allow
51             an attacker to execute arbitrary commands by a number of methods. The
52             easiest one, illustrated on
53             http://www.digitaldefense.net/labs/papers/Termulation.txt shows how to
54             compromise a remote host by sending carefully chosen requests that end
55             up in log files. It is then a matter of time for an innocent command
56             such as
57              
58             tail -f poisoned.log
59              
60             To wreak havoc in your system.
61              
62             You must C this module as the last in the list so that it can
63             override the methods exported from other modules.
64              
65             This module is a quick solution for this vulnerability. What it does
66             is very simple: It replaces ocurrences of the ESC character in the
67             output of any common logging mechanism such as C,
68             C, C and C.
69              
70             It does so by overriding the functions with a safer alternative so
71             that no code needs to be changed. Hopefully this will be followed by
72             better solutions from other Perl developers.
73              
74             Note that in order for this protection to be effective, this module
75             must be Cd as the last module (ie, after all the modules it can
76             override) in order for proper method replacement to occur.
77              
78             The protection can also be invoked by the C method, which
79             takes a list of arguments and returns the same list, with all ESC
80             characters safely replaced. This method is provided so that you can
81             call it by yourself.
82              
83             Tipically, you will want to issue an C after
84             the last module is Cd in your code, to automatically benefit from
85             the most common level of protection agains the attacks describen in
86             the paper.
87              
88             =cut
89              
90             # This is the core of our protection. Replace
91             # the escape character by an inocuous symbol
92              
93             sub _protect
94             {
95 16     16   29 my $msg = $_[0];
96 16 50       41 return $_[0] if ref $_[0];
97 16         52 $msg =~ s/\x1b/[esc]/g;
98 16         6860 return $msg;
99             }
100              
101             sub protect
102             {
103 9     9 0 31 return map { _protect $_ } @_;
  16         38  
104             }
105              
106             =pod
107              
108             The list of methods or functions that this module replaces are as
109             follows.
110              
111             =cut
112              
113             # This eases the task of replacing a method
114             # from other package
115              
116             sub _build
117             {
118 5     5   23 no strict 'refs';
  5         9  
  5         1595  
119 25     25   35 my $name = shift;
120 25         177 my $r_orig = \&$name;
121 25         98 $name =~ s/^.*:://;
122 25     4   154 *$name = sub { $r_orig->( protect @_ ) };
  4         2248  
123             }
124              
125             =pod
126              
127             =over
128              
129             =item C
130              
131             The standard Perl C.
132              
133             =cut
134              
135             *CORE::GLOBAL::warn = sub
136             {
137 1     1   1071 CORE::warn(protect @_);
138             };
139              
140             =pod
141              
142             =item C
143              
144             The standard Perl C.
145              
146             =cut
147              
148             *CORE::GLOBAL::die = sub
149             {
150 1     1   11 CORE::die(protect @_);
151             };
152              
153             =pod
154              
155             =item C
156              
157             =item C
158              
159             =item C
160              
161             =item C
162              
163             All the methods from C are overridden by this module.
164              
165             =cut
166              
167             _build('Carp::carp');
168             _build('Carp::croak');
169             _build('Carp::confess');
170             _build('Carp::cluck');
171              
172             =pod
173              
174             =item C
175              
176             =item C
177              
178             The known and common C calls are automatically overridden by
179             this module.
180              
181             =cut
182              
183             _build('main::syslog');
184              
185             =pod
186              
187             =item C
188              
189             =item C
190              
191             Calls from C are automatically overridden by this module.
192              
193             =cut
194              
195             my $clone_warn = \&warnings::warn;
196             my $clone_warnif = \&warnings::warn;
197              
198             *warnings::warn = sub
199             {
200 1     1   144 @_ = protect @_;
201 1         496 goto $clone_warn;
202             };
203              
204             *warnings::warnif = sub
205             {
206 1     1   915 @_ = protect @_;
207 1         278 goto $clone_warnif;
208             };
209              
210             1;
211             __END__