miggel15 has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,

I must change passwords from customers with a cgi-script (html -> cgi-script -> change pw in /etc/passwd). I've create a short script but I'm not sure, if it's safty or not?

How it works: a user must enter his username, old password and his new password. First, I check if the old password matches his actual password. If so, I create with some commandline tools the password string for /etc/shadow.

#!/usr/bin/perl -w my $benutzername = "test"; my $passwordold = "password"; my $passwordnew = "freeSt19"; $pwd = (getpwnam($benutzername))[1]; #check, if the user knows his old password: if (crypt($passwordold, $pwd) ne $pwd) { die "Sorry...\n"; } else { print "ok\n"; } my $cryptedShadowString = `echo "$passwordnew"|openssl passwd -1 -stdi +n`; chomp($cryptedShadowString); my @Zeilen = (""); open(DATA, "</etc/shadow") || die "Datei mit E-Mails nicht gefunden\n" +; while(<DATA>) { push(@Zeilen,$_); } close(DATA); #Write the new shadow-file open(SHADOW, ">/etc/shadow"); for(@Zeilen){ if( $_ =~ m/^$benutzername/){ my @pwField = split( /:/, $_); $pwField[1] = $cryptedShadowString; print SHADOW $pwField[0].":".$pwField[1].":".$pwField[2].":".$ +pwField[3].":".$pwField[4].":".$pwField[5].":".$pwField[6].":".$pwFie +ld[7].":".$pwField[8]; }else{ print SHADOW $_; } } close(SHADOW); $mode = 0640; chmod $mode, "/etc/shadow"; `chown root /etc/shadow`; `chgrp shadow /etc/shadow`;
I will also implement a feature which disallows password changes for root and other system accouts. Would be nice to get some feedback!

Replies are listed 'Best First'.
Re: change unix password with cgi-script
by Perlbotics (Archbishop) on Jun 07, 2011 at 19:44 UTC

    Personally, I would have nightmares knowing to have such a this program out in the wild...

    Some suggestions if you cannot resign this task...

    • use strict; use warnings;
    • use taint-mode (-T flag)
    • when calling external programs, use absolute paths
    • check return status of external programs
    • convert this concept into a module or at least a sub with proper arguments and defined exit state
    • never ever operate on /etc/shadow directly. Create a new temp. version (perm: 0600). Make a backup of the former /etc/shadow. Rename new temp. version to /etc/shadow iff no error has occurred until this point in execution. Better: Use your OS tools to manipulate /etc/shadow instead of manipulating it directly.
    • check input (e.g. $benutzername = ".*" probably has an unpleasant effect...)
    • define ENVironment (e.g., PATH; LD_LIBRARY_PATH, etc.)
    • sudo might be useful
    • have a look at Security in CGI Programming and perlsec...
    • restrict pwd changes to certain users (good, you already planned that)
    • think about some load-limitation other other restriction that helps to reduce the rate an external attacker can crack accounts... (sleep 5 is cheap)
    • log every change (time, user, IP, etc.)
    • allow good passwords only (spawn a password-checker)
    • restrict access to certain IPs (e.g. intranet) only
    • see also: Passwd::Unix, Passwd::Unix::Alt, Expect, Expect-FAQ, How do I send a password to a command I start with Perl's Expect.pm, Changing passwords using Expect.pm through ssh on a large number (75) of systems
    • ...
    Good luck.

      You can believe me that I would really prefer to use the operating system tools for changing passwords but I didn't figure out how to use them (I have passwd without --stdin or something else)! This script will be run in our intranet, not on the internet! But of course, I have planned to implement a password validation (for problems like ".*"). Thanks for the hint to work with a shadow.temp file. This makes this a bit saver than it is designed now.

        This should handle the mechanics of updating the shadow file for you:

        system "/usr/sbin/usermod" => "--password", $cryptedShadowString, $benutzername;

        Good Day,
            Dean

Re: change unix password with cgi-script
by locked_user sundialsvc4 (Abbot) on Jun 07, 2011 at 19:56 UTC

    /me nods...

    Ahem... coding like that is a very good way to get yourself fired, and if you did such a thing in my shop I would cheerfully be the one to do it.   I would consider myself very lucky to have stopped you in time.

      I was going to disagree, but then I took a closer look at the actual code. Hacking together a script like this is wrong on so many levels I do not even know where to start. At least he's seeking advice on here.

      Elda Taluta; Sarks Sark; Ark Arks
      My deviantART gallery

Re: change unix password with cgi-script
by MidLifeXis (Monsignor) on Jun 08, 2011 at 16:54 UTC

    In addition to those items mentioned elsewhere in this thread, you also have a race condition (protect against two of these processes running at the same time), don't check for write errors on the new shadow file (think of a DOS by filling the filesystem before running this), ownership issues (unless you have ownership giveaway privs (or are running as root, which it appears the script assumes), you cannot do the chown, once you do the chown, you cannot do the chgrp), not verifying system calls (open, print), and a plethora of other issues associated with this script.

    I would second other suggestions to use the vendor supplied API functions (usermod as an example) to modify this information. There are many problems with your solution as provided.

    Also look at prior art. anlpasswd is an example of a password shim that I have used to perform some of your requirements. Last I checked, it was dated, however, so it may not be any better than an example.

    Update: Re-reading my response, I see that my response can possibly be read as "if you fix these things, then it is a good idea". Just so that there is no confusion, unless you are familiar with the deep magic, it is not a good idea to undertake this application. I would not be comfortable implementing this in a CGI script (or anywhere else) without many appropriate reviews, logging, audits, blah blah blah.

    --MidLifeXis

      I wasn't even going to touch the race condition! Good catch on the chown thing. Whole thing is a mess. And I guess the web server is running as root?? No evidence sudo is being used. Very, very risky.

      Elda Taluta; Sarks Sark; Ark Arks
      My deviantART gallery

Re: change unix password with cgi-script
by Argel (Prior) on Jun 08, 2011 at 16:54 UTC
    FYI, You can also use the Perl Expect module to drive shell commands if just using backticks or system calls is not working out for you. But this whole thing is a bad idea, especially given your your level of coding experience.

    Not only are you shelling out far, far too much but you have at least one huge security hole: 'echo "$passwordnew"'. Imagine if someone entered `/bin/rm -rf /` for the password!! Use single ticks in the echo command instead. (Update: added the bold italics)

    But really, I think you should bail on this. It's a bad idea. Maybe tell us why it has to be a web page --there might be another way to do this.

    Elda Taluta; Sarks Sark; Ark Arks
    My deviantART gallery