register_globals = Off
아직도 많은 국내의 호스팅 업체들에서 register_globals = On 으로 놓고 서비스를 하고 있으나 Off 로 해야 옳다.
물론 이렇게 하면 제로보드처럼 On에서 코딩한 것들은 쓸 수 없게 된다. (제로보드는 쓰지 않는 것이 좋다.)
register_globals = On 으로 놓고서 코드 내에서 따로 보안을 위해 변수를 검사하는 방법도 있겠으나, 그런 이중의 수고를 막으려면 php4 이상에서는 그냥 register_globals = Off 로 하고 그에 따라 코딩해야 한다.
이를테면 $a를 받아서 $b = $a; 로 처리해야 할 때는,
$b=$_GET["a"]; (GET 방식으로넘어온 변수일경우)
$b=$_POST["a"]; (POST 방식으로넘어온 변수일경우)
$b=$_COOKIE ["a"]; (cookie에서 넘어온 값이면)
$b=$_SERVER["a"]; (서버변수일경우)
$b=$_ENV["a"]; (환경변수일 경우)
$b=$_REQUEST["a"]; (서버요청변수일 경우. - GET, POST, Cookie 방식으로 넘어오는 모든 경우에 해당되며, 보안상 권장되지 않는다.)
$b=$_SESSION["a"]; (세션변수이면)
$b=$_FILES["a"]; (file 업로드로 넘어온 변수이면)
와 같이 처리해야 한다.
위 처럼 하기 귀찮을 경우, extract($_GET); 으로 선언하면 $_GET['a']로 들어오는 $a 를 자동으로 인식한다.
♣ 단, SESSION 변수의 경우 절대 extract($_SESSION); 하면 안된다. 보안에 위배되기 때문이다. if (isset($_GET['password'])) { $password = $_GET['password']; echo $password; }
.inc 파일 등 특정 확장자 소스 못보게 하기
아파치 설정파일(httpd.conf) 안에 보면 아래와 같은 라인이 있다.
AddType application/x-httpd-php .php .php3 .html .sql .ph .inc .ins
AddType application/x-httpd-php-source .phps
위에서와 같이 inc를 등록시키면 된다.
그리고 웹브라우저에서 보아도 소스는 나오지 않는다. *.inc 등으로 작성하려거든 반드시 이렇게 해야만 한다. 혹은 *.inc.php 이런 식으로 작성한다.
PHP 보안을 위한 코딩 스타일 (파일 업로드 등)
현재(2002.3) PHP4.1.2 나 PHP4.2.dev 버전을 제외한 모든 버전은 PHP4.1.2로 패치할 것을 권고하고 있다. PHP 파일 업로딩이 RFC 1867에 의해 만들어졌는데, 웹서버를 재부팅 시킬 수도 있다고 한다. PHP4.1.2 이상의 최신 버전이 아닌 모든 버전은 파일 업로드 버그가 존재한다고 한다.
예전 스타일의 파일 업로드를 사용하지 마라; HTTP_POST_FILES 배열과 관련된 함수를 사용해라. PHP 는 특별한 이름을 갖는 어떤 임시디렉토리에 파일을 업로드함으로써 파일 업로드를 지원한다. PHP 는 그 파일 이름이 존재했던 곳을 가리키기 위해 원래 많은 변수들을 설정한다. 그러나 공격자가 변수 이름 및 그 값을 제어할 수 있기 때문에 이들을 사용해 커다란 악영향을 야기할 수 있다. 대신 업로드된 파일에 접근하기 위해서는 언제나 HTTP_POST_FILES 및 관련된 함수를 사용해라. 이 경우라도 PHP 는 공격자가 임의의 내용을 갖는 파일을 업로드할 수 있게 하며 이는 그 자체로 위험함을 주목해라.
모든 입력에 대해 다른 언어에서와 같이 받아들일 수 있는지 패턴과의 일치 여부를 검사하고 그 후 문자열이 아닌 데이타를 요구되는 타입으로 맞추기 위해 타입 캐스팅을 사용해라. (예상되는) 입력의 선택된 리스트를 쉽게 검사하고 import 하기 위해 ``helper" 함수를 개발해라. PHP 는 부정확하게 타입이 정해질 수 있는데 (loosely-typed) 이는 문제를 야기할 수 있다. 예를 들어 입력 데이타가 "000" 값을 갖는다면 이는 "0" 와 같지 않으며 또한 empty() 도 아니다. 이는 특히 결합 (associative) 배열의 경우 중요한데 이들의 인덱스가 문자열이기 때문이다; 이는 $data["000"] 과 $data["0"] 이 다르다는 것을 의미한다. 예를 들어 $bar 가 double 타입임을 확인하기 위해 (double 에 적합한 포맷을 갖는지 확인한 후) 다음과 같이 해라:
$bar = (double) $bar;
위험한 함수에 주의할 것 :
코드실행함수(require(), include(), eval(), preg_replace() 등), 명령실행함수(exec(), passthru(), backtick 연산자, system(), popen() 등), 파일오픈암수(fopen(), readfile(), file()) 등.
PHP에러출력을 방지한다. php.ini의 Error_Handling 부분에서 display_errors = Off 로 설정한다. (오류가 보여지면 apache 디렉토리 위치나 htdocs 디렉토리 위치를 노출시키게 된다.)
magic_quotes_gpc() 를 사용해라. 이는 많은 종류의 공격을 제거한다.
게시판 글올릴때 html소스는 그냥 다 막아버려라. <a>태그 외에 <a onmouse= 등의 태그도 안되고 자바스크립트도 안된다. 그냥 다 막아버리면 제일 속편하다.
phpinfo();는 설치한 후 테스트하고 바로 지워라.
쿠키보다는 세션을, 세션보다는 autu인증을 사용하라.
location.replace 인증 (이동했던 히스토리 삭제) function goto_page($url) { echo "<script> location.replace('.$url.');</script>"; }
쇼핑몰 등의 사이트는 반드시 SSL을 사용하라.
디렉토리는 755대신 711로 설정. 그리고 될수있으면 아파치 httpd.conf 에서 Indexes 지운다. (index.html 파일이 없을 경우 디렉토리 목록이 출력되는 것을 방지.)
(보안) 세션, 자료실, PHP_SELF
(출처: http://tood.net)
php.ini 에서 register_globals = Off 로 설정했다면 세션의 등록은 아래와 같이 한다. <?php session_start(); $HTTP_SESSION_VARS['foo'] = "blah blah"; // $_SESSION['foo'] = "blah blah"; // $_SESSION은 PHP4.1.0 이상이다. session_register('foo'); ?>
회원 비번은 md5()로 암호화하고 php.ini에서 세션저장장소를 /tmp가 아닌 다른 장소에 저장한다. (보안을 위해)
세션 생성 시 $userid를 생성하고, $userpass = md5($userpass); 로 생성해서, 2개 값이 있는지 비교하고 isset()등으로 비교하는게 좋다.
$userpass값은 md5()로 해싱하면 32자가 되므로 길이를 확인한다.
if((session_is_registered(username)) && (session_is_registered(user_id)))
으로 체크. <?php function check_session() { session_start(); if (session_is_registered(user_id)) { return TRUE; } else { header("Location: login.php"); exit; } } ?>
파일의 경우는 $HTTP_POST_FILES 를 따로 해야 한다. extract($HTTP_POST_FILES); foreach ($HTTP_POST_FILES as $UploadedFile ) { $UploadedFile_name = $UploadedFile['name']; $UploadedFile_size = $UploadedFile['size']; $UploadedFile_type = $UploadedFile['type']; }
특히 파일의 경우 절대로 GET으로 올리지 못하게 해야한다.
upload.php?file_name=/etc/passwd$file_type=text&file_size=30
이런 식으로 해킹할 시스템의 passwd파일을 자료실에 올려버리고 다운받는 경우가 있기 때문이다. 아예 파일명 중에 pass나 shadow등이 있을 경우 올리지 못하게 하는 방법도 있다.
또는 file_exists($file_name)를 사용하여 체크한다. 로컬 시스템에 파일이 있으면 절대 못올리게 되는 것이다.
$PHP_SELF의 경우도 바로 출력되지 않는다. $_SERVER['REQUEST_METHOD']; //GET or POST $_SERVER['REQUEST_URI']; $_SERVER['PHP_SELF'];
링크로 넘어오는 값 확인
( 출처 : http://www.nzeo.com/bbs/zboard.php?id=cgi_tip&page=2&sn1=&divpage=1&sn=off&ss=on&sc=off&keyword=링크&select_arrange=headnum&desc=asc&no=1030 ) if(!eregi(getenv("HTTP_HOST"),getenv("HTTP_REFERER"))) { $reffer = getenv("HTTP_REFERER"); echo "<script>alert('여기다 무단링크시 남길 메세지');window.location.href='http://4rum.uu.st (홈주소)';</script>"; $filename = "기록할 파일 이름"; if (!file_exists($filename)) touch ("$filename"); chmod($filename,0777); $fp = fopen($filename,"a+"); if (!trim($reffer)) $reffer = "Typing or Bookmark"; fwrite($fp,"IP : $REMOTE_ADDR , REFFER : $reffer\n"); fclose($fp); exit; }
자료실에서 무단링크, 웹상에서 실행을 막는 한 가지 방법
자료를 업로드 할 때 원래이름과 바꿀이름 2가지를 디비에 저장한다. 그리고 다운로드를 받을 때는 디비에서 원래 이름을 가져와서 헤더 함수를 이용해 파일명을 원래이름으로 바꿔서 보냅니다.. 이렇게하면 저장되어있는 파일이름을 알 수가 없기때문에 무단링크, 웹상에서 실행이 불가능 하게된다. 파일이름을 안다고 해도 웹상에서는 실행되자 않는다. (아파치가 인식할 수 없는 확장자명으로 지정했을경우) 그러니까 파일을 저장할때 파일명을 $filename = date("YmdHis").".down"; 으로 한다. 그럼 200101231203.down 이런 식으로 파일명이 된다.
PHP파일문서를 자료실에 올리는 문제 (불완전정보)
자료실에 확장자 php인 자료를 올려 해당 서버의 정보를 유출하거나 자료를 삭제하는 해킹이 있을 수 있다. 이 때는 php를 사용할 디렉토리를 정한 후 모든 php소스는 그 디렉토리 밑에 두어야 한다.
예를 들어 자신의 Document Root 디렉토리가 '/home/aaa/public_html'이라면 public_html 아래에 php란 디렉토리를 만든다. 그런 다음 아파치 웹 서버의 설정파일 httpd.conf 를 다음과 같이 수정한다.
<Directory "/home/aaa/public_html"> ... php_admin_flag engine off ... </Directory> <Directory "/home/aaa/public_html"> ... php_admin_flag engine off ... </Directory>
게시글 목록
| 번호 | 제목 |
|---|---|
| 8265 | |
| 20403 | |
| 20402 | |
| 20401 | |
| 20400 |
웹서버
서버 동시접속자 설정 변경하기
|
| 8259 | |
| 20399 | |
| 20398 | |
| 8255 | |
| 8249 | |
| 8246 | |
| 8242 | |
| 20396 | |
| 8240 | |
| 20395 | |
| 20394 |
MySQL
테이블 복사 쿼리
|
| 31033 | |
| 28385 | |
| 20393 |
PHP
현재 접속중인 사용자 나타내기
|
| 28380 | |
| 20392 |
MySQL
mysql select 후 update 하기
|
| 28377 | |
| 20391 | |
| 20390 |
PHP
한글문자열 자르는 법 입니다.
|
| 20389 | |
| 20388 | |
| 20387 |
PHP
이메일주소 검사하기 입니다.
|
| 20386 | |
| 20385 | |
| 20384 |
node.js
Node js 게시판 프로젝트 소개합니다.
|
| 20383 |
PHP
pc 모바일 체크
1
|
| 20382 |
PHP
계정 사용량(용량) 확인
|
| 8238 | |
| 20380 | |
| 20379 |
MySQL
소수점 반올림 버림
|
| 28376 | |
| 28372 | |
| 20378 | |
| 20377 |
PHP
에러 로그파일 생성하기
|
| 8235 | |
| 20375 | |
| 20374 | |
| 20373 |
PHP
후이즈검색 하기 입니다.
|
| 20372 |
PHP
그래프 그리기 입니다.
|
| 20371 |
JavaScript
자바스크립트로 구현한 number_format() 입니다.
|
| 20370 |
JavaScript
금액 관련 숫자를 한글로 변환하기 입니다.
|
| 28370 | |
| 20369 |
PHP
PHP 날짜 계산 관련 함수
|
| 28366 | |
| 20368 |
jQuery
jQuery 1.x와 2.x 버전 동시에 사용하기
|
| 20367 | |
| 20366 | |
| 20365 |
JavaScript
사업자 등록번호 검사하기 입니다.
|
| 20364 | |
| 20363 |
JavaScript
항상 같은곳에 광고창 만들기 입니다.
|
| 20362 |
JavaScript
부메뉴 나오게 하기 입니다.
|
| 20361 |
JavaScript
특정문자 제거하기 입니다.
|
| 20360 |
JavaScript
휴대폰번호 검사 하기 입니다.
|
| 20359 |
JavaScript
이미지 좌우로 이동 갤러리 입니다.
|
| 8231 | |
| 20358 | |
| 20357 |
JavaScript
쉬운 replaceAll 입니다.
|
| 20356 | |
| 20355 | |
| 20354 | |
| 20353 | |
| 20352 |
JavaScript
콤보스타일 메뉴 입니다.
|
| 20351 |
JavaScript
쿠키를 이용한 레이어 공지창 입니다.
|
| 20350 |
JavaScript
효과있는 텍스트 틱커 입니다.
|
| 20349 | |
| 20348 |
PHP
HTTP 인증 하기 입니다.
|
| 20347 |
JavaScript
외부 문서 불러오기 입니다.
|
| 20346 |
JavaScript
지정한 날짜까지 New 이미지를 띄워주기 입니다.
|
| 20345 | |
| 20344 |
JavaScript
메일 주소 검사하기 체크박스 입니다.
|
| 20343 |
JavaScript
무단링크 금지하기 입니다.
|
| 20342 | |
| 20341 |
MySQL
DB백업 및 복원
|
| 20340 |
JavaScript
페이지가 다른 사이트의 프레임에 갇히는 것을 막기 입니다.
|
| 20339 | |
| 20338 | |
| 20337 |
jQuery
input text 대문자만 받는 Jquery
|
| 20336 | |
| 20335 |
JavaScript
이미지 업로드와 미리보기 입니다.
|
| 20334 |
JavaScript
배경음악 랜덤 재생 하기 입니다.
|
| 20333 |
JavaScript
css 지원 여부 확인해서 다른 페이지로 이동하기 입니다.
|
| 20332 |
JavaScript
하부메뉴가 보였다가 숨겨졌다 하는 토글버튼 입니다.
|
| 20331 |
JavaScript
개별 페이지에 인덱스로 거쳐 들어오게 하기 입니다.
|
| 20330 |
JavaScript
랜덤으로 이미지 출력 되기 입니다.
|
| 20329 |
JavaScript
사용자 해상도 알아내기 입니다.
|
| 20328 |
JavaScript
붙여넣기 금지하기 입니다.
|
| 20327 |
MySQL
대소문자 데이터 조회하기
|
| 20326 |
JavaScript
퇴장시 팝업창 한번한 띄우기 입니다.
|
| 20325 | |
| 20324 | |
| 20323 |
JavaScript
시도, 구군, 동 주소 select
|
| 20322 |
MySQL
커리로 DB 테이블 명세서 출력하기
|
| 20321 |
JavaScript
브라우저 해상도 구분없는 절대 x,y 좌표 값 구하기 입니다
|
| 20320 |
PHP
rss 읽어오기 입니다.
|
| 20319 |
JavaScript
자바스크립트로 Ajax 효과내기 입니다.
|
댓글 작성
댓글을 작성하시려면 로그인이 필요합니다.
로그인하기