'Tip/PHP'에 해당하는 글 8건

OCIEnvNlsCreate() failed

Tip/PHP 2013. 4. 24. 22:59

php 에서 오라클 연결시 오류 발생 (apache2.2.22 / php5.3.14)

 

oci_connect() function.oci-connect: OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and LD_LIBRARY_PATH are set and point to the right directories in /home/oops4u/www/db.php on line 3

 

ORACLE_HOME 이랑 LD_LIBRARY_PATH 가 설정이 안됐나; 오디에??
언젠가 아무 설정 없이도 잘 됐던거 같은데 ㅜㅜ
음... 페이지 권한 때문인가? oracle:oinstall 로 바꿔보고 /etc/group 도 바꿔보고 했더니.
되네? ㅋㅋㅋㅋㅋㅋㅋㅋ 조금지나 새로고침(F5) 했더니 다시 안되네? 되다? 안되다?
머 이런게 다 있노;; 되려면 확실하게 되고 말려면 말 것이지.

 

 

하지만 역시 정답은 저 에러 메시지 안에 있었음. apache 환경 변수 추가.

 

# vi /usr/local/httpd/bin/envvars

 

ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE
ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1; export ORACLE_HOME
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib; export LD_LIBRARY_PATH

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

PHP Security

Tip/PHP 2012. 12. 12. 00:10

1. 외부/입력 데이터 처리

 

GET/POST/COOKIE/SESSION 변수, DB, php config 등으로 전달되는 데이터는 변조될 수 있으므로 정규식을 사용하여 입력 처리.

 

function cleanInput($input){
    $clean = strtolower($input);
    $clean = preg_replace("/[^a-z]/", "", $clean);
    $clean = substr($clean,0,12);
    return $clean;
}

 

$userId = cleanInput($_POST['userid']);

 

입력받은 $_POST['userid'] 변수의 형식이 영문(소문자), 12자 이내로만 이루어져야 한다면,
위와 같이, 입력 변수를 체크할 수 있도록 처리합니다.
특히 사용자 입력값에 길이 제한을 두는 것은 여러 공격에 대하여 방지해 줍니다.

 

 

2. PHP config 의 보안 설정

 

php.ini 파일 편집

 

register_globals = off  
// GET,POST,COOKIE,SESSION,SERVER 등의 변수 공유 악용 방지
// php5.3 deprecated, 5.4 removed)

 

display_errors = off
// 오류정보 출력에 대한 악용 방지.
// 개발시에는 많은 오류가 보고되는 것이 좋지만, 완료 후에는 오류 대신에 파일로 대체.

 

 

3. SQL Injection 공격 회피

 

where username = '{$_GET['username'}' and password = '{$_GET['password']}' 의 경우
$_GET['password'] 에 악의적인 코드를 삽입하여 쿼리를 통과할 수 있습니다.
password 입력 항목에 ' or '1'='1 이라고 입력한다면,
where username = '' and password = '' or '1'='1' 이 되어 무조건 통과하게 됩니다.
이를 방지하기 위해 입력 값에 mysql_real_escape_string 함수를 사용하여 '등의 특수문자를 회피할 수 있도록 합니다.

 

 

4. 버퍼 오버플로우 공격 방지

 

특정 버퍼를 전복시키거나 다음 버퍼에 악성 코드를 삽입하여 데이터를 손상시키는 오버플로우에 대해서는 데이터 길이 제한을 두고,
16진 문자열에 대해서는 이 문자열을 제거하는 정규식을 추가합니다.

 

function cleanHex($input){
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
    return $clean;
}

 

$name = cleanHex($_POST['name']);

 

 

5. 교차 사이트 스크립팅(XSS) 공격 방지

 

사용자 입력 폼에서 이름, 이메일, 내용 등을 넣을 때 악성 스크립트로 쿠키 등의 정보를 훔칠 수 있습니다.
전달된 값에 태그 변환 strip_tags(), HTML 엔티티 변환 htmlspecialchars() 등을 사용해 공격을 차단하도록 합니다.

 

 

6. 원격 폼 전송 차단

 

폼 페이지를 저장하여 타 사이트에 게재하고 form action 값을 위장할 수 있습니다.
HTTP_REFERER 을 확인할 수도 있으나 가장 좋은 대처 방법은,
토큰을 생성하여 session 변수와 폼에 배치시키고 전송 뒤에 이 값들을 확인하는 방법입니다.
토큰을 무작위로 작성하려면 md5(), uniqid(), rand() 함수를 사용해야 합니다.

 

#form.php
$token = md5( uniqid( rand(), true ) );
$_SESSION['token']= $token;

 

<input type="hidden" name="token" value="<?=$token?>"/>

 

#action.php
if ( $_SESSION['token'] != $token ) {
    die( 'Invalid token!' );
}


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

보안서버 구축시에 필요시 프로토콜 전환 작업이 필요합니다. http <-> https
로그인은 다음과 같은 처리 순서를 가집니다.

 

  1. http 로그인 폼에서 사용자로부터 입력을 받습니다.
  2. https 전달된 정보(id/pw)를 체크합니다.
  3. http return url로 이동합니다.

 

사용자 입력이 올바르다면 3번 과정에서 로그인 된 페이지가 출력되야 하는데,
IE에서는 로그인으로 나오지만, chrome, firefox 등에서는 로그인이 되지 않은 페이지가 출력됩니다.

 

결론적으로,

 

  1. http 는 로그인 되지 않은 상태.
  2. https 는 로그인이 된 상태.

 

몇몇 브라우저에서 http <-> https 간에 세션 공유를 못하는 것이 원인.

 

다음과 같이 해결 하였습니다.

 

  1. http 로그인 폼에서 사용자로부터 입력을 받고, https 로 전송할 때 session_id 값을 같이 전달합니다.
  2. https 에서 전달받은 session_id으로 session_id를 재설정합니다.

 

//https page
<? session_id( $_GET['sess_key'] ); ?>

 

주의할 것은 session_id() 설정은 session_start() 보다 먼저 와야 합니다.


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,
한 8시간 가량 삽질했더니, 목이 매우 뻐근하군...
삽질 주제는 어김없이 찾아온 인코딩 UTF-8.
물론 UTF-8의 기본적인 인코딩 설정은 정상적으로 마치고, php에서 DB와의 한글 입출력을 했는데, '???? 궭걐궹...' 이 즈랄..
엄청난 시간을 투자해서 문제를 해결해 보려고 했지만, 방법이 구리다.

- 일단 터미널에서 찍어본 mysql 인코딩 정보
mysql> show variables like 'c%';
+--------------------------+----------------------------+

| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8_general_ci            |
| collation_database       | utf8_general_ci            |
| collation_server         | utf8_general_ci            |
| completion_type          | 0                          |
| concurrent_insert        | 1                          |
| connect_timeout          | 5                          |
+--------------------------+----------------------------+

- php로 DB접속 한 후 브라우저에서 확인한 문제의 mysql 인코딩 정보
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | latin1_swedish_ci          |
| collation_database       | utf8_general_ci            |
| collation_server         | utf8_general_ci            |
| completion_type          | 0                          |
| concurrent_insert        | 1                          |
| connect_timeout          | 5                          |
+--------------------------+----------------------------+

엄청난 시간을 들여 인터넷을 다 휘집어 나온 해결방법은...
db 접속 하자마자 수작업으로 열심히 변경시켜 주는 방법.
$conn = mysql_connect( 'localhost', 'user_id', 'user_pass' );

mysql_query( "set character_set_client = utf8;" );
mysql_query( "set character_set_connection = utf8;" );
mysql_query( "set character_set_results = utf8;" );

가장 중요한 건 utf8이 latin1로 바뀐 원인을 모르겠다.
죽어도 모르겠다. 죽여도 모르겠다...

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

print VS echo

Tip/PHP 2007. 10. 8. 20:13
공통점
  • 문자열을 출력한다.
  • 실제 함수가 아닌 언어 구조이므로, 가변함수 방식으로 호출할 수 없고 괄호를 사용할 필요가 없다.

차이점
  • void echo ( string arg1 [, string argn...] )
  • int print ( string arg )
  • print를 함수처럼 호출하면 1을 반환한다.
  • print는 대체로 echo보다 느리다.

ex)
// print는 함수이다.
($some_var) ? print('true') : print('false');

// echo는 함수가 아니므로, 다음 코드는 유효하지 않다.
// Parse error: parse error, unexpected T_ECHO
($some_var) ? echo 'true' : echo 'false';

echo $some_var ? 'true': 'false'; // 구문을 변경하여 처리

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,