File: security.xml

package info (click to toggle)
phpdoc 20020310-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 35,272 kB
  • ctags: 354
  • sloc: xml: 799,767; php: 1,395; cpp: 500; makefile: 200; sh: 140; awk: 51
file content (542 lines) | stat: -rw-r--r-- 27,646 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
<?xml version="1.0" encoding="utf-8"?>
<chapter id="security">
	<title>Security</title>
	<simpara>
	PHP는 매우 강력한 언어이다. 
	이 인터프리터는 웹서버의 모듈로 되어 있건 <acronym>CGI</acronym> 바이너리로 되어 있건, 시스템 내의 파일을 사용할 수 있고, 
	여타의 명령이나 프로그램을 실행할 수 있을뿐 아니라, 네트웍을 통해 다른 서버로 연결을 할 수도 있다. 
	이런 기능들은 악의를 가진 사용자나 초보자가 어떤 프로그램이든 실행시켜 웹서버를 보안상 불안한 상태로 만들 수 있다. 
	PHP는 분명히 Perl이나 C보다 좀더 안전한 CGI 프로그램을 만들 수 있도록 되어 있다. 
	여러이 컴파일이나 실행시 설정 옵션들을 적절히 조합하여 사용하면, 원하는 정도의 자유로움과 보안상의 제약을 조화시킬 수 있다.
  </simpara>
	<simpara>
	PHP는 수많은 방법으로 이용이 가능하고, 이에 따른 여러 가지 설정 옵션이 있을 수 있다. 
	많은 옵션 선택 사항들은 PHP를 보다 많은 목적으로 사용할 수 있도록 하지만, 
	이 옵션들의 조합과 서버의 설정에 따라 보안상의 허점을 노출시킬 수도 있다. 
  </simpara>
	<simpara>
   PHP에서 설정의 유연성은 코드의 유연성과 비견될 만큼 훌륭하다.
   PHP는 쉘 사용자와 동일한 권한으로 완전한 서버 어플리케이션을 만드는데 사용될 수도 있고,
   위험이 거의 없는 매우 제한된 환경에서 간단한 server-side include에도 사용될 수 있다.
   환경을 어떻게 만드는가, 보안은 어떻게 설정하는가는 전적으로 PHP 개발자에게 달려있다.
  </simpara>
	<simpara>
   이 장은 PHP를 안전하게 사용할수 있는 여러 다른 설정 옵션의 조합과 상황을 설명하는 것으로 시작한다.
   그리고, 각각 상이한 보안 레벨에서의 코딩에 있어서 여러가지 고려사항을 설명한다.
  </simpara>
	<sect1 id="security.cgi-bin">
		<title>Installed as CGI binary</title>
		<sect2 id="security.cgi-bin.attacks">
			<title>가능한 공격 (Possible attacks)</title>
			<simpara>
     <acronym>CGI</acronym> binary 형태의 PHP는 어떤 이유로 (아파치 같은) 서버 소프트웨어의 모듈로 
	사용되기를 원하지 않는 경우에 사용할 수 있고, PHP를 다른 종류의 CGI wrapper와 함께 
	안전한 chroot와 setuid 환경을 만들어 내는 곳에 때에 사용할 수 있다. 
	이 설정은 보통 실행할 PHP binary를 웹서버의 cgi-bin디렉토리에 설치해야 한다. 
	CERT 권고사항 <ulink url="&url.cert;">CA-96.11</ulink>에 따르면 모든 인터프리터들은 cgi-bin에 설치하도록 권고된다. 
	비록 PHP binary가 독립적인 인터프리터로 사용된다 할지라도, 
	PHP는 이런 설정에서 받을 수 있는 공격을 다음과 같이 막아내도록 설계되어 있다. : 
    </simpara>
			<itemizedlist>
				<listitem>
					<simpara>
       시스템 파일로의 접근 : <filename role="url">http://my.host/cgi-bin/php?/etc/passwd</filename>
					</simpara>
					<simpara>
	이 url내의 물음표(?)이후에 있는 요청은 CGI 인터페이스에 의해 command line argument로 인터프리터에게 전달된다.
	보통 인터프리터는 커맨드 라인의 첫 번째 argument의 파일을 읽어서 실행 한다. 
      </simpara>
					<simpara>
	CGI binary로 실행 된 PHP는 모든 command line argument들을 모두 무시한다. 
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       서버의 웹 문서로의 접근 : <filename role="url">http://my.host/cgi-bin/php/secret/doc.html</filename>
					</simpara>
					<simpara>
	이 url의 PHP binary 이후의 path 정보(<filename role="uri">/secret/doc.html</filename>)는 
	일반적으로 <acronym>CGI</acronym> 프로그램에 의해 읽고 해석될  파일 이름으로 사용된다. 
	보통 웹서버는 설정 지시자(Apache의 경우 Action)를 사용하여 <filename role="url">http://my.host/secret/script.php</filename>같은 
	문서 요청을 PHP 인터프리터로 바로 리디렉트 하도록 할 수 있다. 이렇게 설정하면, 
	웹서버는 우선 <filename role="uri">/secret</filename> 디렉토리의 접근 권한을 검사한 후에 
	<filename role="url">http://my.host/cgi-bin/php/secret/script.php</filename>로 리디렉트를 한다. 
	불행히도, 이 요청이 원래의 form에서 주어진 것이라면, 웹서버는 <filename role="uri">/secret/script.php</filename>
	파일에 대한 접근 권한 검사를 하지 않고, <filename role="uri">/cgi-bin/php</filename> 파일에 대한 검사만을 행한다. 
	이 방법을 사용하면 <filename role="uri">/cgi-bin/php</filename>에 접근 가능한 사용자는 웹서버상의 모든 보호된 문서들도 접근할 수 있다.
      </simpara>
					<simpara>
	이런경우 서버 문서 tree에 접근 제약이 있는 디렉토리가 있다면, 
	컴파일시에 <link linkend="install.configure.enable-force-cgi-redirect">--enable-force-cgi-redirect</link> 설정 옵션을 주고, 
	실행시에 <link linkend="ini.doc-root">doc_root</link>와 <link linkend="ini.user-dir">user_dir</link> 지시자를 사용하여서 
	이 공격을 막아낼 수 있다. 아래에 여러 가지 다른 조합 방법에 대한 자세한 설명이 나와 있다.
      </simpara>
				</listitem>
			</itemizedlist>
		</sect2>
		<sect2 id="security.cgi-bin.default">
			<title>Case 1: 공용 파일만 제공하는 경우 (only public files served)</title>
			<simpara>
	만약 여러분의 서버가 password 나 ip 기준의 접근 통제에 관한 어떠한 사항도 없다면, 
	이러한 설정 옵션들은 필요 없다. 
	만약 여러분의 웹서버가 리디렉트를 허용하지 않거나, 서버가 해당 요구가 안전하게 리디렉트된 요구인지 대한 정보를 
	PHP binary에 전달할 수 있는 방법이 없을 경우, config 스크립트에서
	<link linkend="install.configure.enable-force-cgi-redirect">--enable-force-cgi-redirect</link> 옵션을 주는 것이 좋다.
	그러나 여전히 PHP 스크립트가, <filename role="php">http://my.host/cgi-bin/php/dir/script.php</filename>같은 직접 접근 방법이나
	<filename role="php">http://my.host/dir/script.php</filename>같은 리디렉션의 방법 이외의,
	다른 믿지 못할 방법에 의해 불려 질 때를 대비하여 대책을 강구해 두어야 합니다
    </simpara>
			<simpara>
	리디렉션은 예를들어 Apache에서는 AddHandle과 Action 지시자를 사용하여 설정할 수 있습니다. (아래를 보세요.)
    </simpara>
		</sect2>
		<sect2 id="security.cgi-bin.force-redirect">
			<title>Case 2: --enable-force-cgi-redirect 옵션 사용</title>
			<simpara>
	이 옵션을 주고 PHP를 컴파일 하면, 사용자가 <filename role="php">http://my.host/cgi-bin/php/secretdir/script.php</filename>와 
	같이 PHP를 직접 호출하는 것을 막아준다. 
	대신, 이 모드에서 PHP는 사용자의 요구(request)가 웹서버의 리디렉트 규칙을 통과한 경우에만 동작 할 것이다.
    </simpara>
			<simpara>
	일반적으로 아파치에서 리디렉트 설정은 다음과 같은 지시자를 사용하여 한다. : 
    </simpara>
			<programlisting role="apache-conf">
Action php-script /cgi-bin/php
AddHandler php-script .php
    </programlisting>
			<simpara>
	이 옵션은 아파치 웹서버에서만 검증되었다. 
	아파치는 리디렉트된 요구에 대해서는 <envar>REDIRECT_STATUS</envar> 라는 비 표준 CGI 환경 변수를 설정한다. 
	만약 웹서버가 해당 문서 요구가 직접접근(direct)인지 리디렉트(redirect)인지 구별할 수 있는 방법을 제공하지 않는다면 
	여러분은 이 옵션을 사용할 수 없으므로 이 문서에 있는 CGI 버전에 대한 다른 방법을 사용해야 할 것이다. 
    </simpara>
		</sect2>
		<sect2 id="security.cgi-bin.doc-root">
			<title>Case 3: doc_root나 user_dir의 설정</title>
			<simpara>
	웹서버 문서 디렉토리에 script나 실행파일 같은 Active content를 포함하는 것은 때때로 불안한 상황을 만들 수 있다. 
	만약 약간의 설정 오류로 스크립트가 실행되지 않고 HTML 문서처럼 그대로 출력 된다면, 
	각종 지적 재산이나 Password같은 보안상의 정보가 누설되는 결과가 초래될 지 모른다. 
	그러므로 많은 시스템 관리자들은 스크립트를 위한 별도의 디렉토리를 만들어 놓고, 
	이 디렉토리는 PHP CGI를 통해서만 접근이 가능하도록 만들어 놓아 실행은 가능하지만 보여지지는 않도록 하고 있다.
    </simpara>
			<simpara>
	또한, 위에서 말한 바와 같이, 문서 요구가 리디렉트된 것이 아니라고 확인해주는 방법이 없다면, 
	웹서버의 document root와는 별도의 script doc_root를 설정해 주는 것이 반드시 필요하다.
    </simpara>
			<simpara>
				<link linkend="configuration.file">configuration file (php.ini)</link>의 <link linkend="ini.doc-root">doc_root</link> 지시자를 설정하거나, 	<envar>	PHP_DOCUMENT_ROOT</envar>라는 환경변수를 설정하여, PHP script document root를 설정할 수 있다. 
	만약 이것이 설정되어 있다면, CGI 버전의 PHP는 접근하려는 파일의 이름을 
	이 <parameter>doc_root</parameter>와 request에 있는 경로 정보를 이용하여 만들어낸다.
	따라서 여러분은 이 디렉토리 밖에서는 어떠한 스크립트도 실행될 수 없도록 만들게 된다. (아래에 있는 user_dir 만은 예외이다)
    </simpara>
			<simpara>
	여기서 사용할 수 있는 또다른 옵션은 <link linkend="ini.user-dir">user_dir</link>이다. 
	user_dir이 설정되어 있지 않으면 접근 가능한 파일은 <parameter>doc_root</parameter> 밑에 있는 것 뿐이다. 
	<filename role="url">http://my.host/~user/doc.php</filename>같은 url로는 user home directory에 있는 파일을 열 수 없다. 
	단지 doc_root아래의 <filename role="uri">~user/doc.php</filename> 파일을 부를 뿐이다. 
	(물론 틸데[<literal>~</literal>]로 시작하는 "~user"라는 디렉토리이다.)
    </simpara>
			<simpara>
	예를 들어, 만약 user_dir이 <filename role="dir">public_php</filename>로 설정되어 있다면, 
	<filename role="url">http://my.host/~user/doc.php</filename>와 같은 요구는 user의 home 디렉토리 밑의 
	<filename role="dir">public_php</filename>라는 디렉토리 밑에 있는 doc.php라는 파일을 호출 할 것이다. 
	만약 사용자의 home이 <filename role="dir">/home/user</filename>라면, 
	실행되는 파일은 <filename>/home/user/public_php/doc.php</filename>가 된다. 
    </simpara>
			<simpara>
				<parameter>user_dir</parameter> 확장은 <parameter>doc_root</parameter> 설정과 관련없으므로, 
	여러분은 document root와 user directory 접근 통제를 따로따로 할 수 있다.
    </simpara>
		</sect2>
		<sect2 id="security.cgi-bin.shell">
			<title>Case 4: PHP parser를 웹 트리 밖에 두기 (parser outside of web tree)</title>
			<para>
	매우 신뢰할수 있는 방법으로 PHP parser binary를 웹 트리 밖에다 두는 방법이다. 
	예를 들어 <filename role="dir">/usr/local/bin</filename> 같은 곳에 둔다. 
	이 옵션의 단점은, 모든 PHP 택을 포함하고 있는 파일의 첫번째 라인에 다음과 같이 적어주는 것 뿐이다. : 
     <informalexample>
      <programlisting>
#!/usr/local/bin/php
      </programlisting>
     </informalexample>
	또한 파일을 실행 가능으로 만들어 주어야 한다. 
	즉, 자신의 실행을 위해서 <literal>#!</literal> shell-escape 메카니즘을 사용하는 
	Perl이나 sh 혹은 다른 스크립트 언어와 같은 방식으로 다루는 것이다.
    </para>
    <para>
	이 설정에서 PHP가 <envar>PATH_INFO</envar>와 <envar>PATH_TRANSLATED</envar>정보를 정확히 다루려면, 
	php parser가 <link linkend="install.configure.enable-discard-path">--enable-discard-path</link> 설정 옵션으로 컴파일 되어야 한다.
    </para>
		</sect2>
	</sect1>
	<sect1 id="security.apache">
		<title>Installed as an Apache module</title>
		<simpara>
    PHP가 아파치 모듈로 사용되면 아파치 사용자 권한을 그대로 이어받는다. (보통 'nobody' user)
    이것은 보안과 인증에 대해 각각 영향을 미친다. 예를들어 PHP로 데이타베이스에 접근하고,
   이 데이타베이스의 자체적인 내장 접근 통제를 사용하지 않는다면, "nobody" 사용자를 
    데이타베이스에 접근 가능하도록 설정해 두어야 한다.
   이것은 username과 password를 몰라도 악의적인 스크립트를 사용하여 데이타베이스에 접근하고 
   데이타를 수정할 수 있다는 것을 의미한다. 또한 크래커가 관리자용 웹페이지를 들락거리고,
   데이타베이스를 삭제해 버리는 것도 가능하다. 여러분은 아파치의 인증 기능을 사용하여 
   이런 공격에 대항하는 방어를 할 수 있다.

   사용
    When PHP is used as an Apache module it inherits Apache's user
    permissions (typically those of the "nobody" user). This has several
    impacts on security and authorization. For example, if you are using
    PHP to access a database, unless that database has built-in access
    control, you will have to make the database accessable to the
    "nobody" user. This means a malicious script could access and modify
    the databse, even without a username and password. It's entirely
    possible that a web spider could stumble across a database
    adminisitror's web page, and drop all of your databases. You can
    protect against this with Apache authorization, or you can design
    your own access model using LDAP, .htaccess files, etc. and include
    that code as part of your PHP scripts.
   </simpara>
		<simpara>
    Often, once security is established to the point where the PHP user
    (in this case, the apache user) has very little risk, it is
    discovered that PHP now has been prevented from writing virus files
    to user directories. Or perhaps it has been prevented from accessing
    or changing a non-public database. It has equally been secured from
    writing files that it should, or entering database transactions.
   </simpara>
		<simpara>
    A frequent security mistake made at this point is to allow apache
    root permissions.
   </simpara>
		<simpara>
    Escalating the Apache user's permissions to root is extremely
    dangerous and may compromise the entire system, so sudo'ing,
    chroot'ing ,or otherwise running as root should not be considered by
    those who are not security professionals.
   </simpara>
	</sect1>
	<sect1 id="security.filesystem">
		<title>Filesystem Security</title>
		<simpara>
    PHP is subject to the security built into most server systems with
    respect to permissions on a file and directory basis. This allows
    you to control which files in the filesystem may be read. Care
    should be taken with any files which are world readable to ensure
    that they are safe for reading by all users who have access to that
    filesystem.
   </simpara>
		<simpara>
    Since PHP was designed to allow user level access to the filesystem,
    it's entirely possible to write a PHP script that will allow you
    to read system files such as /etc/password, modify your ethernet
    connections, send massive printer jobs out, etc. This has some
    obvious implications, in that you need to ensure that the files
    that you read from and write to are the appropriate ones.
   </simpara>
		<simpara>
    Consider the following script, where a user indicates that they'd
    like to delete a file in their home directory. This assumes a
    situation where a PHP web interface is regularly used for file
    management, so the Apache user is allowed to delete files in
    the user home directories.
   </simpara>
		<para>
			<example>
				<title>Poor variable checking leads to....</title>
				<programlisting role="php">
&lt;?php
// remove a file from the user's home directory
$username = $user_submitted_name;
$homedir = "/home/$username";
$file_to_delete = "$userfile";
unlink ($homedir/$userfile);
echo "$file_to_delete has been deleted!";
?&gt;
     </programlisting>
			</example>
   Since the username is postable from a user form, they can submit
   a username and file belonging to someone else, and delete files.
   In this case, you'd want to use some other form of authentication.
   Consider what could happen if the variables submitted were
   "../etc/" and "passwd". The code would then effectively read:
    <example>
				<title>... A filesystem attack</title>
				<programlisting role="php">
&lt;?php
// removes a file from anywhere on the hard drive that
// the PHP user has access to. If PHP has root access:
$username = "../etc/";
$homedir = "/home/../etc/";
$file_to_delete = "passwd";
unlink ("/home/../etc/passwd");
echo "/home/../etc/passwd has been deleted!";
?&gt;
     </programlisting>
			</example>   
    There are two important measures you should take to prevent these
    issues.
    <itemizedlist>
				<listitem>
					<simpara>
       Only allow limited permissions to the PHP web user binary.
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       Check all variables which are submitted.
      </simpara>
				</listitem>
			</itemizedlist>
    Here is an improved script:
    <example>
				<title>More secure file name checking</title>
				<programlisting role="php">
&lt;?php
// removes a file from the hard drive that
// the PHP user has access to. 
$username = $HTTP_REMOTE_USER; // use an authentication mechanisim

$homedir = "/home/$username";

$file_to_delete = basename("$userfile"); // strip paths
unlink ($homedir/$file_to_delete);

$fp = fopen("/home/logging/filedelete.log","+a"); //log the deletion
$logstring = "$HTTP_REMOTE_USER $homedir $file_to_delete";
fputs ($fp, $logstring);
fclose($fp);

echo "$file_to_delete has been deleted!";
?&gt;
     </programlisting>
			</example>
    Alternately, you may prefer to write a more customized check:
    <example>
				<title>More secure file name checking</title>
				<programlisting role="php">
&lt;?php
$username = getenv("REMOTE_USER");
$homedir = "/home/$username";

if (!ereg('^[^./][^/]*$', $userfile))
    die('bad filename'); //die, do not process
    
//etc...
?&gt;
     </programlisting>
			</example> 
    Depending on your operating system, there are a wide variety of files
    which you should be concerned about, including device entries (/dev/
    or COM1), configuration files (/etc/ files and the .ini files),
    well known file storage areas (/home/, My Documents), etc. For this
    reason, it's usually easier to create a policy where you forbid
    everything except for what you explicitly allow.
   </para>
	</sect1>
	<sect1 id="security.errors">
		<title>Error Reporting</title>
		<simpara>
    A standard attack tactic involves profiling a system by feeding
    it improper data, and checking for the kinds, and contexts, of the
    errors which are returned. This allows the system cracker to probe
    for information about the server, to determine possible weaknesses.
   </simpara>
		<simpara>
    The PHP errors which are normally returned can be quite helpful to a
    developer who is trying to debug a script, indicating such things
    as the function or file that failed, the PHP file it failed in,
    and the line number which the failure occured in. This is all
    information that can be exploited.  It is not uncommon for a php
    developer to use <function>show_source</function>, 
    <function>highlight_string</function>, or 
    <function>highlight_file</function> as a debugging measure, but in 
    a live site, this can expose hidden variables, unchecked syntax, 
    and other dangerous information.
   </simpara>
		<simpara>
    For example, the very style of a generic error indicates a system
    is running PHP. If the attacker was looking at an .html page, and
    wanted to probe for the back-end (to look for known weaknesses in
    the system), by feeding it the wrong data they may be able to
    determine that a system was built with PHP.
   </simpara>
		<simpara>
    A function error can indicate whether a system may be running a
    specific database engine, or give clues as to how a web page or
    programmed or designed. This allows for deeper investigation into
    open database ports, or to look for specific bugs or weaknesses
    in a web page. By feeding different pieces of bad data, for example,
    an attacker can determine the order of authentication in a script,
    (from the line number errors) as well as probe for exploits that
    may be exploited in different locations in the script.
   </simpara>
		<simpara>
    A filesystem or general PHP error can indicate what permissions
    the webserver has, as well as the structure and organization of
    files on the web server. Developer written error code can aggravate
    this problem, leading to easy exploitation of formerly "hidden"
    information.
   </simpara>
		<simpara>
    There are three major solutions to this issue. The first is to
    scrutinize all functions, and attempt to compensate for the bulk
    of the errors. The second is to disable error reporting entirely
    on the running code. The third is to use PHP's custom error
    handling functions to create your own error handler. Depending
    on your security policy, you may find all three to be applicable
    to your situation.
   </simpara>
	</sect1>
	<sect1 id="security.variables">
		<title>User Submitted Data</title>
		<para>
    The greatest weakness in many PHP programs is not inherent in the
    language itself, but merely an issue of code not being written with
    security in mind. For this reason, you should always take the time
    to consider the implications of a given piece of code, to ascertain
    the possible damage if an unexpected variable is submitted to it.
    <example>
				<title>Dangerous Variable Usage</title>
				<programlisting role="php">
&lt;?php
// remove a file from the user's home directory... or maybe
// somebody else's?
unlink ($evil_var);

// Write logging of their access... or maybe not?
fputs ($fp, $evil_var);

// Execute something trivial.. or rm -rf *?
system ($evil_var);
exec ($evil_var);

?&gt;
     </programlisting>
			</example>
    You should always carefully examine your code to make sure that any
    variables being submitted from a web browser are being properly
    checked, and ask yourself the following questions:
    <itemizedlist>
				<listitem>
					<simpara>
       Will this script only affect the intended files?
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       Can unusual or undesirable data be acted upon?
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       Can this script be used in unintended ways?
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       Can this be used in conjunction with other scripts in a negative
       manner?
      </simpara>
				</listitem>
				<listitem>
					<simpara>
       Will any transactions be adequately logged?
      </simpara>
				</listitem>
			</itemizedlist>
    By adequately asking these questions while writing the script,
    rather than later, you prevent an unfortunate re-write when you
    need to increase your security. By starting out with this mindset,
    you won't guarantee the security of your system, but you can help
    improve it.
   </para>
		<para>
    You may also want to consider turning off register_globals,
    magic_quotes, or other convenience settings which may confuse
    you as to the validity, source, or value of a given variable.
    Working with PHP in error_reporting(E_ALL) mode can also help warn
    you about variables being used before they are checked or
    initialized (so you can prevent unusual data from being
    operated upon).
   </para>
	</sect1>
	<sect1 id="security.general">
		<title>General considerations</title>
		<simpara>
    A completely secure system is a virtual impossibility, so an
    approach often used in the security profession is one of balancing
    risk and usability. If every variable submitted by a user required
    two forms of biometric validation (such as a retinal scan and a
    fingerprint), you would have an extremely high level of
    accountability. It would also take half an hour to fill out a fairly
    complex form, which would tend to encourage users to find ways of
    bypassing the security.
   </simpara>
		<simpara>
    The best security is often inobtrusive enough to suit the
    requirements without the user being prevented from accomplishing
    their work, or over-burdening the code author with excessive
    complexity. Indeed, some security attacks are merely exploits of
    this kind of overly built security, which tends to erode over time.
   </simpara>
		<simpara>
    A phrase worth remembering: A system is only as good as the weakest
    link in a chain. If all transactions are heavily logged based on
    time, location, transaction type, etc. but the user is only
    verified based on a single cookie, the validity of tying the users
    to the transaction log is severely weakened.
   </simpara>
		<simpara>
    When testing, keep in mind that you will not be able to test all
    possibilities for even the simplest of pages. The input you
    may expect will be completely unrelated to the input given by
    a disgruntled employee, a cracker with months of time on their
    hands, or a housecat walking across the keyboard. This is why it's
    best to look at the code from a logical perspective, to discern
    where unexpected data can be introduced, and then follow how it is
    modified, reduced, or amplified.
   </simpara>
		<simpara>
    The Internet is filled with people trying to make a name for
    themselves by breaking your code, crashing your site, posting
    inappropriate content, and otherwise making your day interesting.
    It doesn't matter if you have a small or large site, you are
    a target by simply being online, by having a server that can be
    connected to. Many cracking programs do not discern by size, they
    simply trawl massive IP blocks looking for victims. Try not to
    become one.
   </simpara>
	</sect1>
	<sect1 id="security.current">
		<title>Keeping Current</title>
		<simpara>
    PHP, like any other large system, is under constant scrutiny and
    improvement. Each new version will often include both major and
    minor changes to enhance and repair security flaws, configuration
    mishaps, and other issues that will affect the overall security
    and stability of your system.
   </simpara>
		<simpara>
    Like other system-level scripting languages and programs, the best
    approach is to update often, and maintain awareness of the latest
    versions and their changes.
   </simpara>
	</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->