PHPセキュリティの基本

この資料は初心者プログラマ向けです。



内容









エラー表示



なぜこんなに頻繁にいくつかのウェブサイトに行くのを見ているのですか:

警告:未定義の定数LOCAL_SERVERの使用-13行目の/web/includes/page-definitions.phpで 'LOCAL_SERVER'を想定





これは標準のPHPエラーの1つであり、a)ユーザーにとっては見苦しいものです。 b)潜在的に危険。

したがって、それらを傍受して注文する必要があります。



まず、 error_reporting関数を使用して、 表示するエラーを決定できます。

原則として、すべてのエラーの表示をオフにするだけで十分です(error_reporting(0))が、エラーについて知りたいため、これは必要ありません。

すべてのエラーの定数はE_ALLです。

5番目のバージョンでは、定数E_STRICTが表示され、コードに関する厳密なコメントが示されました。

もちろん、それらを見ることが望ましいですが、E_ALLには含まれていないため、数値error_reporting(8191)を使用します。これは、第6バージョンの新しいエラーまですべてを吸収します。



好奇心の強い人への注意:error_reporting(E_ALL | E_STRICT)は適切ではありません。PHP4はE_STRICTが何であるかを知らずに誓うからです。 数値に問題はありません。





DEBUGのチェック(構成内の定数セット)を追加し、 set_error_handlerを使用して、既に実行中のサービスでエラーをキャッチします。 ところで、エラーレポーターはtrueを返す必要があります。そうでない場合、PHPは標準エラーをスローします。



結果:

(変数を5つのパラメーターと比較する場合、方法の選択についてはわかりません。in_arrayはよりきれいではるかに遅く、スイッチケースはより高速ですが、完全にいです。美しさは主観的な問題です...)

	<?php

		error_reporting(8191);
		if (!DEBUG)
		{
			function errorHandler ($errno, $errstr, $errfile, $errline)
			{
				//        .

				if	($errno == E_ERROR ||
					$errno == E_PARSE ||
					$errno == E_CORE_ERROR ||
					$errno == E_COMPILE_ERROR ||
					$errno == E_USER_ERROR)
				{	
					//  . , «,  »...

				}
				return true;
			}
			set_error_handler('errorHandler');
		}
	?>
	
      
      









register_globals



4.2.0 register_globals PHP .

, , , PHP if ($username == 'admin')…



, .

POST, GET, COOKIE superglobals $_POST, $_GET, $_COOKIE.

import_request_variables, .

.

.



register_globals:

	<?php
		...
		if (check_admin($..., $...))
		{
			...
			$user_level = 169;
		}
		...
		if ($user_level > 150)
		{
			echo 'Boom!';
		}
	?>
	
      
      





— , $user_level

( 0 , , 0 ),

foo.php?user_level=999 .





SQL injection magic_quotes





	<?php
		$user = mysql_fetch_assoc(mysql_query("SELECT * FROM `users` WHERE `username` = '{$_POST['username'}' AND `password` = '{$_POST['password']}'"));
	?>

	
      
      





. ' OR `username` = 'admin, .



, , .

, - , SQL injection.

PHP , , , escape ( , addslashes).

? . , . , .

, 100- SQL injection.



. ) , . ) , SQL mysql_real_escape_string ( ).



:

	<?php
		{
		if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
		{
			function stripslashes_deep($value)
			{
				if(is_array($value))
				{
					$value = array_map('stripslashes_deep', $value);
				}
				elseif (!empty($value) && is_string($value))
				{
					$value = stripslashes($value);
				}
				return $value;
			}
	
			$_POST = stripslashes_deep($_POST);
			$_GET = stripslashes_deep($_GET);
			$_COOKIE = stripslashes_deep($_COOKIE);
		}
	}
	?>

	
      
      







(mysql_real_escape_string — , . ?)

	<?php
		function quote($value) {
			if (!is_numeric($value)) {
				$value = "'".mysql_real_escape_string($value)."'";
			}
			return $value;
		}
	?>

	
      
      





. - SQL, quote:

	<?php
		$user = mysql_fetch_assoc(mysql_query('SELECT * FROM `users` WHERE `username` = '.quote($_POST['username']).' AND `password` = '.quote($_POST['password'])));	
	?>

	
      
      











, .

.



, .

, , .



	<?php
		if (are_bad_symbols($data)) boo();
	?>
	
      
      







	<?php
		if (!all_good_symbols($data)) boo();
		// :
		is_numeric($data);
		preg_match('/[a-z0-9_-]*/i', $data)
		...
	?>

	
      
      





, .

, - %00 , , , .



, , , , .

.

.



, .

include, require, readfile, eval, ``, system, exec, create_function, dir, fopen .

, , , , — - .

	<?php
		include($_GET['module'] . '.php');
	?>
	
      
      





. '../../../../../etc/passwd%00', , — -.





, cookies , , .

, , — .

cookies ID.

PHP , .

	<?php
		session_start();
		$_SESSION['userid'] = 168;
		session_write_close();
	?>
	
      
      







, cookies - , ?







$_GET, $_POST, $_COOKIE, .

Trust no one! :)




All Articles