⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch19_07.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 19.6. Executing Commands Without Shell Escapes (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:45:35Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch19_01.htm"TITLE="19. CGI Programming"><LINKREL="prev"HREF="ch19_06.htm"TITLE="19.5. Making CGI Scripts Efficient"><LINKREL="next"HREF="ch19_08.htm"TITLE="19.7. Formatting Lists and Tables with HTML Shortcuts"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch19_06.htm"TITLE="19.5. Making CGI Scripts Efficient"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 19.5. Making CGI Scripts Efficient"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch19_01.htm"TITLE="19. CGI Programming"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch19_08.htm"TITLE="19.7. Formatting Lists and Tables with HTML Shortcuts"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 19.7. Formatting Lists and Tables with HTML Shortcuts"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch19-13007">19.6. Executing Commands Without Shell Escapes</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch19-pgfId-512">Problem<ACLASS="indexterm"NAME="ch19-idx-1000005448-0"></A><ACLASS="indexterm"NAME="ch19-idx-1000005448-1"></A><ACLASS="indexterm"NAME="ch19-idx-1000005448-2"></A><ACLASS="indexterm"NAME="ch19-idx-1000005448-3"></A></A></H3><PCLASS="para">You need to use a user's input as part of a command, but you don't want to allow the user to make the shell run other commands or look at other files. If you just blindly call the <CODECLASS="literal">system</CODE><ACLASS="indexterm"NAME="ch19-idx-1000005581-0"></A> function or <ACLASS="indexterm"NAME="ch19-idx-1000005583-0"></A><ACLASS="indexterm"NAME="ch19-idx-1000005583-1"></A>backticks on a single string containing a command line, the shell might be used to run the command. This would be unsafe.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch19-pgfId-518">Solution</A></H3><PCLASS="para">Unlike its single-argument version, the list form of the <CODECLASS="literal">system</CODE> function is safe from shell escapes. When the command's arguments involve user input from a form, never use this:</P><PRECLASS="programlisting">system(&quot;command $input @files&quot;);            # UNSAFE</PRE><PCLASS="para">Write it this way instead:</P><PRECLASS="programlisting">system(&quot;command&quot;, $input, @files);          # safer</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch19-pgfId-530">Discussion</A></H3><PCLASS="para">Because Perl was designed as a glue language, it's easy to use it to call other programs &nbsp;-  too easy, in some cases.</P><PCLASS="para">If you're merely trying to run a shell command but don't need to capture its output, it's easy enough to call <CODECLASS="literal">system</CODE> using its multiple argument form. But what happens if you're using the command in backticks or as part of a piped open? Now you have a real problem, because those don't permit the multiple argument form that <CODECLASS="literal">system</CODE> does. The solution is to manually <CODECLASS="literal">fork</CODE><ACLASS="indexterm"NAME="ch19-idx-1000005591-0"></A><ACLASS="indexterm"NAME="ch19-idx-1000005591-1"></A> and <CODECLASS="literal">exec</CODE> the child processes on your own. It's more work, but at least stray shell escapes won't be ruining your day.</P><PCLASS="para">It's safe to use backticks in a CGI script only if the arguments you give the program are purely internally generated, as in:</P><PRECLASS="programlisting">chomp($now = `date`);</PRE><PCLASS="para">But if the command within the backticks contains user-supplied input, perhaps like this:</P><PRECLASS="programlisting">@output = `grep $input @files`;</PRE><PCLASS="para">you have to be much more careful.</P><PRECLASS="programlisting">die &quot;cannot fork: $!&quot; unless defined ($pid = open(SAFE_KID, &quot;|-&quot;));if ($pid == 0) {    exec('grep', $input, @files) or die &quot;can't exec grep: $!&quot;;} else {    @output = &lt;SAFE_KID&gt;;    close SAFE_KID;                 # $? contains status}</PRE><PCLASS="para">This works because <CODECLASS="literal">exec</CODE>, like <CODECLASS="literal">system</CODE>, permits a calling convention that's proof against shell escapes. When passed a list, no shell is called, and so no escapes can occur.</P><PCLASS="para">Similar circumlocutions are needed when using <CODECLASS="literal">open</CODE> to start up a command. Here's a safe backtick or piped open for read. Instead of using this unsafe code:</P><PRECLASS="programlisting">open(KID_TO_READ, &quot;$program @options @args |&quot;);    # UNSAFE</PRE><PCLASS="para">Use this more complicated but safer code:</P><PRECLASS="programlisting"># add error processing as abovedie &quot;cannot fork: $!&quot; unless defined($pid = open(KID_TO_READ, &quot;-|&quot;));if ($pid) {   # parent   while (&lt;KID_TO_READ&gt;) {       # do something interesting   }   close(KID_TO_READ)               or warn &quot;kid exited $?&quot;;} else {      # child   # reconfigure, then   exec($program, @options, @args)  or die &quot;can't exec program: $!&quot;;}</PRE><PCLASS="para">Here's a safe piped open for writing. Instead of using this unsafe code:</P><PRECLASS="programlisting">open(KID_TO_WRITE, &quot;|$program $options @args&quot;);   # UNSAFE</PRE><PCLASS="para">Use this more complicated but safer code:</P><PRECLASS="programlisting">$pid = open(KID_TO_WRITE, &quot;|-&quot;);die &quot;cannot fork: $!&quot; unless defined($pid = open(KID_TO_WRITE, &quot;|-&quot;));$SIG{ALRM} = sub { die &quot;whoops, $program pipe broke&quot; };if ($pid) {  # parent   for (@data) { print KID_TO_WRITE $_ }   close(KID_TO_WRITE)              or warn &quot;kid exited $?&quot;;} else {     # child   # reconfigure, then   exec($program, @options, @args)  or die &quot;can't exec program: $!&quot;;}</PRE><PCLASS="para">At the point where the comment in the code says <CODECLASS="literal">reconfigure,</CODE> <CODECLASS="literal">then</CODE> you can put in any extra security measures you'd like. You're in the child process now, where changes won't propagate back to the parent. You can change environment variables, reset temporary user or group ID values, change directories or umasks, etc.</P><PCLASS="para">All this doesn't help you, of course, if your <CODECLASS="literal">system</CODE> call runs a setuid program that can be exploited with the data you give it. The mail program <EMCLASS="emphasis">sendmail</EM> is a setuid program commonly run from CGI scripts. Know the risks before you call <EMCLASS="emphasis">sendmail</EM> or any other setuid program.<ACLASS="indexterm"NAME="ch19-idx-1000005450-0"></A><ACLASS="indexterm"NAME="ch19-idx-1000005450-1"></A><ACLASS="indexterm"NAME="ch19-idx-1000005450-2"></A><ACLASS="indexterm"NAME="ch19-idx-1000005450-3"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch19-pgfId-632">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">system</CODE>, <CODECLASS="literal">exec</CODE>, and <CODECLASS="literal">open</CODE> functions in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A> and in <ICLASS="filename">perlfunc </I>(1); the section on <ACLASS="olink"HREF="../prog/ch06_03.htm">"Cooperating with Strangers"</A> in <ACLASS="olink"HREF="../prog/ch06_01.htm">Chapter 6</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ICLASS="filename">perlsec </I>(1); <ACLASS="xref"HREF="ch16_02.htm"TITLE="Gathering Output from a Program">Recipe 16.1</A>; <ACLASS="xref"HREF="ch16_03.htm"TITLE="Running Another Program">Recipe 16.2</A>; <ACLASS="xref"HREF="ch16_04.htm"TITLE="Replacing the Current Program with a Different One">Recipe 16.3</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch19_06.htm"TITLE="19.5. Making CGI Scripts Efficient"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 19.5. Making CGI Scripts Efficient"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch19_08.htm"TITLE="19.7. Formatting Lists and Tables with HTML Shortcuts"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 19.7. Formatting Lists and Tables with HTML Shortcuts"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">19.5. Making CGI Scripts Efficient</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">19.7. Formatting Lists and Tables with HTML Shortcuts</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -