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">
<?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!";
?>
</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">
<?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!";
?>
</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">
<?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!";
?>
</programlisting>
</example>
Alternately, you may prefer to write a more customized check:
<example>
<title>More secure file name checking</title>
<programlisting role="php">
<?php
$username = getenv("REMOTE_USER");
$homedir = "/home/$username";
if (!ereg('^[^./][^/]*$', $userfile))
die('bad filename'); //die, do not process
//etc...
?>
</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">
<?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);
?>
</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:
-->
|