perlsec.html

来自「perl教程」· HTML 代码 · 共 526 行 · 第 1/3 页

HTML
526
字号
<?xml version="1.0" ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!-- saved from url=(0017)http://localhost/ -->
<script language="JavaScript" src="../../displayToc.js"></script>
<script language="JavaScript" src="../../tocParas.js"></script>
<script language="JavaScript" src="../../tocTab.js"></script>
<link rel="stylesheet" type="text/css" href="../../scineplex.css">
<title>perlsec - Perl security</title>
<link rel="stylesheet" href="../../Active.css" type="text/css" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:" />
</head>

<body>

<script>writelinks('__top__',2);</script>
<h1><a>perlsec - Perl security</a></h1>
<p><a name="__index__"></a></p>

<!-- INDEX BEGIN -->

<ul>

	<li><a href="#name">NAME</a></li>
	<li><a href="#description">DESCRIPTION</a></li>
	<ul>

		<li><a href="#laundering_and_detecting_tainted_data">Laundering and Detecting Tainted Data</a></li>
		<li><a href="#switches_on_the____line">Switches On the &quot;#!&quot; Line</a></li>
		<li><a href="#taint_mode_and__inc">Taint mode and @INC</a></li>
		<li><a href="#cleaning_up_your_path">Cleaning Up Your Path</a></li>
		<li><a href="#security_bugs">Security Bugs</a></li>
		<li><a href="#protecting_your_programs">Protecting Your Programs</a></li>
		<li><a href="#unicode">Unicode</a></li>
		<li><a href="#algorithmic_complexity_attacks">Algorithmic Complexity Attacks</a></li>
	</ul>

	<li><a href="#see_also">SEE ALSO</a></li>
</ul>
<!-- INDEX END -->

<hr />
<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>perlsec - Perl security</p>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>Perl is designed to make it easy to program securely even when running
with extra privileges, like setuid or setgid programs.  Unlike most
command line shells, which are based on multiple substitution passes on
each line of the script, Perl uses a more conventional evaluation scheme
with fewer hidden snags.  Additionally, because the language has more
builtin functionality, it can rely less upon external (and possibly
untrustworthy) programs to accomplish its purposes.</p>
<p>Perl automatically enables a set of special security checks, called <em>taint
mode</em>, when it detects its program running with differing real and effective
user or group IDs.  The setuid bit in Unix permissions is mode 04000, the
setgid bit mode 02000; either or both may be set.  You can also enable taint
mode explicitly by using the <strong>-T</strong> command line flag. This flag is
<em>strongly</em> suggested for server programs and any program run on behalf of
someone else, such as a CGI script. Once taint mode is on, it's on for
the remainder of your script.</p>
<p>While in this mode, Perl takes special precautions called <em>taint
checks</em> to prevent both obvious and subtle traps.  Some of these checks
are reasonably simple, such as verifying that path directories aren't
writable by others; careful programmers have always used checks like
these.  Other checks, however, are best supported by the language itself,
and it is these checks especially that contribute to making a set-id Perl
program more secure than the corresponding C program.</p>
<p>You may not use data derived from outside your program to affect
something else outside your program--at least, not by accident.  All
command line arguments, environment variables, locale information (see
<a href="../../lib/Pod/perllocale.html">the perllocale manpage</a>), results of certain system calls (<a href="../../lib/Pod/perlfunc.html#item_readdir"><code>readdir()</code></a>,
<a href="../../lib/Pod/perlfunc.html#item_readlink"><code>readlink()</code></a>, the variable of <a href="../../lib/Pod/perlfunc.html#item_shmread"><code>shmread()</code></a>, the messages returned by
<a href="../../lib/Pod/perlfunc.html#item_msgrcv"><code>msgrcv()</code></a>, the password, gcos and shell fields returned by the
<code>getpwxxx()</code> calls), and all file input are marked as &quot;tainted&quot;.
Tainted data may not be used directly or indirectly in any command
that invokes a sub-shell, nor in any command that modifies files,
directories, or processes, <strong>with the following exceptions</strong>:</p>
<ul>
<li>
<p>Arguments to <a href="../../lib/Pod/perlfunc.html#item_print"><code>print</code></a> and <a href="../../lib/Pod/perlfunc.html#item_syswrite"><code>syswrite</code></a> are <strong>not</strong> checked for taintedness.</p>
</li>
<li>
<p>Symbolic methods</p>
<pre>
    <span class="variable">$obj</span><span class="operator">-&gt;</span><span class="variable">$method</span><span class="operator">(</span><span class="variable">@args</span><span class="operator">);</span>
</pre>
<p>and symbolic sub references</p>
<pre>
    <span class="operator">&amp;{</span><span class="variable">$foo</span><span class="operator">}(</span><span class="variable">@args</span><span class="operator">);</span>
    <span class="variable">$foo</span><span class="operator">-&gt;(</span><span class="variable">@args</span><span class="operator">);</span>
</pre>
<p>are not checked for taintedness.  This requires extra carefulness
unless you want external data to affect your control flow.  Unless
you carefully limit what these symbolic values are, people are able
to call functions <strong>outside</strong> your Perl code, such as POSIX::system,
in which case they are able to run arbitrary external code.</p>
</li>
</ul>
<p>For efficiency reasons, Perl takes a conservative view of
whether data is tainted.  If an expression contains tainted data,
any subexpression may be considered tainted, even if the value
of the subexpression is not itself affected by the tainted data.</p>
<p>Because taintedness is associated with each scalar value, some
elements of an array or hash can be tainted and others not.
The keys of a hash are never tainted.</p>
<p>For example:</p>
<pre>
    <span class="variable">$arg</span> <span class="operator">=</span> <span class="keyword">shift</span><span class="operator">;</span>               <span class="comment"># $arg is tainted</span>
    <span class="variable">$hid</span> <span class="operator">=</span> <span class="variable">$arg</span><span class="operator">,</span> <span class="string">'bar'</span><span class="operator">;</span>         <span class="comment"># $hid is also tainted</span>
    <span class="variable">$line</span> <span class="operator">=</span> <span class="operator">&lt;&gt;;</span>                 <span class="comment"># Tainted</span>
    <span class="variable">$line</span> <span class="operator">=</span> <span class="operator">&lt;</span><span class="variable">STDIN</span><span class="operator">&gt;;</span>            <span class="comment"># Also tainted</span>
    <span class="keyword">open</span> <span class="variable">FOO</span><span class="operator">,</span> <span class="string">"/home/me/bar"</span> <span class="keyword">or</span> <span class="keyword">die</span> <span class="variable">$!</span><span class="operator">;</span>
    <span class="variable">$line</span> <span class="operator">=</span> <span class="operator">&lt;</span><span class="variable">FOO</span><span class="operator">&gt;;</span>              <span class="comment"># Still tainted</span>
    <span class="variable">$path</span> <span class="operator">=</span> <span class="variable">$ENV</span><span class="operator">{</span><span class="string">'PATH'</span><span class="operator">}</span><span class="operator">;</span>       <span class="comment"># Tainted, but see below</span>
    <span class="variable">$data</span> <span class="operator">=</span> <span class="string">'abc'</span><span class="operator">;</span>              <span class="comment"># Not tainted</span>
</pre>
<pre>
    <span class="keyword">system</span> <span class="string">"echo $arg"</span><span class="operator">;</span>         <span class="comment"># Insecure</span>
    <span class="keyword">system</span> <span class="string">"/bin/echo"</span><span class="operator">,</span> <span class="variable">$arg</span><span class="operator">;</span>   <span class="comment"># Considered insecure</span>
                                <span class="comment"># (Perl doesn't know about /bin/echo)</span>
    <span class="keyword">system</span> <span class="string">"echo $hid"</span><span class="operator">;</span>         <span class="comment"># Insecure</span>
    <span class="keyword">system</span> <span class="string">"echo $data"</span><span class="operator">;</span>        <span class="comment"># Insecure until PATH set</span>
</pre>
<pre>
    <span class="variable">$path</span> <span class="operator">=</span> <span class="variable">$ENV</span><span class="operator">{</span><span class="string">'PATH'</span><span class="operator">}</span><span class="operator">;</span>       <span class="comment"># $path now tainted</span>
</pre>
<pre>
    <span class="variable">$ENV</span><span class="operator">{</span><span class="string">'PATH'</span><span class="operator">}</span> <span class="operator">=</span> <span class="string">'/bin:/usr/bin'</span><span class="operator">;</span>
    <span class="keyword">delete</span> <span class="variable">@ENV</span><span class="operator">{</span><span class="string">'IFS'</span><span class="operator">,</span> <span class="string">'CDPATH'</span><span class="operator">,</span> <span class="string">'ENV'</span><span class="operator">,</span> <span class="string">'BASH_ENV'</span><span class="operator">}</span><span class="operator">;</span>
</pre>
<pre>
    <span class="variable">$path</span> <span class="operator">=</span> <span class="variable">$ENV</span><span class="operator">{</span><span class="string">'PATH'</span><span class="operator">}</span><span class="operator">;</span>       <span class="comment"># $path now NOT tainted</span>
    <span class="keyword">system</span> <span class="string">"echo $data"</span><span class="operator">;</span>        <span class="comment"># Is secure now!</span>
</pre>
<pre>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">FOO</span><span class="operator">,</span> <span class="string">"&lt; $arg"</span><span class="operator">);</span>        <span class="comment"># OK - read-only file</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">FOO</span><span class="operator">,</span> <span class="string">"&gt; $arg"</span><span class="operator">);</span>        <span class="comment"># Not OK - trying to write</span>
</pre>
<pre>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">FOO</span><span class="operator">,</span><span class="string">"echo $arg|"</span><span class="operator">);</span>     <span class="comment"># Not OK</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">FOO</span><span class="operator">,</span><span class="string">"-|"</span><span class="operator">)</span>
        <span class="keyword">or</span> <span class="keyword">exec</span> <span class="string">'echo'</span><span class="operator">,</span> <span class="variable">$arg</span><span class="operator">;</span>   <span class="comment"># Also not OK</span>
</pre>
<pre>
    <span class="variable">$shout</span> <span class="operator">=</span> <span class="string">`echo $arg`</span><span class="operator">;</span>       <span class="comment"># Insecure, $shout now tainted</span>
</pre>
<pre>
    <span class="keyword">unlink</span> <span class="variable">$data</span><span class="operator">,</span> <span class="variable">$arg</span><span class="operator">;</span>         <span class="comment"># Insecure</span>
    <span class="keyword">umask</span> <span class="variable">$arg</span><span class="operator">;</span>                 <span class="comment"># Insecure</span>
</pre>
<pre>
    <span class="keyword">exec</span> <span class="string">"echo $arg"</span><span class="operator">;</span>           <span class="comment"># Insecure</span>
    <span class="keyword">exec</span> <span class="string">"echo"</span><span class="operator">,</span> <span class="variable">$arg</span><span class="operator">;</span>          <span class="comment"># Insecure</span>
    <span class="keyword">exec</span> <span class="string">"sh"</span><span class="operator">,</span> <span class="string">'-c'</span><span class="operator">,</span> <span class="variable">$arg</span><span class="operator">;</span>      <span class="comment"># Very insecure!</span>
</pre>
<pre>
    <span class="variable">@files</span> <span class="operator">=</span> <span class="operator">&lt;*.</span><span class="variable">c</span><span class="operator">&gt;;</span>             <span class="comment"># insecure (uses readdir() or similar)</span>
    <span class="variable">@files</span> <span class="operator">=</span> <span class="keyword">glob</span><span class="operator">(</span><span class="string">'*.c'</span><span class="operator">);</span>       <span class="comment"># insecure (uses readdir() or similar)</span>
</pre>
<pre>
    <span class="comment"># In Perl releases older than 5.6.0 the &lt;*.c&gt; and glob('*.c') would</span>
    <span class="comment"># have used an external program to do the filename expansion; but in</span>
    <span class="comment"># either case the result is tainted since the list of filenames comes</span>
    <span class="comment"># from outside of the program.</span>
</pre>
<pre>
    <span class="variable">$bad</span> <span class="operator">=</span> <span class="operator">(</span><span class="variable">$arg</span><span class="operator">,</span> <span class="number">23</span><span class="operator">);</span>          <span class="comment"># $bad will be tainted</span>
    <span class="variable">$arg</span><span class="operator">,</span> <span class="string">`true`</span><span class="operator">;</span>               <span class="comment"># Insecure (although it isn't really)</span>
</pre>

⌨️ 快捷键说明

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