http://qs321.pair.com?node_id=1191203


in reply to Use CGI to run a Perl script via web server

The documentation (at http://search.cpan.org/~pjf/IPC-System-Simple-1.25/lib/IPC/System/Simple.pm says, very plainly:

"...use the "capture()" command just like you'd use backticks. If there's an error, it will die with a detailed description of what went wrong."

So, I ask, what's that look like?


Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
  1. code
  2. verbatim error and/or warning messages
  3. a coherent explanation of what "doesn't work actually means.

Replies are listed 'Best First'.
Re^2: Use CGI to run a Perl script via web server
by suvajit123 (Initiate) on May 25, 2017 at 13:50 UTC

    Thanks everyone for all the comments. First of all, sorry to not mention "doesn't work". There is no security risk as this Link will only be used from within a different application. I am providing the script that needs to be executed over CGI via the webserver. It connects to LDAP and queries the username and some other details and with those creates a user account in another application (using system call). Reason is mentioned in the script comments.

    This script works fine with shift flag on line 11, by running the script manually like 'perl myscript.pl 212453261'.

    #!/usr/bin/perl use strict; use CGI; use Net::LDAP; use IPC::System::Simple qw(system capture); #create CGI query object to get the SSO from URL #my $query = new CGI; #my $sso = $query->param( "sso" ); my $sso = shift; if( $sso == "" ) { print "<html>"; print "<body>"; print "<h1>\n\n ERROR: Entered SSO is EMPTY! </h1>\n\n"; die "Empty SSO"; } else { print "<p>Processing: $sso</p>\n\n"; #LDAP server with port my $LDAP_SERVER = 'ldaps://ldap.hostname.com:636/ou=enterprise,dc=vds, +dc=logon'; my $LDAP_USER = 'bind_user'; my $LDAP_PWD = 'bindpwd'; #base tree to start searching my $BASE = "ou=users,ou=enterprise,dc=vds,dc=logon"; #Just search for the SSO - no group search required. my $FILTER = "(cn=$sso)"; #values to return - we need CN - SSO, First Name, Last Name, and Email my $ATRBS = ['cn', 'givenName', 'sn', 'mail']; #Start LDAP session and bind to LDAP my $ldap = Net::LDAP->new($LDAP_SERVER) or die "$@"; my $mesg = $ldap->bind($LDAP_USER, password=>$LDAP_PWD); my $result = $ldap->search(base => $BASE, filter => $FILTER, attrs => $ATRBS ); my @entries = $result->entries; #only one result should be returned if(@entries == 1) { print "\n\t<p>Found user $sso in LDAP</p>\n"; my $usr = $entries[0]; my $firstName = $usr->get_value('givenName'); my $lastName = $usr->get_value('sn'); my $email = $usr->get_value('mail'); print "\t<p>Creating User account in Application with \n Login name:- $sso \n FullName:- $firstName $lastName \n Email ID:- $email \n </p>\n\n"; #*********SYSTEM CALL ********** #script within a script both files in same path #This is required because the main script runs with ActiveState Extend +ed Perl v5.24.1 #Whereas cqperl runs with v5.16.1 (limited features), cannot use Activ +eState for this one. #*********SYSTEM CALL ********** system( "cqperl NewLdapUser.pl $sso $firstName $lastName $email" ); print "\n\t<p>Application account created for $sso - $firstName $last +Name - $email</p>\n\n"; } else { #error print "\t<h1>ERROR: Wrong SSO or User doesn't exist in OneAD LDAP</h +1>\n\n"; } $mesg = $ldap->unbind; } print "\t<h3>DONE!</h3>\n"; print "</body></html>";

    The output of the script is attached below. All I am looking for is to find out a way to parse the value from $sso = shift to just $sso using CGI.

    # perl myscript.pl 212453261 <p>Processing: 212453261</p> <p>Found user 212453261 in LDAP</p> <p>Creating User account in Application with Login name:- 212453261 FullName:- John Doe Email ID:- john.doe@mailhost.com </p> <p>Application account created for 212453261 - John Doe - john +.doe@mailhost.com</p> <h3>DONE!</h3>
      There is no security risk as this Link will only be used from within a different application.

      The road to Pwnsville (and thence to Bankruptcy) is littered with the corpses of devs who said precisely that.

      Use taint mode. Use it right now. Secure your code. Then secure it some more. Try to break it. Have others try to break it. Write security tests. Become known as the one in your team who writes the bulletproof code. Teach others what you have learned.

      There is no security risk as this Link will only be used from within a different application.

      Sorry, but those are famous last words. Getting security right is really hard. At the very least, you need to use the LIST form of system, i.e. system("cqperl","NewLdapUser.pl",$sso,$firstName,$lastName,$email);, and even better, since you're already using IPC::System::Simple, be explicit by using its systemx instead of system function. <update2> Plus, what hippo said, plus some kind of authentication for this script, and so on. </update2>

      ... creates a user account in another application (using system call). Reason is mentioned in the script comments.

      I admit I don't know cqperl (ClearQuest Perl?), but I'm not entirely convinced that whatever the Perl script NewLdapUser.pl is doing could not be done by your CGI script, especially given that your script is already making use of Net::LDAP.

      $sso == ""

      This is not doing what you want, as Perl would tell you, that's why you should always Use strict and warnings. Use eq instead and see the Basic debugging checklist.

      All I am looking for is to find out a way to parse the value from $sso = shift to just $sso using CGI.

      I'm not sure I understand the question, are you having trouble with getting the CGI parameters? I don't really see anything immediately wrong with my $sso = $query->param("sso");, have you tried narrowing down your script to only that part and attempting to debug it (using the links previously provided)?

      Update: Your code also seems to be potentially vulnerable to a Cross-site scripting (XSS) attack, see also this. Even if not, you should still use CGI's escapeHTML() function.

        Surely I will look into the security aspect, but at this moment the code fails because 'use CGI' cannot be clubbed with other things like 'use Net::LDAP' or 'IPC:System::Simple'. If I disable them I could execute it.

        But disabling them will take away the entire purpose of the script i.e. automated user management.

        #!/usr/bin/perl use strict; use CGI; use CGI::Carp; #create CGI query object to get the SSO from URL my $query = CGI->new; my $sso = $query->param("sso"); $sso = shift; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Application Management Sysyem</title>"; print "</head>"; if($sso eq "") { print "<h1>\n\nERROR: SSO is EMPTY!</h1>\n\n"; } else { use Proc::Background; print "<body>"; print "<h2>You have entered $sso</h2>"; print "</body>"; print "</html>"; }

        I really appreciate help.

      When accepting a parameter, you will need to know how the other side sends the parameter.

      If your other side sends the parameter as a CGI parameter, like:

      http://example.com/cgi-bin/myscript.pl?sso=212453261

      then you can read that parameter using the CGI methods:

      my $sso = $query->param('sso'); $sso = 0+ $sso; # convert to number, strip all leading zeroes

      But note that the "current directory" may not be what you think it is. When running other programs, you should use the full path to them and all filenames:

      #*********SYSTEM CALL ********** #script within a script both files in same path #This is required because the main script runs with ActiveState Extend +ed Perl v5.24.1 #Whereas cqperl runs with v5.16.1 (limited features), cannot use Activ +eState for this one. #*********SYSTEM CALL ********** system( "c:\\path\\to\\cqperl C:\\another\\path\\to\\NewLdapUser.pl $ +sso $firstName $lastName $email" );