Broad Network


Tainted Scalar Values and Prevention in Perl

Perl Insecurities and Prevention – Part 3

Perl Course

Foreword: In this part of the series I talk about tainted scalar values and prevention in Perl.

By: Chrysanthus Date Published: 23 Nov 2015

Introduction

This is part 3 of my series, Perl Insecurities and Prevention. In this part of the series I talk about tainted scalar values and prevention in Perl. The verb, taint, means, to damage or spoil the quality of something. Tainted scalar value means input scalar value to a Perl program (script) that has wrong data or wrong code. You should have read the previous parts of the series before coming here, as this is a continuation.

In this series, once a user successfully sends wrong data or wrong code into a Perl program, we say the program has been hacked. The consequences of the hacking, such as financial benefic, false information, knowing credentials or destruction of program flow and other ills, are not really addressed. In this series, you learn about Perl insecure data expressions and how to prevent them from being exploited by hackers.

Prevention from hacking can be summarized as follows: Wrong data or wrong code, should not enter a program. While wrong data or wrong code is in the program, it should not disrupt the program flow. Wrong data or code should not leave the program for other destinations, because of wrong data inputted or wrong code inputted.

Taintedness is associated with a scalar value.

How can wrong scalar value affect a program flow adversely? A scalar value that has been assigned to a variable by the good programmer can receive a new value at run time from input. This new value can have wrong data or wrong code. A scalar variable that never had a value assigned to it, can still receive wrong data or wrong code.

What is a scalar value? A scalar value is a number or a string or a reference. A reference can be a reference to a scalar variable, a reference to an array, a reference to a hash or a reference to a function. A value can be a value of a scalar; an array consists of scalar values; a hash consists of key/value pairs. The argument to a function can be a scalar value, an array or a hash.

Can a hacker figure out the name of a Perl variable? – Yes: in two ways: Firstly, if the hacker has read permission to the Perl executable file, then he can open the file for reading and see the names of all the scalar variables in the program. Secondly, if the hacker does not have read permission, with some patience, he can work out (determine) the name of the variable because of the following reasons:

Any good programmer chooses a variable name that is easy to remember and that has meaning for the normal use of the variable. The hacker can use this scheme to work out the name of the variable. With some more patience, he can test for all the combinations of characters for the variable, because the hacker is a programmer like the good programmer; he knows the rules that govern the naming of the variable:

A scalar variable, begins with the $ symbol. This is followed by a letter or underscore. After that you can have a series of characters consisting of letters, underscores, or digits, in any order. Other variable types follow these rules, but may begin with @ or % or & or no symbol.

So a hacker can write a program to display all the possible combinations of characters for a variable. The output will take time, but he will still arrive at what the good programmer has chosen.

The solution is not to write a variable that is complex, difficult to remember and does not indicate its meaning. The solution is to lock all the exploiting means of the hacker; and that you learn in this series.

Effect of wrong Data Input or Wrong Code Input
If a good program is expecting an email address, it should not receive a URL. If it accepts a URL, the use of the input will be wrong. A wrong code input is input that will affect the program interpretation just to cause trouble, or to gain some selfish benefit for the hacker. Wrong data or wrong code can come in as scalar input. The problem of wrong code or wrong data is minimized using validation.

Validation is to check if the input you are expecting is the correct type of input. If you are expecting an email address, you should not have a URL. If you have a URL, do not use it; send a feedback message to the user (client) that the input was wrong, so that he can try again.

Validating a Number Input
If you are expecting a number, use the following code for validation:

use strict;

    my $variab;   # holds the supposed input number
    $variab =~ s/^\s+|\s+$//g;  # remove leading and trailing whitespaces
    my $ret = 0;

    sub isNumber
        {
            $ret = 0 if $variab =~ /\D/;  # means $variab holds a string
            $ret = 1 if $variab =~ /^\d+\z/; # testing for whole number
            $ret = 1 if $variab =~ /^[+-]?\d+\z/; # testing for integer
            $ret = 1 if $variab =~ /^-?(?:\d+\.?|\.\d)\d*\z/; # testing for real number
            $ret = 1 if $variab =~ /^[+-]?(?=\.?\d)\d*\.?\d*(?:e[+-]?\d+)?\z/i; # testing exponential real number
            if ($ret == 1)
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItNumber = isNumber($variab);  # true for number and false otherwise

Validating a Boolean Input
If you are expecting a Boolean input, use the following code for validation:

use strict;

    my $variab;   # holds the supposed Boolean input
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub istrue
        {
            if (($_[0] eq undef)||($_[0] eq "")||($_[0] eq "0"))
                {
                    return 0; #for not true
                }
            else
                {
                    return 1; #for true
                }
        }

    my $isItTrue =  istrue($variab);

Validating Email Input
If you are expecting an email address, use the following code for validation:

use strict;

    my $variab;    # holds the input address
    $variab =~ s/@/\\@/;  #replace @ with \@
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isEmail
        {
            my $temp = 0;
        
            if ($_[0] =~ /^[0-9a-zA-Z_\.-]{1,64}@[0-9a-zA-Z_-]{1,252}(\.[0-9a-zA-Z_\-]{2,4}){0,2}$/)
                {
                    $temp = 1;
                }

            if ($temp == 1)
                {
                    if (length($_[0]) <=254)
                        {
                            return 1;
                        }
                    else
                        {
                            return 0;
                        }                                    
                }
            else
                {
                    return 0;
                }
        }

    my $isItEmail =  isEmail($variab);

Validating URL Input
If you are expecting a URL, use the following code for validation:

use strict;

    my $variab;   # holds the supposed URL
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isURL
        {
            if ($_[0] =~ /^http|https:\/\/([0-9a-zA-Z_\-]{1,64}\.)?[0-9a-zA-Z_\-]{1,64}(\.[0-9a-zA-Z_\-]{2,4}){0,2}(:[0-9]{1,5})?(\/[0-9a-zA-Z_\-]{1,64}){0,64}([0-9a-zA-Z_\-]{1,64}(\.[a-zA-Z]{1,4})?)?(#[0-9a-zA-Z_\-]{1,64})?/)
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItURL = isURL($variab);

Validating IP Input
If you are expecting an IP address, use the following code for validation:

use strict;

    my $variab;  # holds the IP address
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isIP
        {
            if (($_[0] =~ /^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}$/) || ($_[0] =~ /^[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}:[\da-fA-F]{1,4}$/))
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItIP = isIP($variab);

Validating Short Text Input
If you are expecting short text, such as the first name of a person or the name of an object or characteristic of an object, use the following code for validation. Such text should contain only word characters, and may contain hyphen, @, dot, apostrophe or space. The binding operation for this is,

    $variab =~ /^[-\@\w.' ]+$/

The code is:

use strict;

    my $variab;  # holds the input
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isGoodText
        {
            if ($_[0] =~ /^[-\@\w.' ]+$/)
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItGoodText = isGoodText($variab);

Validating Input with Known Text Pattern
If you are expecting input of text with known pattern, you can use code similar to the following, with regex:

use strict;

    my $variab = "cork";  # holds the input
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isPattern
        {
            if ($_[0] =~ /c.rk/)
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItPattern = isPattern($variab);

String
In normal coding, text in single quotes does not expand or interpolates. In normal coding, text in double quotes expands and interpolates. Expansion of variable means that variable is replaced by its value.

The following code segment is dangerous if only the scalar value is wrong:

    my $var = 'her';
    print "I asked $var to come.";

Expansion will also take place with array and hash variables.

The following normal code, looking dangerous, calls a function within a double quoted string:

use strict;

    sub fn
        {
            my $var = "trouble";
            print "Danger! ";
            return \$var;
        }

    print "I asked ${&fn} to come.";

The output is:

    Danger! I asked trouble to come.

In order for a variable within double quotes to call a function, it has to be a dereferenced scalar, array or hash variable (using {} ). Within {} you can have code, even consisting of more than one statement separated by semicolons. In the case of scalar dereferencing, ${}, the code should return a scalar reference. In the case of array dereferencing, @{}, the code should return an array reference. In the case of hash dereferencing, %{}, the code should return a hash reference. If the code consists of many statements, the value of the last expression (statement) is returned.

When a text input from the console or file is received by the program, the text input comes as if it were within single quotes. So, there is no expansion or interpolation of variables or escape sequences. Even if you surround the console input with double quotes there will still be no expansion or interpolation. Input text from a file behaves as input text from the console. Input string from the console or file, is still tainted, because it may be wrong data (needs validation). To test whether it is a string, the regex is,

    $variab=~/\D/

If true it means the input is a string. You can use the following code:

use strict;

    my $variab;  # holds the input
    $variab =~ s/^\s*|\s*$//g;  #remove leading and trailing whitespaces

    sub isString
        {
            if ($_[0] =~ /\D/)
                {
                    return 1;
                }
            else
                {
                    return 0;
                }
        }

    my $isItString = isString($variab);

You will still need to test whether it is a URL, email, number, etc.

However, if the string is coming from a module, you should be careful. If the string in the module, is in single quotes, there will be no expansion or interpolation. If the string in the module is in double quotes, there will be expansion and interpolation. The expanded variable is referring to data or code in the module.

Note: it is possible to integrate the namespace of a module with the namespace of the main program.

The Issue Knowing Variable Name
If a hacker can know a variable name in your program, the obvious way for him to inject wrong code is as input argument or part of input argument to an eval function. He may also send in a wrong value to the variable if the variable takes input directly or indirectly. I will talk about the eval() function in a different part of the series.

Time to take a break. We stop here and continue in the next part.

Chrys

Related Links

Perl Basics
Perl Data Types
Perl Syntax
Perl References Optimized
Handling Files and Directories in Perl
Perl Function
Perl Package
Perl Object Oriented Programming
Perl Regular Expressions
Perl Operators
Perl Core Number Basics and Testing
Commonly Used Perl Predefined Functions
Line Oriented Operator and Here-doc
Handling Strings in Perl
Using Perl Arrays
Using Perl Hashes
Perl Multi-Dimensional Array
Date and Time in Perl
Perl Scoping
Namespace in Perl
Perl Eval Function
Writing a Perl Command Line Tool
Perl Insecurities and Prevention
Sending Email with Perl
Advanced Course
Miscellaneous Features in Perl
Perl Two-Dimensional Structures
Advanced Perl Regular Expressions
Designing and Using a Perl Module
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course

BACK NEXT

Comments

Become the Writer's Fan
Send the Writer a Message