This file is indexed.

/usr/share/perl5/CGI/Untaint.pm is in libcgi-untaint-perl 1.26-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
package CGI::Untaint;

$VERSION = '1.26';

=head1 NAME 

CGI::Untaint - process CGI input parameters

=head1 SYNOPSIS

  use CGI::Untaint;

  my $q = new CGI;
  my $handler = CGI::Untaint->new( $q->Vars );
  my $handler2 = CGI::Untaint->new({
  	INCLUDE_PATH => 'My::Untaint',
  }, $apr->parms);

  my $name     = $handler->extract(-as_printable => 'name');
  my $homepage = $handler->extract(-as_url => 'homepage');

  my $postcode = $handler->extract(-as_postcode => 'address6');

  # Create your own handler...

  package MyRecipes::CGI::Untaint::legal_age;
  use base 'CGI::Untaint::integer';
  sub is_valid { 
    shift->value > 21;
  }

  package main;
  my $age = $handler->extract(-as_legal_age => 'age');

=head1 DESCRIPTION

Dealing with large web based applications with multiple forms is a
minefield. It's often hard enough to ensure you validate all your
input at all, without having to worry about doing it in a consistent
manner. If any of the validation rules change, you often have to alter
them in many different places. And, if you want to operate taint-safe,
then you're just adding even more headaches.

This module provides a simple, convenient, abstracted and extensible
manner for validating and untainting the input from web forms.

You simply create a handler with a hash of your parameters (usually
$q->Vars), and then iterate over the fields you wish to extract,
performing whatever validations you choose. The resulting variable is
guaranteed not only to be valid, but also untainted.

=cut

use strict;
use Carp;
use UNIVERSAL::require;

=head1 CONSTRUCTOR

=head2 new

  my $handler  = CGI::Untaint->new( $q->Vars );
  my $handler2 = CGI::Untaint->new({
  	INCLUDE_PATH => 'My::Untaint',
  }, $apr->parms);

The simplest way to contruct an input handler is to pass a hash of
parameters (usually $q->Vars) to new(). Each parameter will then be able
to be extracted later by calling an extract() method on it.

However, you may also pass a leading reference to a hash of configuration
variables.

Currently the only such variable supported is 'INCLUDE_PATH', which
allows you to specify a local path in which to find extraction handlers.
See L<LOCAL EXTRACTION HANDLERS>.

=cut

sub new {
	my $class = shift;

	# want to cope with any of:
	#  (%vals), (\%vals), (\%config, %vals) or (\%config, \%vals)
	#    but %vals could also be an object ...
	my ($vals, $config);

	if (@_ == 1) {

		# only one argument - must be either hashref or obj.
		$vals = ref $_[0] eq "HASH" ? shift: { %{ +shift } }

	} elsif (@_ > 2) {

		# Conf + Hash or Hash
		$config = shift if ref $_[0] eq "HASH";
		$vals   = {@_}

	} else {

		# Conf + Hashref or 1 key hash
		ref $_[0] eq "HASH" ? ($config, $vals) = @_ : $vals = {@_};
	}

	bless {
		__config => $config,
		__data   => $vals,
	} => $class;

}

=head1 METHODS

=head2 extract

  my $homepage = $handler->extract(-as_url => 'homepage');
  my $state = $handler->extract(-as_us_state => 'address4');
  my $state = $handler->extract(-as_like_us_state => 'address4');

Once you have constructed your Input Handler, you call the 'extract'
method on each piece of data with which you are concerned.

The takes an -as_whatever flag to state what type of data you
require. This will check that the input value correctly matches the
required specification, and return an untainted value. It will then call
the is_valid() method, where applicable, to ensure that this doesn't
just _look_ like a valid value, but actually is one.

If you want to skip this stage, then you can call -as_like_whatever
which will perform the untainting but not the validation.

=cut

sub extract {
	my $self = shift;
	$self->{_ERR} = "";
	my $val = eval { $self->_do_extract(@_) };
	if ($@) {
		chomp($self->{_ERR} = $@);
		return;
	}
	return $val;
}

sub _do_extract {
	my $self = shift;

	my %param = @_;

	#----------------------------------------------------------------------
	# Make sure we have a valid data handler
	#----------------------------------------------------------------------
	my @as = grep /^-as_/, keys %param;
	croak "No data handler type specified"        unless @as;
	croak "Multiple data handler types specified" unless @as == 1;

	my $field      = delete $param{ $as[0] };
	my $skip_valid = $as[0] =~ s/^(-as_)like_/$1/;
	my $module     = $self->_load_module($as[0]);

	#----------------------------------------------------------------------
	# Do we have a sensible value? Check the default untaint for this
	# type of variable, unless one is passed.
	#----------------------------------------------------------------------
	defined(my $raw = $self->{__data}->{$field})
		or die "No parameter for '$field'\n";

	# 'False' values get returned as themselves with no warnings.
	# return $self->{__lastval} unless $self->{__lastval};

	my $handler = $module->_new($self, $raw);

	my $clean = eval { $handler->_untaint };
	if ($@) {    # Give sensible death message
		die "$field ($raw) does not untaint with default pattern\n"
			if $@ =~ /^Died at/;
		die $@;
	}

	#----------------------------------------------------------------------
	# Are we doing a validation check?
	#----------------------------------------------------------------------
	unless ($skip_valid) {
		if (my $ref = $handler->can('is_valid')) {
			die "$field ($raw) does not pass the is_valid() check\n"
				unless $handler->$ref();
		}
	}

	return $handler->untainted;
}

=head2 error

  my $error = $handler->error;

If the validation failed, this will return the reason why.

=cut

sub error { $_[0]->{_ERR} }

sub _load_module {
	my $self = shift;
	my $name = $self->_get_module_name(shift());

	foreach
		my $prefix (grep defined, "CGI::Untaint", $self->{__config}{INCLUDE_PATH})
	{
		my $mod = "$prefix\::$name";
		return $self->{__loaded}{$mod} if defined $self->{__loaded}{$mod};
		eval {
			$mod->require;
			$mod->can('_untaint') or die;
		};
		return $self->{__loaded}{$mod} = $mod unless $@;
	}
	die "Can't find extraction handler for $name\n";
}

# Convert the -as_whatever to a FQ module name
sub _get_module_name {
	my $self = shift;
	(my $handler = shift) =~ s/^-as_//;
	return $handler;
}

=head1 LOCAL EXTRACTION HANDLERS

As well as as the handlers supplied with this module for extracting
data, you may also create your own. In general these should inherit from
'CGI::Untaint::object', and must provide an '_untaint_re' method which
returns a compiled regular expression, suitably bracketed such that $1
will return the untainted value required.

e.g. if you often extract single digit variables, you could create 

  package My::Untaint::digit;

  use base 'CGI::Untaint::object';

  sub _untaint_re { qr/^(\d)$/ }

  1;

You should specify the path 'My::Untaint' in the INCLUDE_PATH
configuration option.  (See new() above.)

When extract() is called CGI::Untaint will also check to see if you have
an is_valid() method also, and if so will run this against the value
extracted from the regular expression (available as $self->value).

If this returns a true value, then the extracted value will be returned,
otherwise we return undef. 

is_valid() can also modify the value being returned, by assigning 
  $self->value($new_value)

e.g. in the above example, if you sometimes need to ensure that the
digit extracted is prime, you would supply:

  sub is_valid { (1 x shift->value) !~ /^1?$|^(11+?)\1+$/ };

Now, when users call extract(), it will also check that the value
is valid(), i.e. prime:

  my $number = $handler->extract(-as_digit => 'value');

A user wishing to skip the validation, but still ensure untainting can
call 

  my $number = $handler->extract(-as_like_digit => 'value');

=head2 Test::CGI::Untaint

If you create your own local handlers, then you may wish to explore
L<Test::CGI::Untaint>, available from the CPAN. This makes it very easy
to write tests for your handler. (Thanks to Profero Ltd.)

=head1 AVAILABLE HANDLERS

This package comes with the following simplistic handlers: 

  printable  - a printable string
  integer    - an integer
  hex        - a hexadecimal number (as a string)

To really make this work for you you either need to write, or download
from CPAN, other handlers. Some of the handlers available on CPAN include:

  asin         - an Amazon ID
  boolean      - boolean value
  country      - a country code or name
  creditcard   - a credit card number
  date         - a date (into a Date::Simple)
  datetime     - a date (into a DateTime)
  email        - an email address
  hostname     - a DNS host name
  html         - sanitized HTML
  ipaddress    - an IP address
  isbn         - an ISBN
  uk_postcode  - a UK Postcode
  url          - a URL
  zipcode      - a US zipcode

=head1 BUGS

None known yet.

=head1 SEE ALSO

L<CGI>. L<perlsec>. L<Test::CGI::Untaint>.

=head1 AUTHOR

Tony Bowden

=head1 BUGS and QUERIES

Please direct all correspondence regarding this module to:
  bug-CGI-Untaint@rt.cpan.org

=head1 COPYRIGHT and LICENSE

Copyright (C) 2001-2005 Tony Bowden. All rights reserved.

This module is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;