is there any sql injection protection in typo framework?
Or I have to take care by myself of building a query?
I found prepare_SELECTqueryArray, but there is no example how it should look.
My TYPO3 version is 4.7. And this prepare_SELECTqueryArray I found on site with TYPO3 v.6.1.
Prepared Statements are available at least in TYPO3 4.5 as you can see here [1] and [2]
A Prepared query could look like this
$preparedQuery = $this->link->prepare_SELECTquery('fieldblob,fieldblub', $table, 'id=:id', '', '', '', array(':id' => 1));
$preparedQuery->execute();
$result = $preparedQuery->fetch();
or
$preparedQuery = $this->link->prepare_SELECTquery('fieldblob,fieldblub', $table, 'id=:id');
$preparedQuery->bindValues(array(':id' => 1));
$preparedQuery->execute();
$result = $preparedQuery->fetch();
[1] https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_4-5/t3lib/class.t3lib_db.php
[2] https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_4-5/t3lib/db/class.t3lib_db_preparedstatement.php
On many places values are quoted automatically. Within the prepare_* functions, all parameters are quoted by default.
If you use exec_* querys, you need to escape values in where part on your own. Use $GLOBALS['TYPO3_DB']->fullQuoteStr($value, $tablename) for that.
Be aware, that you can create SQL-Injections with TypoScript too. If you use CONTENT-Object you can insert GET/POST Data into the where-clause. Use intval or select.markers for creating SQL-Injection save querys.
Related
I want to update a topic with a post id in Wordpress and add it to the end of the post. However, I could not run the code below. Can you help?
wp_update_post(['ID' => $posts->ID,"post_content" => "concat_ws(' ',post_content, 'SECOND')"]);
Normally, this process is done over sql with concat. But I want to use it with php.
The version that works with sql;
update test_user set descrip = concat_ws(' ',descrip, 'SECOND') where Id=2
but I want to run it with php, not sql. How should the first code be?
You can use braces or concatenation operator .
echo "qwe{$a}rty"; // qwe12345rty, using braces
echo "qwe" . $a . "rty"; // qwe12345rty, concatenation used
Also, it much better to use WP_Post class than modify data in tables directly.
Your WP instance can use some db caching layer, or some hooks for posts updating. This functionality can be
potentially broken if you work with tables directly.
$post = get_post( 123 );
$post->post_content = $post->post_content . "Some other content";
wp_update_post( $post );
I am trying to avoid a sql injection. This topic has been dealt with in Java (How to prevent query injection on Google Big Query) and Php.
How is this accomplished in App Scripts? I did not find how to add a parameter to a SQL statement. Here is what I had hoped to do:
var sql = 'SELECT [row],etext,ftext FROM [hcd.hdctext] WHERE (REGEXP_MATCH(etext, esearch = ?) AND REGEXP_MATCH(ftext, fsearch = ?));';
var queryResults;
var resource = {
query: sql,
timeoutMs: 1000,
esearch='r"[^a-zA-z]comfortable"',
fsearch='r"[a-z,A-z]confortable"'
};
queryResults = BigQuery.Jobs.query(resource,projectNumber);
And then have esearch and fsearch filled in with the values (which could be set elsewhere).
That does not work, according to the doc.
Any suggestions on how to get a parameter in an SQL query? (I could not find a setString function...)
Thanks!
Unfortunately, BigQuery doesn't support this type of parameter substitution. It is on our list of features to consider, and I'll bump the priority since it seems like this is a common request.
The only suggestion that I can make in the mean time is that if you are building query strings by hand, you will need to make sure you escape them carefully (which is a non-trivial operation).
I have this site with the following parameters:
http://www.example.com.com/pagination.php?page=4&order=comment_time&sc=desc
I use the values of each of the parameters as a value in a SQL query.
I am trying to test my application and ultimately hack my own application for learning purposes.
I'm trying to inject this statement:
http://www.example.com.com/pagination.php?page=4&order=comment_time&sc=desc' or 1=1 --
But It fails, and MySQL says this:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource,
boolean given in /home/dir/public_html/pagination.php on line 132
Is my application completely free from SQL injection, or is it still possible?
EDIT: Is it possible for me to find a valid sql injection statement to input into one of the parameters of the URL?
The application secured from sql injection never produces invalid queries.
So obviously you still have some issues.
Well-written application for any input produces valid and expected output.
That's completely vulnerable, and the fact that you can cause a syntax error proves it.
There is no function to escape column names or order by directions. Those functions do not exist because it is bad style to expose the DB logic directly in the URL, because it makes the URLs dependent on changes to your database logic.
I'd suggest something like an array mapping the "order" parameter values to column names:
$order_cols = array(
'time' => 'comment_time',
'popular' => 'comment_score',
... and so on ...
);
if (!isset($order_cols[$_GET['order'])) {
$_GET['order'] = 'time';
}
$order = $order_cols[$_GET['order']];
Restrict "sc" manually:
if ($_GET['sc'] == 'asc' || $_GET['sc'] == 'desc') {
$order .= ' ' . $_GET['sc'];
} else {
$order .= ' desc';
}
Then you're guaranteed safe to append that to the query, and the URL is not tied to the DB implementation.
I'm not 100% certain, but I'd say it still seems vulnerable to me -- the fact that it's accepting the single-quote (') as a delimiter and then generating an error off the subsequent injected code says to me that it's passing things it shouldn't on to MySQL.
Any data that could possibly be taken from somewhere other than your application itself should go through mysql_real_escape_string() first. This way the whole ' or 1=1 part gets passed as a value to MySQL... unless you're passing "sc" straight through for the sort order, such as
$sql = "SELECT * FROM foo WHERE page='{$_REQUEST['page']}' ORDER BY data {$_REQUEST['sc']}";
... which you also shouldn't be doing. Try something along these lines:
$page = mysql_real_escape_string($_REQUEST['page']);
if ($_REQUEST['sc'] == "desc")
$sortorder = "DESC";
else
$sortorder = "ASC";
$sql = "SELECT * FROM foo WHERE page='{$page}' ORDER BY data {$sortorder}";
I still couldn't say it's TOTALLY injection-proof, but it's definitely more robust.
I am assuming that your generated query does something like
select <some number of fields>
from <some table>
where sc=desc
order by comment_time
Now, if I were to attack the order by statement instead of the WHERE, I might be able to get some results... Imagine I added the following
comment_time; select top 5 * from sysobjects
the query being returned to your front end would be the top 5 rows from sysobjects, rather than the query you try to generated (depending a lot on the front end)...
It really depends on how PHP validates those arguments. If MySQL is giving you a warning, it means that a hacker already passes through your first line of defence, which is your PHP script.
Use if(!preg_match('/^regex_pattern$/', $your_input)) to filter all your inputs before passing them to MySQL.
I'm working on a PHP MSSQL project that is using the sqlsrv driver.
What's the best way to stop SQL injection attacks? I need something like mysql_real_escape_string() but for sqlsrv driver.
If you use it like this, quoting is automatic:
$sql = "exec usp_cis_upd
#key = ?,
#value = ?";
$params = array(
$key,
trim($_POST["value"]));
$stmt = sqlsrv_query($dbh, $sql, $params);
The best way is not to write your SQL so that you need to use an analogue of mysql_real_escape_string(), which you would do by using placeholders for the values and then passing the variables (that would otherwise have been handled by mysql_real_escape_string()) when you execute the statement or open the cursor or whatever.
Failing that, look at the output of mysql_real_escape_string(); it might be appropriate for MS SQL Server too. It depends on how it does the escaping (and what escaping it does).
I'm writing a Rails 3 ActiveRecord query using the "where" syntax, that uses both the SQL IN and the SQL OR operator and can't figure out how to use both of them together.
This code works (in my User model):
Question.where(:user_id => self.friends.ids)
#note: self.friends.ids returns an array of integers
but this code
Question.where(:user_id => self.friends.ids OR :target => self.friends.usernames)
returns this error
syntax error, unexpected tCONSTANT, expecting ')'
...user_id => self.friends.ids OR :target => self.friends.usern...
Any idea how to write this in Rails, or just what the raw SQL query should be?
You don't need to use raw SQL, just provide the pattern as a string, and add named parameters:
Question.where('user_id in (:ids) or target in (:usernames)',
:ids => self.friends.ids, :usernames => self.friends.usernames)
Or positional parameters:
Question.where('user_id in (?) or target in (?)',
self.friends.ids, self.friends.usernames)
You can also use the excellent Squeel gem, as #erroric pointed out on his answer (the my { } block is only needed if you need access to self or instance variables):
Question.where { user_id.in(my { self.friends.ids }) |
target.in(my { self.friends.usernames }) }
Though Rails 3 AR doesn't give you an or operator you can still achieve the same result without going all the way down to SQL and use Arel directly. By that I mean that you can do it like this:
t = Question.arel_table
Question.where(t[:user_id].in(self.friends.ids).or(t[:username].in(self.friends.usernames)))
Some might say it ain't so pretty, some might say it's pretty simply because it includes no SQL. Anyhow it most certainly could be prettier and there's a gem for it too: MetaWhere
For more info see this railscast: http://railscasts.com/episodes/215-advanced-queries-in-rails-3
and MetaWhere site: http://metautonomo.us/projects/metawhere/
UPDATE: Later Ryan Bates has made another railscast about metawhere and metasearch: http://railscasts.com/episodes/251-metawhere-metasearch
Later though Metawhere (and search) have become more or less legacy gems. I.e. they don't even work with Rails 3.1. The author felt they (Metawhere and search) needed drastic rewrite. So much that he actually went for a new gem all together. The successor of Metawhere is Squeel. Read more about the authors announcement here:
http://erniemiller.org/2011/08/31/rails-3-1-and-the-future-of-metawhere-and-metasearch/
and check out the project home page:
http://erniemiller.org/projects/squeel/
"Metasearch 2.0" is called Ransack and you can read something about it from here:
http://erniemiller.org/2011/04/01/ransack-the-library-formerly-known-as-metasearch-2-0/
Alternatively, you could use Squeel. To my eyes, it is simpler. You can accomplish both the IN (>>) and OR (|) operations using the following syntax:
Question.where{(:user_id >> my{friends.id}) | (:target >> my{friends.usernames})}
I generally wrap my conditions in (...) to ensure the appropriate order of operation - both the INs happen before the OR.
The my{...} block executes methods from the self context as defined before the Squeel call - in this case Question. Inside of the Squeel block, self refers to a Squeel object and not the Question object (see the Squeel Readme for more). You get around this by using the my{...} wrapper to restore the original context.
raw SQL
SELECT *
FROM table
WHERE user_id in (LIST OF friend.ids) OR target in (LIST OF friends.usernames)
with each list comma separate. I don't know the Rails ActiveRecord stuff that well. For AND you would just put a comma between those two conditions, but idk about OR