728x90
PHP 위지윅 에디터를 이용하여 글쓰기를 할 경우 DB에 저장하는 코드 예시이다.
https://link2me.tistory.com/1142 게시글을 참조하면 도움된다.
<?php
if(!isset($_SESSION)){
session_start();
}
// 데이터가 제대로 넘어오는지 검증 목적
//echo '<pre>';print_r($_POST);echo '</pre>';
//echo '<pre>';print_r($_FILES);echo '</pre>';
//exit;
if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){
@extract($_POST);
require_once 'path.php';// root 폴더를 기준으로 상대경로 자동 구하기
require_once $g['path_config'].'config.php';
require_once $g['path_config'].'dbconnect.php';
require_once $g['path_class'].'dbDataClass.php';
require_once $g['path_class'].'dbconnect.php';
require_once $g['path_class'].'adminClass.php';
require_once $g['path_class'].'bbsClass.php';
$a = new adminClass();
$b = new bbsClass();
$d = new LegacyDBClass;
if($mode == 'write'){
$subject = trim($subject);
$subject = preg_replace("/\s{2,}/", " ", $subject); // s(공백문자)가 2회 이상을 1번으로 변경
$subject = $d->XSSFilter($subject);
$content = trim($content);
$content = $b->html_purifier($content);
$filename = NULL;
if ($_FILES['file']['name']) { // 파일이 첨부되어 있으면
$allowed_ext = array('jpg','bmp','png','gif','zip','doc','xls', 'xlsx');
$tmpname = $_FILES['file']['tmp_name']; // 임시파일명
$realname = $_FILES['file']['name']; // 실제 파일명
$filesize = $_FILES['file']['size']; // 파일 크기
$filetype = $_FILES['file']['type']; // 파일 형태
if (!$_FILES['file']['error']) { // 오류 없이 파일 업로드 성공
$fileExt = $b->getExt($realname); // 파일 확장자 구하는 함수
if(!in_array($fileExt, $allowed_ext)) {
@unlink($tmpname);
echo "-1"; // 허용되지 않는 확장자
exit;
} else {
// 새로운 파일을 업로드하면 기존 파일은 삭제 처리
if($idx > 0) {
$R = $d->getDbData('bbs_data','idx='.$idx,'*');
if($R['filename'] != NULL) {
$oldfilename = $g['path_root'].'files/infile/' . $R['filename'];
@unlink($oldfilename);
}
}
// 신규 파일 등록
if (is_uploaded_file($tmpname)){ // 임시파일이 디렉토리에 존재하는 경우
$filename = date("Ymd").md5(uniqid($tmpname)) .round(microtime(true)).'.'.$fileExt;
$uploadFile = $g['path_root'].'files/infile/' . $filename; //change this directory
if(move_uploaded_file($tmpname, $uploadFile)){ // 임시 디렉토리에 있던 파일을 실제 파일의 이름으로 전송
@chmod($uploadFile,0606); // 리눅스에서 파일 권한 변경
}
}
}
}
}
$userID = $_SESSION['userID'];
$userNM = $_SESSION['userNM'];
$html = 1;
$depth = 1;
$notice = 0;
date_default_timezone_set('Asia/Seoul');
if($idx == 0){
$d_regis = date('YmdHis');
$access_ip=$d->getClientIP();
$QKEY = "subject,content,html,depth,filename,notice,d_regis,userID,userNM,ip";
$QVAL = "'$subject','$content',$html,$depth,'$filename',$notice,'$d_regis','$userID','$userNM','$access_ip'";
$d->getDbInsert('bbs_data',$QKEY,$QVAL);
echo 1;
} else {
$idx = $d->XSSFilter($idx);
// 등록자 여부 체크
$R = $d->getDbData('bbs_data','idx='.$idx,'*');
if($R['userID'] === $_SESSION['userID']){ // 등록자만 수정 가능하며 관리자도 수정은 불가
$QSET="subject='".$subject."',";
$QSET.="content='".$content."',";
$QSET.="filename='".$filename."',";
$QSET.="html='".$html."'";
$QVAL="idx='".$idx."'";
$d->getDbUpdate('bbs_data',$QSET,$QVAL);
echo 2;
} else {
echo -2;
}
}
} else if($mode == 'delete'){
$d->getDbDelete('bbs_data',"idx='".$idx."'");
echo 3; // 삭제
}
} else {
echo -1;
}
?>
|
여기서 더 신경써야 할 사항은
realname 을 DB 칼럼에 추가로 저장하는 것이다.
그래야 파일 다운로드할 때 실제 서버에 저장된 파일명과 다운로드되는 파일명이 달라서 해킹 시도 자체를 방지하는 것이 된다.
최근에는 그누보드 소스코드를 분석해보니 html_purifier 를 이용하여 악성코드를 걸러내고 있는 거 같다.
아래 코드는 위에 사용하는 Class 내에 있는 함수들 중에서 일부 발췌하였다.
<?php
class bbsClass extends DBDataClass {
function conv_content($content){
$source = array();
$target = array();
$source[] = "//";
$target[] = "";
$source[] = "/\n/";
$target[] = "<br/>";
// 테이블 태그의 개수를 세어 테이블이 깨지지 않도록 한다.
$table_begin_count = substr_count(strtolower($content), "<table");
$table_end_count = substr_count(strtolower($content), "</table");
for ($i=$table_end_count; $i<$table_begin_count; $i++)
{
$content .= "</table>";
}
$content = preg_replace($source, $target, $content);
$content = $this->html_purifier($content);
$content = str_replace('<A href=','<a target="_blank" href=',$content);
$content = str_replace('<a href=','<a target="_blank" href=',$content);
return $content;
}
function html_purifier($html){
// 절대경로 지정
//include_once('/home/httpd/htdocs/vendor/ezyang/htmlpurifier/library/HTMLPurifier.auto.php');
// 상대경로 지정
include_once('../vendor/ezyang/htmlpurifier/library/HTMLPurifier.auto.php');
$config = HTMLPurifier_Config::createDefault();
// data/cache 디렉토리에 CSS, HTML, URI 디렉토리 등을 만든다.
$config->set('Attr.EnableID', false);
$config->set('Attr.DefaultImageAlt', '');
// 인터넷 주소를 자동으로 링크로 바꿔주는 기능
$config->set('AutoFormat.Linkify', true);
// 이미지 크기 제한 해제 (한국에서 많이 쓰는 웹툰이나 짤방과 호환성 유지를 위해)
$config->set('HTML.MaxImgLength', null);
$config->set('CSS.MaxImgLength', null);
$config->set('Core.Encoding', 'UTF-8'); // 인코딩
$config->set('HTML.SafeEmbed', false);
$config->set('HTML.SafeObject', false);
$config->set('Output.FlashCompat', false);
$config->set('HTML.SafeIframe', true);
$config->set('Attr.AllowedFrameTargets', array('_blank'));
$purifier = new HTMLPurifier($config);
return $purifier->purify($html);
}
// 파일 확장자 추출
function getExt($filename){
$ext = substr(strrchr($filename,"."),1); // 공격방어 감지를 위해 콤마의 취지를 뒤에서부터 검색
// strrchr(문자열, 찾을 문자) : 찾을 문자가 마지막으로 나온 위치부터 끝까지 반환
// strstr(문자열, 찾을 문자) : 찾을 문자열이 나온 처음 위치부터 끝까지 반환.
$ext = strtolower($ext); // 확장자 소문자로 변환
return $ext;
}
}//end class boardClass
|
728x90
'Web 프로그램 > 테이블, 게시판, 검색' 카테고리의 다른 글
PHP 위지윅 에디터 파일 다운로드 (0) | 2023.07.02 |
---|---|
PHP 위지윅 에디터 View (0) | 2023.07.02 |
PHP 위지윅 에디터 글쓰기 기능 (0) | 2023.06.28 |
bootstrap4 paging with PHP (0) | 2022.02.27 |
XSS(cross-site scripting) filtering function in PHP (0) | 2018.05.01 |