1

I create one custom plugin and submit for review to wordpress.org. But the give me test log they says Unsafe SQL calls

`includes/databases/class-stepup-user-crud.php:313 $sql_orders = $wpdb->prepare(
"
SELECT p.*
FROM {$db->tb_posts} p
INNER JOIN {$db->tb_postmeta} pm ON p.ID = pm.post_id AND meta_key = %s AND (meta_value = %d OR meta_value like '%s')
",
'_user_id',
$user_id,
$user_id_str
);
includes/databases/class-stepup-user-crud.php:338 $sql = $sql_orders /* . ' UNION ' . $sql_guest_orders */ . $sql_rest;
includes/databases/class-stepup-user-crud.php:341 $order_posts = $db->wpdb->get_results($sql);
# There is a call to a wpdb::prepare() function, that's correct.
# You cannot add variables like "$db->tb_posts" directly to the SQL query.
# Using wpdb::prepare($query, $args) you will need to include placeholders for each variable within the query and include the variables in the second parameter.
# The SQL query needs to be included in a wpdb::prepare($query, $args) function.`

I added $db->tb_posts in global class.

they says do not use variable like these

You cannot add variables like "$db->tb_posts" directly to the SQL query

Please help me.

I read these content https://www.wordfence.com/blog/2025/08/how-to-find-sql-injection-vulnerabilities-in-wordpress-plugins-and-themes/

some document says use $wpdb::prapare() and I already used it but not found correct solution.

These is my query

    $sql_orders = $wpdb->prepare( "SELECT p.* FROM {$db->tb_posts} p INNER JOIN {$db->tb_postmeta} pm ON p.ID = pm.post_id AND meta_key = %s AND (meta_value = %d OR meta_value like '%s')", '_user_id',$user_id,$user_id_str); 
$sql = $sql_orders . $sql_rest; 
$order_posts = $db->wpdb->get_results($sql); 
11
  • Go check global variables provided from WordPress such as $wpdb. Why you define $db when you already have $wpdb ? Also $db->tb_posts should be $wpdb->posts same for the meta. If you insist on using your own keep in mind that you must whitelist and escape table names manually before inserting them into your query. You will be flaged for stuff like that if you dont follow the guidelines. Commented Sep 29, 2025 at 7:54
  • @Snuffy can you guide me which type of escape I required here? Commented Sep 29, 2025 at 8:21
  • If you provide some code to look up. WIth this its unclear what you define how and so on. Commented Sep 29, 2025 at 8:47
  • @Snuffy $sql_orders = $wpdb->prepare( "SELECT p.* FROM {$db->tb_posts} p INNER JOIN {$db->tb_postmeta} pm ON p.ID = pm.post_id AND meta_key = %s AND (meta_value = %d OR meta_value like '%s')", '_user_id',$user_id,$user_id_str); $sql = $sql_orders . $sql_rest; $order_posts = $db->wpdb->get_results($sql); # You cannot add variables like "$db->tb_posts" directly to the SQL query. # Using wpdb::prepare($query, $args) you will need to include placeholders for each variable within the query and include the variables in the second parameter. Commented Sep 29, 2025 at 8:58
  • Please edit your question and add the code. Dont post in comments. Commented Sep 29, 2025 at 9:25

1 Answer 1

1

Yes, the plugin team has cracked down on using variable interpolation in SQL statements. They are trying to avoid SQL injection. That is a worthy goal.

$wpdb->prepare() now offers the %i placeholder for identifiers like table names. So try something like this:

$sql_orders = 'SELECT p.* FROM %i p INNER JOIN %i pm ON p.ID = pm.post_id AND meta_key = %s AND (meta_value = %d OR meta_value like \'%s\'';
$sql_orders = $wpdb->prepare( $sql_orders, 
                              $db->tb_posts, $db->tb_postmeta,
                              '_user_id', $user_id, $user_id_str ); 
$sql = $sql_orders . $sql_rest; 
$order_posts = $db->wpdb->get_results($sql); 

There's a catch with this, though. It only works in WordPress 6.2 and higher. So you'll need to set this Requires at least: 6.2 in your readme.txt.

A remark:

It looks like you're searching for a numeric postmeta value. Rather than writing your own query, you might want to investigate using the WP_Query class with WP_Meta_Query. It covers the numeric issue you address with your OR clause correctly. And the plugin review team won't have as many problems with it

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.