Open In App

Perl – Taint() Method

Last Updated : 25 Aug, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

In Perl, taint mode is a way to make our code more secure. It makes our program fussier about the data that it receives from an external source. The external source means the users, the file system, the environment, locale information, and some system calls. Taint mode was created for situations where security was important, like writing Perl programs that run root or CGI scripts. One should always use taint mode in their CGI script.
Some functions unexpectedly cause issues with bad data. It’s in our interest to ensure that the program is opening the file that we want it to open and not something else like a command provided by a mischievous user.

Use of Taint() Method

To turn the taint mode on we just use -T flag in our hashbang line.

#!/usr/bin/perl -wT 

Taint mode is used to keep track of the data coming from the user and avoids doing anything insecure with it. When it is enabled, every variable is monitored by Perl to check whether it is tainted or not. Tainted data is any data that comes from outside the code. 
Since it covers anything read from STDIN as well as all environment variables, it includes everything a CGI script receiver from a server. Thus abiding Perl from allowing any user-inputted value to be used in any of the Perl commands that affect external files.
Taint mode doesn’t allow data from outside our application to affect anything external to our application. 

Taint() is a function of the Scalar::Util module which can be used to check whether a variable is tainted or not and also the ones use of which would trigger an “Insecure dependency” message.

Sources of Taint()

Whenever there is a security breach in a given system, a program’s attack surface is checked first. The Attack surface is the part of the program which is exposed to an attacker.
Taint sources are the locations in a program where the data is read from a potentially risky source, including things like environmental variables, data, files, the network services, etc.

These unverified channels can be used by an attacker to trigger security vulnerabilities or cause problems to crash. Hence, to avoid that, Taint analysis takes place. It is an effective method to reduce the risk factors by allowing us to eliminate exploitable attack surfaces. 

 Removal of Taint()

Taint mode would’ve been so much restrictive if there wouldn’t have been a way to untaint our data. But of course, one doesn’t want to untaint the data without checking it for safety. Fortunately, there’s one command in Perl that allows us to accomplish both of these tasks. Perl doesn’t allow an expression involving tainted values to evaluate to an untainted value.  
So the only way to untaint a tainted variable is by performing a pattern matching operation on it and then extracting the matched substrings. If we match a variable with a regular expression, then the match variables that correspond to the matched parenthesis are untainted (like $1, $2, etc).

For example: If we want a variable to contain an e-mail address, then we can extract an untainted copy of the address in this way:

Perl




$mail_address=~/(\S+)\@([\w.-]+)/;
$untainted_address = "$1\@$2";


Explanation: In the above example the first parentheses surround (\w{1}[\w-.]*) matches one or more word characters, dashes, and periods with at least one-word character before it which does not contain dashes or periods. The parentheses make the first match gets assigned to $1 in Perl.
Then, an @ symbol is matched. Finally, the second set of parentheses ([\w-.]+) matches more word characters, dashes, and periods. The second match gets assigned to $2.
Thus, when the regular expression is successful, $1 will equal the username portion of the email address and $2 will equal the domain portion.
Perl considers these variables special because Perl basically believes that since these variables resulted from a regular expression that we had set up, that we have explicitly checked the data for validity in that regular expression. Thus, $1 and $2 are not considered tainted.

 Removal of Taint() from the environment

The issue of what data is tainted is dependent on the execution environment. For example, a database’s data may or may not be considered tainted. Perl has a DBI module that has the optional Taintout attribute which when set, makes all the data received from the database to be considered tainted. Similarly, there are specific sets of actions that shouldn’t be performed on tainted data which totally depend upon the execution environment. 

By default, importing symbols from the module turns on the taint checks. If one wishes to use this module without requiring taint checking (removing the taint from the environment), we can do it in the following ways :

  • By using (allow to run without -T).
# allow to run without -T
use Taint qw(allow_no_taint);    

# default import list
use Taint;                        
  • By not importing any symbols by explicitly passing an empty import list.
# importing no symbols
use Taint ();      

A basic program showing the implementation of the taint mode:

Perl




# Showing how a variable assigned to
# a tainted value gets tainted itself too:
  
#!/usr/bin/perl -T
  
my $arg = $ARGV[0];
my $file = "/home/foo/$arg";
  
open FOO, ">$file" or die $!;
print FOO "Yay\n";
  
close FOO;
exit 0;


This program will fail with the following error:

Insecure dependency in open while running with -T switch at ./test.pl line 9.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads