I come across this sql code in a php software.
What does the #section_filter mean?
Is that a valid mysql syntax? or just a templating system?
$filterid = ac_sql_select_one("
SELECT
id
FROM
#section_filter
WHERE
userid = '$ary[userid]'
AND
sectionid = 'article'
AND
conds = '$conds_esc'
");
Thanks
It is a valid sql syntax but the problem i suspect is that hash # character creates comments in sql queries hence this query might not execute.
Another possiblity is that the program that you saw this query in should be able to dynamically replace the #section_filter with some table name before it gets to mysql engine and then the query should run fine. This is the highest possibility in my view.
The # symbol is one way to express a comment in MySQL. So, this isn't a valid SQL statement as written, since the line:
#section_filter
would be completely ignored.
Related
I'm using a PHP webservice where I have performed a simple SELECT query, and stored it
$result = run_query($get_query);
I now need to perform further querying on the data based on different parameters, which I know is possible via MySQL in the form:
SELECT *
FROM (SELECT *
FROM customers
WHERE CompanyName > 'g')
WHERE ContactName < 'g'
I do know that this performs two Select queries on the table. However, what I would like to know is if I can simply use my previously saved query in the FROM section of the second section, such as this, and if my belief that it helps performance by not querying the entire database again is true:
SELECT *
FROM ($result)
WHERE ContactName < 'g'
You can make a temp table to put the initial results and then use it to select the data and in the second query. This will work faster only if your 1-st query is slow.
PHP and SQL are different languages and very different platforms. They often don't even run in the same computer. Your PHP variables won't interact at all with the MySQL server. You use PHP to create a string that happens to contain SQL code but that's all. In the end, the only thing that counts is the SQL code you sent to the server—how you manage to generate it is irrelevant.
Additionally, you can't really say how MySQL will run a query unless you obtain an explain plan:
EXPLAIN EXTENDED
SELECT *
FROM (SELECT *
FROM customers
WHERE CompanyName > 'g')
WHERE ContactName < 'g'
... but I doubt it'll read the table twice for your query. Memory is much faster than disk.
Thanks for the responses, everyone. Turns out what I was looking for was a "query of query", which isn't supported directly by PHP but I found a function over here which provides the functionality: http://www.tom-muck.com/blog/index.cfm?newsid=37
That was found from this other SO question: Can php query the results from a previous query?
I still need to do comparisons to determine whether it improves speed.
If I understand your question correctly you want to know whether saving the "from" part of your SQL query in a php variable improves the performance of you querying your SQL server, then the answer is NO. Simply because the variable keeping the value is inserted into the query.
Whether performance is gained in PHP, the answer is most probable yes; but depends on the length of the variable value (and how often you repeat using the variable instead of building a new complete query) whether the performance will be notable.
Why not just get this data in a single query like this?
SELECT *
FROM customers
WHERE CompanyName > 'g'
AND ContactName < 'g'
I am using MeekroDB (http://www.meekro.com/quickstart.php) to construct simple MySQL queries in PHP. Even simple queries are being rejected due to incorrect syntax. I noticed by writing queries manually in phpMyAdmin that queries are rejected if they use this syntax:
SELECT * FROM 'table name'
But accepted if they use this syntax:
SELECT * FROM `table name`
The only difference is a slightly different apostrophe. MeekroDB seems to be producing the first syntax by default, which is causing the queries to be rejected. Has anyone faced this before? Any solutions? I'm using WAMP Server and MySQL 5.5.24.
Note: Queries generated by MeekroDB are working if they do not contain an apostrophe or if the second apostrophe type is inserted manually. So:
$result = DB::query("SELECT DISTINCT `column` FROM `table`")
works but:
$result = DB::query("SELECT DISTINCT %s FROM %s", "column","table")
doesn't.
I hadn't heard about MeekroDB but it appears to be a simple database abstraction layer. Your second example:
$result = DB::query("SELECT DISTINCT %s FROM %s", "column","table")
... is invalid because neither "column" nor "table" are literal strings you want to inject. They're column/table names that are part of the SQL statement, not user-provided parameters.
This is a basic concept in most programming languages. SELECT foo is different from SELECT 'foo' in SQL for the same reason that echo md5(1); is different from echo 'md5(1)'; in PHP.
Update:
I suspect I wasn't clear enough. Using prepared statements to bind language constructs or object names is a misuse of any database library, MeekroDB or not. You are supposed to bind parameters that represent values, esp. those entered by end users, so you the value does not leak into SQL and breaks the query or change its meaning. But there're normally no tools to inject SQL commands or table names—they'd be of little use: if you allow the user to build arbitrary SQL queries, he's already been granted the power to do almost anything he wants.
Well since PHP doesn't treat strings the same way other languages do this is a somewhat bad idea. In essence they have tried to make it easier for developers but doesn't always happen. In reality what you could do is
$result = DB::query(sprintf("SELECT DISTINCT %s FROM %s", "column","table"));
G'day,
I'm not familiar with MySQL and this will probably be an easy question!
I am trying to mod a Joomla plugin and am working with this code that works well for a similar function:
$q="SELECT `".$naming."` AS naming FROM `#__users` WHERE `id`='".$jomsocial_event->creator."' ";
$db->setQuery($q);
$eventcreatorname = $db->loadResult();
$eventcreator = ''.addslashes($eventcreatorname).'';
What I need to do is lookup the field id in the table community_groups and return the matching field name. What I have is (note that $jomsocial_event->contentid contains the group ID):
$q="SELECT `".$naming."` AS naming FROM `#__community_groups` WHERE `id`='".$jomsocial_event->contentid."' ";
$db->setQuery($q);
$eventgroupname = $db->loadResult();
$eventgroup = ''.addslashes($eventcreatorname).'';
It returns nothing as the query is wrong; what should it be for my usage?
I'd work backwards from the database.
i.e. turn on SQL logging and look at what's actually arriving in the database. Tweak as necessary by playing with the resulting SQL until you get what you want (and expect) and then implement that in your code.
Take a look at your generated query in the debugging from Joomla.
Run it against mysql directly and see where it goes wrong.
Also, I'd use the JDatabaseQuery API because you are much less likely to get errors with quoting etc. It looks to me like you are treating id as a string not an integer.
I have the following MySQL query that I execute from a .php page
SELECT * FROM servers WHERE name LIKE '%$value%'
which, when executed, selects 0 rows (However, the query runs successfully, so I can't use mysql_error() to debug). When I run the query in PHPMyAdmin it selects the appropriate rows. Other queries such as
SELECT * FROM servers
work fine. I can put my code up here if it will help.
Edit: Here's something offering an improvement based on Marek's answer below. Please see the comments regarding the practice of putting variables directly into queries and consider using prepared statements. Anyway, here it goes.
PHP substitutes variables inside doubly-quoted strings, but not inside singly-quoted strings.
One quote character is just treated as an ordinary character within a string delimited by the other.
Putting that together, you can write:
$q = "SELECT * FROM servers WHERE name LIKE '%$value%'"; //Fine
You cannot write:
$p = 'SELECT * FROM servers WHERE name LIKE "%$value%"'; //Broken!
$q works because it's a doubly-quoted string, and the apostrophes are just ordinary characters. $p does not work because it's a singly-quoted string.
As pointed out by GoodFather below, you can also say ${value} to avoid ambiguities with the ambient string, e.g. $r = "ABC${value}DEF";.
You really need to look at doing this query more safely. This will help with your issue as well. As it stands, you are vulnerable to SQL injection. Look at the examples from the PHP manual for how to do it right:
http://php.net/manual/en/function.mysql-query.php
EDIT: From your comments you mentioned that you are already taking care of the string properly, which is great. The code below should fix your problem.
For example, you could rewrite your query statement (in PHP) like so:
$query = sprintf("SELECT * FROM servers WHERE name LIKE '%". mysql_real_escape_string($value) . "%'");
That will clean up your code and it will also handle the issue with your LIKE statement not working properly.
Here is another good article on the subject:
http://joshhighland.com/blog/2008/07/06/php-sprintf-sql-like/
Are you expecting a case-sensitive or case-insensitive query? I'm betting case-insensitive since you're expecting results but not seeing them. Take a look at your database's default collation or the table's specific collation and make sure it ends in _ci, whatever it is.
this is part of a security audition, so there is no way to "change" the query.
Basically, what I found is a flaw that allows statement manipulation, so basically it goes like:
$query = "DELETE FROM `products` WHERE `products`.`whatever` = $variable";
This is PHP, so as far as I know there is no way to execute multiple queries. Using this SQL Injection, I was able to "clear" this table by running "0 OR 1=1#".
This works just fine, but it doesn't allow me to choose more tables to delete from.
This is, in pseudocode what I want to do:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1, FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
Is this plausible anyhow?
If this isn't reliable, is there any other way I could use this?
You can't have multiple FROM clauses for the same DELETE statement, so you can't go about it exactly how you'd want to. If the MySQL db had 'allow multiple queries per statement' turned on, you could try to terminate the one DELETE query and then tack on another to the end, so that it'd look like this:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1; DELETE FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
But that's about it.
Perhaps I don't fully understand the question, but what I take away is that you're building a SQL command as a string and running that string directly against a MySQL database.
You can separate multiple commands using the command separator (usually ';'), so you could run pretty much any command you want as this comic aptly illustrates.
If your database configuration supports multiple commands (or might in the future if someone changes today's setting), you want to ensure you don't have a command separator as part of the input. See this article for advice on sanitizing your input to prevent this type of attack.
As you stated, multiple queries are not supported by the normal MySQL driver module. From the manual for mysql_query:
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier .
Unfortunately for your injection efforts, DELETE syntax only supports multiple table deletes by specifying them in the FROM clause. Your injected variable is part of the WHERE, so the most damage you can do is to the single specified table.
Contrary to popular belief, you can actually run multiple MySQL statements from PHP, you just have to be using a different database driver module such as MySQLi. See MySQLi::multi_query().