$wpdb->query Wordpress shortcode causing syntax error - mysql

I'm trying to update numerous wordpress multisite pages.
I have an ajax script that is posting to a php file where, after the text is formatted, it updates the corresponding table cell.
However, I keep getting the "WordPress database error You have an error in your SQL syntax;" error.
$content = "[shortcode] text processed by shortcode [/shortcode]";
$table = "wp_".$_POST["blogid"]."_posts";
$wpdb->query(" UPDATE {$table} SET post_content={$content} WHERE posts_title='test'");
Is this an issue with the use of square brackets (shortcodes) in the string I wish to use to update the cell?
The syntax seems fine to me, but my SQL knowledge isn't that strong.
In greater detail, I have a mysql query that gets all multisites, then loops through them after making the edits with JS before posting to this php file.

Avoid using string templates directly for query building. You can too-easily include invalid syntax, and since you're reading content directly from the shortcode you're opening your entire database up to SQL-injection attacks. This could give attackers direct access to your database, meaning anyone who can post content could also gain total access to your WordPress.
Always prepare your query first. If you're using $wpdb, the usage is described here: https://developer.wordpress.org/reference/classes/wpdb/prepare/
This will also ensure that the shortcode content you query on is formatted properly.

Related

Building a query in PDO with parameters for table name [duplicate]

This is my PHP SQL statement and it's returning false while var dumping
$sql = $dbh->prepare('INSERT INTO users(full_name, e_mail, username, password) VALUES (:fullname, :email, :username, :password)');
$result = $sql->execute(array(
':fullname' => $_GET['fullname'],
':email' => $_GET['email'],
':username' => $_GET['username'],
':password' => $password_hash));
TL;DR
Always have set PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION in your PDO connection code. It will let the database tell you what the actual problem is, be it with query, server, database or whatever. Also, make sure you can see PHP errors in general.
Always replace every PHP variable in the SQL query with a question mark, and execute the query using prepared statement. It will help to avoid syntax errors of all sorts.
Explanation
Sometimes your PDO code produces an error like Call to a member function execute() or similar. Or even without any error but the query doesn't work all the same. It means that your query failed to execute.
Every time a query fails, MySQL has an error message that explains the reason. Unfortunately, by default such errors are not transferred to PHP, and all you have is a silence or a cryptic error message mentioned above. Hence it is very important to configure PHP and PDO to report you MySQL errors. And once you get the error message, it will be a no-brainer to fix the issue.
In order to get the detailed information about the problem, either put the following line in your code right after connect
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
(where $dbh is the name of your PDO instance variable) or - better - add this parameter as a connection option. After that all database errors will be translated into PDO exceptions which, if left alone, would act just as regular PHP errors.
After getting the error message, you have to read and comprehend it. It sounds too obvious, but learners often overlook the meaning of the error message. Yet most of time it explains the problem pretty straightforward:
Say, if it says that a particular table doesn't exist, you have to check spelling, typos, letter case. Also you have to make sure that your PHP script connects to a correct database
Or, if it says there is an error in the SQL syntax, then you have to examine your SQL. And the problem spot is right before the query part cited in the error message.
You have to also trust the error message. If it says that number of tokens doesn't match the number of bound variables then it is so. Same goes for absent tables or columns. Given the choice, whether it's your own mistake or the error message is wrong, always stick to the former. Again it sounds condescending, but hundreds of questions on this very site prove this advice extremely useful.
Note that in order to see PDO errors, you have to be able to see PHP errors in general. To do so, you have to configure PHP depends on the site environment:
on a development server it is very handy to have errors right on the screen, for which displaying errors have to be turned on:
error_reporting(E_ALL);
ini_set('display_errors',1);
while on a live site, all errors have to be logged, but never shown to the client. For this, configure PHP this way:
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
Note that error_reporting should be set to E_ALL all the time.
Also note that despite the common delusion, no try-catch have to be used for the error reporting. PHP will report you PDO errors already, and in a way better form. An uncaught exception is very good for development, yet if you want to show a customized error page, still don't use try catch for this, but just set a custom error handler. In a nutshell, you don't have to treat PDO errors as something special but regard them as any other error in your code.
P.S.
Sometimes there is no error but no results either. Then it means, there is no data to match your criteria. So you have to admit this fact, even if you can swear the data and the criteria are all right. They are not. You have to check them again. I've short answer that would help you to pinpoint the matching issue, Having issue with matching rows in the database using PDO. Just follow this instruction, and the linked tutorial step by step and either have your problem solved or have an answerable question for Stack Overflow.
Some time ago I had the same problem of not seeing any error messages from mysql. After a research it turned out that the problem has got nothing to do with PHP itself, but with mysql server configuration. The default value of the variable lc_messages_dir pointed to non existing directory. After adding a line in mysqld.cnf, then restarted the mysql server, and finally I was able to see the error messages. For me the following was the right one:
lc_messages_dir=/usr/share/mysql
It is described in the mysql reference manual: https://dev.mysql.com/doc/refman/5.7/en/error-message-language.html

Replace shortcode in SQL database

I'm trying replace this shortcode
[RICH_REVIEWS_SHOW category=”all” num=”6″]
with this shortcode
[site_reviews summary count="3" hide="date"] in a wordpress database.
I've tried the plugin "better search and replace" but no luck.
I've also tried using this code via the cpanel.
update wplq_posts set post_content =
replace(post_content,'[RICH_REVIEWS_SHOW category=”all” num=”6″]','[site_reviews summary count="3" hide="date"]');
Initially no matches, if I remove certain parts of the shortcode I get some results. I'm a bit lost as to what will get the job the job done.
Can anyone point me in the right direction.
Thanks in advance.
The SQL in your example is correct.
A likely explanation for the issue is that the double-quotes within the [RICH_REVIEWS_SHOW category=”all” num=”6″] do not match the double quotes used within the shortcode stored in the post_content table.
For example ” vs ″ vs "
I suggest finding a post manually that has this shortcode and copying that that shortcode into the SQL query. Then try again.

SQL Injection on update query

So I have a server set up to serve payment requests. A user enters their credit card details in a form.
Query to inject here:
$sql = "UPDATE users SET credit_card'".$credit_card."', cvv='".$cvv."', expdate='".$exp."' WHERE userid='".$_SESSION['userid']."'";
I am trying to change another users password from this query.
Where the $credit_card is posted from a form. Im trying to inject the $credit_card part by writing my own query and getting rid of the rest by adding ;-- to the end.
The statement I am using for $credit_card is :
', password='test' where userid='10';--
Now, I am positive this was working yesterday but now the following error appears and I cannot wrap my head around it. Any help please?
Query failed: UPDATE users SET credit_card'', password='test' WHERE userid='20';--, cvv='', expdate='' WHERE userid='20'
Not all database functions accept multiple statements so the ; delimiter may be considered unexpected input.
The syntax for single-line comments in MySQL is -- Foo (please note the white space after the double-dash).
If the server code is yours, you can just print the actually error message generated by the server (and not some generic "something went wrong" text). If it isn't, just copy and paste the SQL code from the error message into your favourite MySQL client.

PHP PDO - Empty Page [duplicate]

This is my PHP SQL statement and it's returning false while var dumping
$sql = $dbh->prepare('INSERT INTO users(full_name, e_mail, username, password) VALUES (:fullname, :email, :username, :password)');
$result = $sql->execute(array(
':fullname' => $_GET['fullname'],
':email' => $_GET['email'],
':username' => $_GET['username'],
':password' => $password_hash));
TL;DR
Always have set PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION in your PDO connection code. It will let the database tell you what the actual problem is, be it with query, server, database or whatever. Also, make sure you can see PHP errors in general.
Always replace every PHP variable in the SQL query with a question mark, and execute the query using prepared statement. It will help to avoid syntax errors of all sorts.
Explanation
Sometimes your PDO code produces an error like Call to a member function execute() or similar. Or even without any error but the query doesn't work all the same. It means that your query failed to execute.
Every time a query fails, MySQL has an error message that explains the reason. Unfortunately, by default such errors are not transferred to PHP, and all you have is a silence or a cryptic error message mentioned above. Hence it is very important to configure PHP and PDO to report you MySQL errors. And once you get the error message, it will be a no-brainer to fix the issue.
In order to get the detailed information about the problem, either put the following line in your code right after connect
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
(where $dbh is the name of your PDO instance variable) or - better - add this parameter as a connection option. After that all database errors will be translated into PDO exceptions which, if left alone, would act just as regular PHP errors.
After getting the error message, you have to read and comprehend it. It sounds too obvious, but learners often overlook the meaning of the error message. Yet most of time it explains the problem pretty straightforward:
Say, if it says that a particular table doesn't exist, you have to check spelling, typos, letter case. Also you have to make sure that your PHP script connects to a correct database
Or, if it says there is an error in the SQL syntax, then you have to examine your SQL. And the problem spot is right before the query part cited in the error message.
You have to also trust the error message. If it says that number of tokens doesn't match the number of bound variables then it is so. Same goes for absent tables or columns. Given the choice, whether it's your own mistake or the error message is wrong, always stick to the former. Again it sounds condescending, but hundreds of questions on this very site prove this advice extremely useful.
Note that in order to see PDO errors, you have to be able to see PHP errors in general. To do so, you have to configure PHP depends on the site environment:
on a development server it is very handy to have errors right on the screen, for which displaying errors have to be turned on:
error_reporting(E_ALL);
ini_set('display_errors',1);
while on a live site, all errors have to be logged, but never shown to the client. For this, configure PHP this way:
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
Note that error_reporting should be set to E_ALL all the time.
Also note that despite the common delusion, no try-catch have to be used for the error reporting. PHP will report you PDO errors already, and in a way better form. An uncaught exception is very good for development, yet if you want to show a customized error page, still don't use try catch for this, but just set a custom error handler. In a nutshell, you don't have to treat PDO errors as something special but regard them as any other error in your code.
P.S.
Sometimes there is no error but no results either. Then it means, there is no data to match your criteria. So you have to admit this fact, even if you can swear the data and the criteria are all right. They are not. You have to check them again. I've short answer that would help you to pinpoint the matching issue, Having issue with matching rows in the database using PDO. Just follow this instruction, and the linked tutorial step by step and either have your problem solved or have an answerable question for Stack Overflow.
Some time ago I had the same problem of not seeing any error messages from mysql. After a research it turned out that the problem has got nothing to do with PHP itself, but with mysql server configuration. The default value of the variable lc_messages_dir pointed to non existing directory. After adding a line in mysqld.cnf, then restarted the mysql server, and finally I was able to see the error messages. For me the following was the right one:
lc_messages_dir=/usr/share/mysql
It is described in the mysql reference manual: https://dev.mysql.com/doc/refman/5.7/en/error-message-language.html

Accessing protected mysql names via ASP

Currently, I've been assisting someone to convert a site using classic ASP, from using MS Access to MySQL(mainly as a bridge until we get time to do a complete rebuild). The current table uses various protected keywords as column names(Datetime, Date, Order, etc). I'm trying to figure out the proper ways to do a few inserts on these columns. The current code is below:
Set oRSess = Server.CreateObject("ADODB.Recordset")
oRSess.AddNew
oRSess.Fields("Order") = CInt(xyz)
oRSess.Fields("SessionID")
oRSess.Update
Now normally, I'd try to just replace this with a standard SQL insert, but there's lots of code around, that breaks easily. Is there away to add a proper escape character for MySQL to recognize it properly?