2011-03-04 4 views
6

MySQL 테이블 "페이지"에서 전체 텍스트 검색을 수행하고 있습니다. "title"(일반 텍스트, VARCHAR, 255) 또는 "content"(html, TEXT)에 키워드와 일치하는 페이지 목록을 표시하고 있습니다. '콘텐츠'입력란에 일치하는 항목이 있으면 해당 일치 항목을 발견 한 스 니펫을 표시하고 싶습니다. 나는 이것에 대해 어떻게 생각하는지 모른다.PHP (및 보안)에서 MySQL fulltext 검색의 일치 컨텍스트 검색

나를 올바른 방향으로 놓을 수 있습니까?

$query = ' SELECT 
       *, 
       MATCH(title, content) AGAINST("'.$keyword.'") AS score 
      FROM 
       page 
      WHERE 
       MATCH(title, content) AGAINST("'.$keyword.'") 
      ORDER BY 
       score 
      DESC '; 
$result = mysql_query($query) or die (mysql_error()); 
if(mysql_num_rows($result) > 0) { 
    $output .= '<p>Your keyword matches the following pages:</p>'; 
    while($row = mysql_fetch_assoc($result)){ 

     $title  = htmlentities($row['title']); 
     $content = htmlentities(strip_tags($row['content'])); 
     $content = limit_text($content, 250); // Cuts it down to 250 characters plus ... 

     $output .= '<h2>'.$title.'</h2>'; 
     if(trim($content) != '') { 
      $output .= '<p>'.$content.'</p>'; // I'd like to place a snippet here with the matched context 
     }   
    } 
} else { 
    $output .= '<p>Keyword not found...</p>';  
} 

또한 보안 관련 질문이 있습니다. 지금은 다음과 같은 세 가지 방법으로 을 확인하고 있습니다.

  • 비어 있지 않습니까?
  • 2 자 이상?
  • 위험하지 않습니까? 사용자 입력이 위험한 경우

내가

<script|&lt;script|&gt;script|document.|alert|bcc:|cc:|x-mailer:|to:|recipient|truncate|drop table 

이 주위에 일을 조금 말도 쉽게 수 있습니다 확인하려면 다음과 일치하는 정규 표현식을 사용 (아래 참조)하지만, XSS 공격에 대한 최소한의 보호 방법입니다. 검색을 위해 키워드를 필터링하기 위해 권장되는 방법은 무엇입니까? PHPIDS 잔인한가요? 먼저 청소

<?php 
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); 
$stmt->bindParam(':name', $name); 
$stmt->bindParam(':value', $value); 

// insert one row 
$name = 'one'; 
$value = 1; 
$stmt->execute(); 

// insert another row with different values 
$name = 'two'; 
$value = 2; 
$stmt->execute(); 
?> 
+0

질문의 보안 부분에 대한 응답으로 가능한 경우 [PDO] (http://php.net/manual/en/ref.pdo-mysql.php)를 사용하십시오. 그렇지 않으면 최소한 mysql_real_escape_string()을 통해'$ keyword'를 실행해야합니다. – glomad

+0

xss 보호 기능이 약합니다. mysql_query()는 쿼리 스태킹을 허용하지 않기 때문에'drop table'은 **이 코드를 공격 할 수 없다고 말할 수있다. – rook

+0

@itchy 감사합니다.'PDO'를 조사 하겠지만, 지금은 mysql_real_escape_string()을 사용합니다. 감사합니다. @ 루크, 당신의 통찰력에 감사드립니다, 나는 이것을 깨닫습니다. 그래서 나는 대안을 찾고 있습니다. – maartenmachiels

답변

6

이렇게하면 "문맥 "일부 ...

// return the part of the content where the keyword was matched 
function get_surrounding_text($keyword, $content, $padding) 
{ 
    $position = strpos($content, $keyword); 
    // starting at (where keyword was found - padding), retrieve 
    // (padding + keyword length + padding) characters from the content 
    $snippet = substr($content, $position - $padding, (strlen($keyword) + $padding * 2)); 
    return '...' . $snippet . '...'; 
} 

$content = 'this is a really long string of characters with a magic word buried somewhere in it'; 
$keyword = 'magic'; 
echo get_surrounding_text($keyword, $content, 15); // echoes '... string with a magic word in it...' 

이 기능은 패딩 경계가 키워드가 컨텐츠의 시작이나 끝 부분에서 발견되었을 때처럼 콘텐츠 문자열 밖에 갈 것입니다 경우에 고려하지 않습니다. 또한 여러 경기 등을 설명하지 않습니다. 그러나 적어도 올바른 방향으로 당신을 가리켜 주길 바랍니다.

2

$keywords 변수를 직접 필터링하려고하기보다는, 당신은 단순히 prepared statement 결코 잠재적 인 누락에 대해 걱정 A가 악용 사용할 수 있습니다 내가 당신이라면. 레코드의 경우 $ keyword에 모든 단어를 배열에 넣으므로 필요한 경우 boolean search을 사용할 수 있습니다. (모든 단어 앞에 +를 붙이면 효과가 나타남)

+0

고마워요 ...이 튜토리얼은 http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/에서 찾았습니다. PDO에서 시작되었습니다. – maartenmachiels

0

내가 아마 함수에 $ 키워드를 얻을 것입니다 :