2011-04-28 42 views
0

我想從SQL注入使用$ wpdb-> prepare()優化SQL;MATCH AGAINST SQL注入預防和wpdb->準備

此查詢不返回任何內容。任何人都可以看到爲什麼或有一個更優雅的選擇。還有必要在MATCH AGAINST語句中轉義搜索條件。

$search_terms = "example search" // input post 
// remove single quotes from search terms 
$search_terms = str_replace("'","",$search_terms); 

$sql = "SELECT 
    post.ID, 
    post.post_author, 
    post.post_date, 
    post.post_title, 
    LEFT(post.post_content, 240) As post_content, 
    post.post_name, 
    post.post_type, 
    post.comment_count, 
    post.comment_status, 
    MATCH (post_search.post_content,post_search.post_title) AGAINST (%s IN BOOLEAN MODE) AS score 
FROM wp_posts post 
LEFT JOIN wp_term_relationships term_rel 
    ON post.ID = term_rel.object_id 
LEFT JOIN wp_term_taxonomy term_tax 
    ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id 
LEFT JOIN wp_terms terms 
    ON term_tax.term_id = terms.term_id 
LEFT JOIN wp_posts_fulltext_search post_search 
    ON post.ID=post_search.post_id 
WHERE MATCH(post_search.post_content,post_search.post_title) AGAINST (%s IN BOOLEAN MODE) && 
    post.post_status = 'publish' && 
    post.post_type = 'post' && 
    (term_tax.description != '' && 
    term_tax.description NOT LIKE '%sample%') 
GROUP BY post.ID 
ORDER BY score DESC 
LIMIT 0,20"; 

$results = $wpdb->get_results($wpdb->prepare($sql, $search_terms)); 

「As分數」用於返回更相關的結果到頂部。只是爲了重申我更關注SQL注入,MATCH AGAINST和wordpress準備功能。

+0

什麼'$ wpdb-> print_error()'顯示,如果有什麼? – 2011-04-28 14:52:09

+0

$ wpdb-> show_errors();什麼都沒顯示 – madphp 2011-04-28 15:04:27

回答

2

不要永遠使用此代碼:

// remove single quotes from search terms 
$search_terms = str_replace("'","",$search_terms); 

這是破的,因爲它並不需要MySQL的編碼考慮。

如果你想逃避,而是使用這樣的:

$search_terms = mysql_real_escape_string($search_terms); 

但要小心!,這隻會轉義值,不是表名而不是字段名。
如果你想查詢操作字段或表名稱的規則是:

  1. 不這樣做,你所要求的SQL注入的麻煩。
  2. 不要用PDO來做,你仍然遇到SQL注入問題。
  3. 閱讀佩卡的回答我的問題:How to prevent SQL injection with dynamic tablenames?

然而
無需轉義,因爲您使用的是事先準備好的聲明。

+0

感謝您的建議。我改變了這一點。當我嘗試使用MATCH AGAINST(%s IN BOOLEAN MODE)和$ wpdb-> prepare時,它仍然不會返回結果。 – madphp 2011-04-28 18:05:54

+0

你是說,如果我使用mysql_real_escape_string()它不是nessecary使用準備好的語句。 – madphp 2011-04-28 18:07:02

+0

@madphp,在使用PDO時不需要使用mysql_real_escape_string()。 PDO比使用mysql_real_escape_string()更安全,但不是100%安全。 – Johan 2011-04-28 20:13:52

0

複製從http://codex.wordpress.org/Function_Reference/wpdb_Class

粘貼防止SQL注入攻擊查詢

對於SQL的WordPress中逃脫一個更完整的概述,請參閱database Data Validation。那Data Validation文章是所有WordPress代碼貢獻者和插件作者必讀的。

簡而言之,SQL查詢中的所有數據必須在執行SQL查詢之前進行SQL轉義,以防止SQL注入攻擊。這可以通過prepare方法方便地完成,該方法同時支持類似於sprintf()和類似vsprintf()的語法。

<?php 
    $sql = $wpdb->prepare('query' [, value_parameter, value_parameter ... ]); 
?> 

查詢
(字符串)要執行的,與%s和%d佔位符的SQL查詢。除非它們被轉義,否則任何其他%字符都可能導致解析錯誤。 SQL字符串文字中的所有%字符(包括LIKE通配符)必須以%%格式轉義%%。 (< < - !!!)

_value_parameter_
(INT |串|陣列)的值替換到佔位符。許多值可以通過簡單地以sprintf()方式傳遞更多參數來傳遞。或者,第二個參數可以是包含值的數組,如在PHP的vsprintf()函數中。必須注意不要讓用戶直接輸入這個參數,這將使數組操作任何帶有多個佔位符的查詢。值不能是SQL轉義的。

例子

添加Meta鍵=>值對 「哈麗雅特的歇後語」=> 「WordPress的數據庫接口就像是星期天的早晨:易」發佈到10.

$metakey = "Harriet's Adages"; 
$metavalue = "WordPress' database interface is like Sunday Morning: Easy."; 

$wpdb->query($wpdb->prepare(" 
    INSERT INTO $wpdb->postmeta 
    (post_id, meta_key, meta_value) 
    VALUES (%d, %s, %s)", 
     10, $metakey, $metavalue)); 

在WordPress中由add_meta()執行。

使用vsprintf()語法的相同查詢。

$metakey = "Harriet's Adages"; 
$metavalue = "WordPress' database interface is like Sunday Morning: Easy."; 

$wpdb->query($wpdb->prepare(" 
    INSERT INTO $wpdb->postmeta 
    (post_id, meta_key, meta_value) 
    VALUES (%d, %s, %s)", 
     array(10, $metakey, $metavalue))); 

(的一部分),你的問題

你沒有翻倍類似聲明逃不過你的 '%'。
變化:

term_tax.description NOT LIKE '%sample%') 

term_tax.description NOT LIKE '%%sample%%')