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

📄 ch11.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 3 页
字号:
dangerous variable paths. Of course, testing and being a little

on the paranoid side does help in flushing out security holes.

Ask yourself this question when testing scripts for security violations:

If I were a hacker, is there any way I can use this script to

break into my system?

<H2><A NAME="SomeTipsonMakingScriptsSecure"><FONT SIZE=5 COLOR=#FF0000>Some

Tips on Making Scripts Secure</FONT></A></H2>

<P>

The first thing to do when making a Perl script secure is to set

the effective user and group <TT><FONT FACE="Courier">id</FONT></TT>s

to the same as the real user and group <TT><FONT FACE="Courier">id</FONT></TT>s

of the process. This is done with the following lines, which should

be placed before any calls that manipulate files or directories:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$&gt; = $&lt;   # set effective user

Ids to real id.<BR>

$) = $(   # set group id to real id.</FONT></TT>

</BLOCKQUOTE>

<P>

Next, make sure that you reset at least these two environment

variables to a known value:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$ENV{'PATH'} = '/bin:/usr/bin';<BR>

$ENV{'IFS'} = '' if $ENV{'IFS'} ne '';</FONT></TT>

</BLOCKQUOTE>

<P>

Force the path to a known value so that unknown programs cannot

be inserted and executed from writable locations in the path.

The <TT><FONT FACE="Courier">IFS</FONT></TT> field is set to a

<TT><FONT FACE="Courier">null</FONT></TT> value to prevent any

misuse of inter-field characters.

<P>

Another thing to do is to explicitly create your own strings rather

than use strings expanded by the shell. If you are making a call

to <TT><FONT FACE="Courier">exec</FONT></TT>, pass each argument

explicitly, not as a complete string that could have been tainted

by the caller's shell program. For example, avoid the use of a

statement like this:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">exec 'myprog @arglist';</FONT></TT>

</BLOCKQUOTE>

<P>

Instead, use statements like this one:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">exec 'myprog', 'arg1', 'arg2', 'arg3';</FONT></TT>

</BLOCKQUOTE>

<P>

This prevents someone from sending more than one argument to a

program. You can use the Perl <TT><FONT FACE="Courier">system()</FONT></TT>,

which like <TT><FONT FACE="Courier">exec()</FONT></TT>, calls

without invoking a shell by supplying more than one argument:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">system('/usr/bin/ls', '-a');</FONT></TT>

</BLOCKQUOTE>

<P>

Pipes are a potential leak in systems, as well. You can use the

<TT><FONT FACE="Courier">open()</FONT></TT> call to get the same

functionality as <TT><FONT FACE="Courier">popen()</FONT></TT>

(but without starting a shell) with a call of the form:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">open(FH, '|-') || exec(&quot;program&quot;,

$arg1, $arg2);</FONT></TT>

</BLOCKQUOTE>

<P>

Finally, whenever you are dealing with pathnames, be sure to check

for the <TT><FONT FACE="Courier">..</FONT></TT> component. The

seemingly safe line to get <TT><FONT FACE="Courier">man</FONT></TT>

pages via HTML pages can be exploited, too. Consider this line:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">open(MANPAGE, &quot;/usr/man/man1/$filename$section&quot;);</FONT></TT>

</BLOCKQUOTE>

<P>

You can get to the password file if the user-supplied filename

has <TT><FONT FACE="Courier">$filename</FONT></TT> set to <TT><FONT FACE="Courier">../../../etc/passwd</FONT></TT>

and <TT><FONT FACE="Courier">$section = &quot; &quot;</FONT></TT>.

Check to see whether the filename has <TT><FONT FACE="Courier">..</FONT></TT>

in it for abuse at the server side. Don't process filenames that

make you traverse upwards. Use explicit, full pathnames wherever

possible.

<P>

There is a time lag between the point where a kernel determines

whether a script is <TT><FONT FACE="Courier">setuid</FONT></TT>

and the time the Perl interpreter executes the script. The script

could be a symbolic link and therefore can be modified during

this time interval. It's hard to do, but not impossible.

<P>

Some kernels do not allow <TT><FONT FACE="Courier">setuid</FONT></TT>

scripts, period. This is somewhat too limiting in most systems

because such a blanket order prevents you from doing even legitimate

tasks. The other route is to simply ignore the <TT><FONT FACE="Courier">setuid</FONT></TT>

bit setting in the kernel and run only at user level. You can

still use the built-in Perl mechanism to emulate the <TT><FONT FACE="Courier">setuid</FONT></TT>

behavior. However, if the kernel allows you to run <TT><FONT FACE="Courier">setuid</FONT></TT>

scripts as root, and the bit is set, Perl will display a warning

message about security. At this point, either disable the Perl

script or call it from a C program.

<H2><A NAME="ThePerlSafepmModule"><FONT SIZE=5 COLOR=#FF0000>The

Perl </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">Safe.pm</FONT></TT><FONT SIZE=5 COLOR=#FF0000>

Module</FONT></A></H2>

<P>

The Perl <TT><FONT FACE="Courier">Safe.pm</FONT></TT> module is

written by Malcolm Beattie (<TT><FONT FACE="Courier">mbeattie@sable.ox.ac.uk</FONT></TT>)

and is designed to test Perl code to see how it will work in the

real world. The <TT><FONT FACE="Courier">Safe</FONT></TT> extension

module creates two &quot;compartments&quot; in which code can

be tested. A <I>compartment</I> is simply a known environment

that does not allow system access.

<P>

A compartment has a name space other than <TT><FONT FACE="Courier">main::</FONT></TT>.

Any variables declared in the new name space cannot access variables

outside this name space. Added to this name space wrapper is the

notion of an operator mask. Basically, an operator mask is an

array of elements, each with a value of <TT><FONT FACE="Courier">0</FONT></TT>

or <TT><FONT FACE="Courier">1</FONT></TT>, indicating which operators

Perl can use and which operators it cannot use. Therefore, most

global variables are shielded from the wrapped section of code

in a <TT><FONT FACE="Courier">Safe</FONT></TT> object.

<P>

The special variables <TT><FONT FACE="Courier">$_</FONT></TT>,<B>

</B><TT><FONT FACE="Courier">@_</FONT></TT>,<B> </B><TT><FONT FACE="Courier">_</FONT></TT>,

and <TT><FONT FACE="Courier">%_</FONT></TT> are still available

to the wrapped section of code. In fact, these special variables

are also shared between different enclosed name spaces. The requirement

to allow these variables to be shared is necessary to allow parameter

passing between subroutines in a wrapped code section.

<H3><A NAME="UsingtheSafeClass">Using the <TT><FONT SIZE=4 FACE="Courier">Safe</FONT></TT><FONT SIZE=4>

Class</FONT></A></H3>

<P>

To use the <TT><FONT FACE="Courier">Safe</FONT></TT> class, you

have to take the following steps:

<UL>

<LI><FONT COLOR=#000000>Create a compartment.</FONT>

<LI><FONT COLOR=#000000>Perform unsafe operations using the compartment.</FONT>

<LI><FONT COLOR=#000000>When unsafe operations are over, delete

the partition.</FONT>

</UL>

<P>

A new compartment is created using a new <TT><FONT FACE="Courier">Safe</FONT></TT>

object. Both arguments to the call to create a <TT><FONT FACE="Courier">Safe</FONT></TT>

object are optional in the syntax shown here:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$cpt = new Safe( $namespace, $mask );</FONT></TT>

</BLOCKQUOTE>

<P>

where<TT><FONT FACE="Courier"> $namespace</FONT></TT> is the root

name space to use instead of <TT><FONT FACE="Courier">main::</FONT></TT>.

If you do not specify this name space, the default name of <TT><FONT FACE="Courier">Safe::Root000000000</FONT></TT>

is used. The zeroes in the number portion of the default name

space are incremented on the creation of every new name space

object. This way you can have separate name spaces for separate

modules.

<P>

The operator mask to use is simply an array of <TT><FONT FACE="Courier">MAXO</FONT></TT>

integers. The value of <TT><FONT FACE="Courier">MAXO</FONT></TT>

is the number of operators in your Perl interpreter. Each element

of the array maps to a Perl operator and has the value of <TT><FONT FACE="Courier">0</FONT></TT>

or <TT><FONT FACE="Courier">1</FONT></TT>. If an element is <TT><FONT FACE="Courier">1</FONT></TT>,

the Perl operator is not permitted to execute; a value of <TT><FONT FACE="Courier">0</FONT></TT>

for an element allows Perl to execute that operator. Therefore,

by judiciously setting the mask elements, you can specify which

commands to execute in your Perl program.

<P>

The default value of the operator mask removes all system and

file operations. Therefore, by default, you cannot create, write

to, or remove files and directories. Interprocess communication

operations are not permitted either. However, input/output operations

via pipes and reading from <TT><FONT FACE="Courier">stdin</FONT></TT>

and writing to <TT><FONT FACE="Courier">stdout</FONT></TT> are

permitted. Any file handles passed into the file handle are considered

secure and any operations on handles that are already opened are

also allowed.

<P>

The <TT><FONT FACE="Courier">Safe</FONT></TT> module file contains

routines for mapping operator names into the operator <TT><FONT FACE="Courier">mask</FONT></TT>

and <TT><FONT FACE="Courier">back</FONT></TT>. Once you have the

object, you can perform the following operations on it:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$namespace = $secure-&gt;root()  # returns

the namespace</FONT></TT>

</BLOCKQUOTE>

<P>

To set the name space to a new value, pass the name in the argument

list:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$newName = &quot;krago&quot;<BR>

$secure-&gt;root($newName);</FONT></TT>

</BLOCKQUOTE>

<P>

The mask can be retrieved and reset using the following method

from outside the wrapped code. The following code disallows all

shared memory operations, but allows any messaging facilities:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">require Safe;<BR>

$secure = new Safe;<BR>

<BR>

@defMask = $secure-&gt;mask();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#

get the mask<BR>

$secure-&gt;trap(OP_SHMGET,OP_SHMCTL,OP_SHMREAD,OP_SHMWRITE);

<BR>

$secure-&gt;untrap(OP_MSGCTL,OP_MSGGET,OP_MSGSND,OP_MSGRCV);<BR>

$secure-&gt;mask(@defmask);<BR>

<BR>

open(DBFILE,'myCredit.File') || die &quot; Whoa! Canna open Kaptain!&quot;;

<BR>

<BR>

sub safecode {<BR>

</FONT></TT>&nbsp;&nbsp;&nbsp;&nbsp;<TT><FONT FACE="Courier">

#<BR>

&nbsp;&nbsp;&nbsp;&nbsp; # Open database and do credit card transaction.

<BR>

</FONT></TT>&nbsp;&nbsp;&nbsp;&nbsp;<TT><FONT FACE="Courier">

⌨️ 快捷键说明

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