File Coverage

lib/ThreatDetector/Handlers/ClientError.pm
Criterion Covered Total %
statement 21 21 100.0
branch 1 2 50.0
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 29 32 90.6


line stmt bran cond sub pod time code
1             package ThreatDetector::Handlers::ClientError;
2            
3 3     3   135167 use strict;
  3         5  
  3         97  
4 3     3   11 use warnings;
  3         4  
  3         188  
5 3     3   15 use Exporter 'import';
  3         4  
  3         84  
6 3     3   11 use JSON;
  3         7  
  3         14  
7 3     3   280 use Time::HiRes qw(gettimeofday);
  3         6  
  3         20  
8            
9             our $VERBOSE = 0;
10             our @EXPORT_OK = qw(handle_client_error get_client_error_events);
11             our @CLIENT_ERROR_EVENTS;
12             our $VERSION = '0.04';
13            
14             sub handle_client_error {
15 1     1 0 1046 my ($entry) = @_;
16 1         9 my ($sec, $micro) = gettimeofday();
17            
18             my $alert = {
19             timestamp => "$sec.$micro",
20             type => 'client_error',
21             ip => $entry->{ip},
22             method => $entry->{method},
23             uri => $entry->{uri},
24             status => $entry->{status},
25             user_agent => $entry->{user_agent},
26 1         10 };
27            
28 1         3 push @CLIENT_ERROR_EVENTS, $alert;
29 1 50       6 print encode_json($alert) . "\n" if $VERBOSE;
30             }
31            
32             sub get_client_error_events {
33 2     2 0 155464 return @CLIENT_ERROR_EVENTS;
34             }
35            
36             1;
37            
38             =head1 NAME
39            
40             ThreatDetector::Handlers::ClientError - Handler for HTTP 4xx client errors
41            
42             =head1 SYNOPSIS
43            
44             use ThreatDetector::Handlers::ClientError qw(handle_client_error);
45            
46             handle_client_error($entry);
47            
48             =head1 DESCRIPTION
49            
50             Prints a JSON alert for any Apache log entry resulting in a 4xx client error.
51             Useful for tracking broken links, unauthorized access, or misconfigured bots.
52            
53             =head1 AUTHOR
54            
55             Jason Hall
56            
57             =cut