22 Sept 2011

Net::LDAP::Security



Net::LDAP::Security

LDAP servers are vulnerable to LDAP query injection and DNS hijacking may lead to your query landing on the attacker's server. Attacker can sniff your username/password through your LDAP connection. Hacker may sniff your confidential information through LDAP connection.

So, How to prevent this? You can use Net::LDAPS and LDAP over TLS.

To know more about various security threats on LDAP and how to overcome those, read the document at Net::LDAP::Security

20 Sept 2011

Security Issues in Perl Scripts

Security Issues in Perl Scripts

system() and exec()

system() and exec() are potentially vulnerable to parameter tampering threat. Suppose if you have a CGI application which reads the the username parameter and displays the file he created. If you directly pass the parameter input to the system call it is a biggest security threat.

$user = param("user");
@out = system("cat /usr/upload/$user");

Imagine if some attacker is changing the param from "foe" to "test; cat /etc/passwd", your script will output the content of the user file along with the contents of /etc/passwd

As far as security is concerned, everything stated above with regard to the system() function applies to exec() too.

setuid scripts

Normally a Perl program runs with the privileges of the user who executed it. By making a script setuid, its effective user ID can be set to one that has access to resources to which the actual user does not (viz., to the owner ID of the file containing the program). The passwd program for example uses setuid to acquire writing permission to the system password file, thus allowing users to change their own passwords. Since programs that are executed via a CGI interface run with the privileges of the user who runs the web server (usually this is user 'nobody', who has very limited privileges), CGI programmers are often tempted to use the setuid technique to let their scripts perform tricks that they otherwise couldn't. This can be useful, but it can also be very dangerous. For one thing, if an attacker finds a way to exploit a weakness in the script, they won't only gain access to the system, but they will also have it with the privileges of the effective UID of that script (often the 'root' UID).

To avoid this, Perl programs should set the effective UID and GID to the real UID and GID of the process before any file manipulations:


     $> = $< # set effective user ID to real UID.
     $) = $( # set effective group ID to real GID.

and CGI scripts should always run with the lowest possible privilege.

Beware that just being careful in what you do inside your setuid script doesn't always solve the problem. Some operating systems have bugs in the kernel that make setuid scripts inherently insecure. For this, and other reasons, Perl automatically switches to a special security mode (taint mode) when it runs setuid or setgid scripts. We will discuss taint mode in our next article.

rand()
Generating random numbers on deterministic machines is a nontrivial problem. In security critical applications, random numbers are used intensely for many important tasks ranging from password generation to cryptography. For such purposes, it is vital that the generated numbers are as close to truly random as possible, making it difficult (but never impossible) for an attacker to predict future numbers generated by the algorithm. The Perl rand() function simply calls the corresponding rand(3) function from the standard C library. This routine is not very secure. The C rand() function generates a sequence of pseudorandom numbers based on some initial value called the seed. Given the same seed, two different instances of a program utilizing rand() will produce the same random values. In many implementations of C, and in all version of Perl before 5.004, if a seed is not explicitly specified, it is computed from the current value of the system timer, which is anything but random. Having some information about values produced by rand() at a given point and a sufficient amount of time, any self-respecting cracker can accurately predict the sequence of numbers that rand() will generate next, thus obtaining key knowledge necessary to compromise a system.

One (partial) solution to the rand() problem is to use one of the built-in random number generators on Linux systems -- /dev/random and /dev/urandom. Those are better sources of randomness then the standard library rand() function, but like anything else, they have their own imperfections. The difference between the two devices is that /dev/random stops supplying random numbers when its entropy pool runs out of randomness while /dev/urandom uses cryptography to generate new numbers when the entropy pool runs out. Another solution is to use a secure implementation of one of the more complicated cryptographic random number generators such as Yarrow.

13 Sept 2011

Perl 5.10 - Switch

 Perl 5.10 - Switch

Perl 5.10 introduces a native switch statement into the language. Like other features in Perl 5.10, we can enable it with the use feature pragma.
    use feature qw(switch);
It's also possible to enable all Perl 5.10 features with any of the following:
    use feature qw(:5.10);
    use 5.10.0;       # Requires perl v5.10.0 or later.
    use 5.010;        # Same, with nicer errors on older versions.
Perl's new switch feature is best demonstrated with an example. Let's take the classic guessing game, where the computer picks a number and our user needs to try and guess it.
    use strict;
    use warnings;
    use feature qw(switch say);
    # Pick our random number between 1 and 100
    my $secret = int(rand 100)+1;
    # An array of numbers guessed thus far
    my @guessed;
    say "Guess my number between 1-100";
    # Get each guess from the user
    while (my $guess = <STDIN>) {
        chomp $guess;
        # Check their guess using given/when
        given($guess) {
            when (/\D/)         { say "Give me an integer"; }
            when (@guessed)     { say "You've tried that";  }
            when ($secret)      { say "Just right!";  last; }
            when ($_ < $secret) { say "Too low";  continue; }
            when ($_ > $secret) { say "Too high"; continue; }
            # record the guess they've made
            push(@guessed,$_);
        }
    }
The heart of our program is the given/when block, which is enabled by the use of use feature qw(switch) at the top of our code. Let's look at each part in detail:
given($guess)
A given construct marks the start of our switch logic. It has the effect as assigning $_ to $guess for the duration of our given block. The changes to $_ are not visible outside of the given block (ie, they are lexical in scope).
when (/\D/)
when provided with a regular expression checks to see if $_ matches that regular expression. In our case, if our input contains non-digit characters, then we have something that doesn't look like an integer, and execute the associated block.
After a successful when match Perl will automatically break out of the given block unless told otherwise. In our case this repeats the loop asking the user for another guess.
when (@guessed)
In this second test we're asking whether $guess appears as a value in the @guessed. If it does we inform the user and go onto their next guess.
when ($secret)
This is a direct comparison. Is $guess the same value as $secret?. If so the player has guessed correctly! Using last allows us to break out of our while loop, ending the game.
when ($_ < $secret) and when ($_ > $secret)
These final two tests are simple comparisons. Remember that $_ contains the item we were given.
We've used continue for these statements to say that Perl should not break out of our given block on a successful match. This means that if the user guesses too low or too high, we will eventually evaluate the line:
    push(@guesses,$guess);
which remembers the guess as one we've already seen.
You can also use when with hashes (is $_ a key in the hash), subroutines (does the subroutine return true with $_ as an argument) and strings (tests for string equality). Furthermore, our given expression need not be merely a number or a string, we can also compare arrays, and hashes if we want to.
Finally, we can also set a default case, for when nothing has matched, although we have not shown it in our example.

foreach / when

If you've enabled use feature qw(switch then you can also use a foreach/when construct. Here's an example of tallying up the number of times we see cool things in a list:
    use feature qw(switch);
    foreach (@cool_things) {
        when (/pirate/)  { $pirate++ }
        when (/ninja/)   { $ninja++  }
        when (/robot/)   { $robot++  }
        say "$_ doesn't look cool...";
    }
If a when is activated, it automatically goes onto the next iteration of the foreach loop. Just like given/while, we can use the continue keyword to continue examining later options after a successful match.
It should be noted that foreach/when only works when using Perl's default $_ variable for iteration.

Lexical $_

In Perl 5.10 we can write:
    my $_;
This is allows us to do anything we like with $_, but without the possibility of changing $_ for code outside our current block. It's strongly recommended for subroutines using $_ in Perl 5.10 to avoid accidentally changing $_ for your caller.