Secure Perl Programming

 

Peter Haworth

pmh@cpan.org

IOP Publishing Ltd.

 

O'Reilly Open Source Convention July 22-26, 2002

Outline

Introduction

Don't trust the user

Robustness

Tainting

Child processes

Child processes - Safe pipes

  • Unsafe
      open my $fh,"| mail $user" or die;
      print $fh $msg;
      close $fh or die;
  • Safe, but invokes the shell
      open my $fh,"| /bin/mail \Q$user\E" or die;
      print $fh $msg;
      close $fh or die;
  • Safe and efficient
      defined(my $pid=open my $fh,'|-') or die;
      if(!$pid){
        exec '/bin/mail',$user;
        die "Can't exec";
      }
      print $fh $msg;
      close $fh or die;
  • Perl 5.8.0
      open my $fh,'|-','/bin/mail',$user or die;
      print $fh $msg;
      close $fh or die;

Validate all user input

Filenames

  • Poison null byte
      # Unsafe if $filename eq "hello.unsafe\0"
      open my $fh, '<', "$filename.safe"
        or die "Invalid filename";
      # Safer
      die "Invalid filename"
        if $filename =~ /\0/;
      open my $fh, '<', "$filename.safe"
        or die "Invalid filename";
  • Don't allow paths
      # Prevents ../../../../etc/passwd
      die "Invalid filename"
        if $filename =~ m#/#;
  • Allow safe; don't disallow unsafe
      die "Invalid filename"
        unless $filename =~ /^\w+$/;

Magic open()

Web applications - HTML forms

Web applications - Cookies

Safe sequence numbers

Not like this!
  my $seqn=$dbh->selectall_arrayref(q(
    select max(key_field)
    from table1
  ))->[0][0]+1;
Let the database do it for you
  my $seqn=$dbh->selectall_arrayref(q(
    select nextval('name_of_sequence')
  ))->[0][0];
Or do it yourself
  sub nextval{
    my($name)=@_;
    $name=~/^\w+$/ or die "Bad sequence name";
    my $fh=IO::File->new("/path/$name",O_RDWR|O_CREAT)
                           or die "Can't open: $!";
    flock $fh,LOCK_EX      or die "Can't lock: $!";
    chomp(my $next=<$fh>);
    ++$next;
    seek $fh,0,0           or die "Can't rewind: $!";
    print $fh "$next\n"    or die "Can't write: $!";
    close $fh              or die "Can't close: $!";
    return $next;
  }

Dynamic method names

$obj -> $meth ()

Conclusion

References

http://www.dwheeler.com/secure-programs/
Secure programming for Linux/Unix

 
http://www.w3.org/Security/Faq/
WWW Security FAQ

 
perldoc perlsec
Perl documentation on tainting

 
$CPAN/authors/id/P/PM/PMH/secprog-tpc2002.tgz
Latest version of these slides and speaker's notes