User defined variables using SET is not working - mysql

I am using node 5.0.0 along with the node module mysql2 - 1.0.0-rc.11. It is working perfectly fine except when I try to use the user defined variables.
Example :
SET #user := 123456;
SELECT * FROM users WHERE user = #user;
The above simple query is throwing syntax error at my end. I am sure that, the syntax is a valid one. So I am wondering what may be the cause for this issue?
Doesn't the node module mysql2 - 1.0.0-rc.11 have support for SET yet? I have scanned the [document1, document2] thoroughly, I couldn't able to find the syntax support list. Can anyone help me to understand what's going wrong with this?

Following up on Andrey Sidorov's comment, you will need to have multipleStatements: true in the options object you pass to createConnection(), createPool(), etc. This is false by default for security reasons, so I don't recommend using it in production code.
https://github.com/mysqljs/mysql#multiple-statement-queries

Related

Couldn't figure out how the payload worked

I was solving one of TryHackMe's rooms about SQL injection.But I couldn't figured out one thing that came to my mind and after spending lots of time I thought it's best to ask that question here. In the room there is a machine to deploy, after deployed machine it gave me an interface(webapp) that takes inputs from me like so :
And if you give it a value like test. It returns following output:
When I saw it, I thought it was an easy SQLi question so I tried most basic SQLi payloads for common dbms like so:
' ; sleep(1) --
' or 1=1 -- ...
But none of them worked and returned me an error message like that:
After that failure, I run sqlmap and it found 2 types of SQLi payload with following payloads:
Then I realized that in time based SQLi, sqlmap used ||. Then I tried to send '|| (select sleep(2)) -- . And it worked. Now my question is why my first payload(' ; select sleep(2) -- ) didn't work, but this one worked ?
By default, MySQL query interfaces do not support multiple queries separated by semicolon. To get that, the application would have to explicitly request this feature to be enabled when it connects to the database. There's a connect option for that.
So by default, any type of SQL injection that works by trying to append a malicious query after a semicolon doesn't work.
But an SQL injection that works by modifying an expression in the single query can still work.

How can I use mysql as jupyterhub's database?

The default database for JupyterHub is a SQLite database. But I want to replace SQLite database with MySQL. I tried with the config variable in the config file.
c.JupyterHub.db_url = 'jdbc:mysql://localhost:3306/test'
But when I run jupyterhub then it yields the error as :
sqlalchemy.exc.ArgumentError: Could not parse rfc1738 URL from string 'jdbc:mysql://localhost:3306/test'
I searched and researched the official docs of jupyterhub but didn't find any thing related to my issue. Any solution to this problem?? Anyone ???
Thank you !
Found the exact line that solve the above problem.
c.JupyterHub.db_url = 'mysql+mysqlconnector://{}:{}#{}/{}{}'.format("username","password","host","database","")
Its an addition to the correct answer above if you dont add that arguement when using mysql you will have timeout issues, as mentioned as per documentation (https://jupyterhub.readthedocs.io/en/stable/reference/database.html)
RFC1738 says that url syntax has to be defined as follows:
//<user>:<password>#<host>:<port>/<url-path>
RFC1738 is not the same syntax than JDBC specification. It looks like you're trying to parse a RFC1738-url (needed by JupyterHub) with JDBC syntax.
Make you also add the option for pool recycling in your JH config. As per documentation.
c.JupyterHub.db_kwargs = {"pool_recycle":300}

Django-MySQL is unable to recognise model.column in queryset extra?

I have SQLite and MySQL installed on my local and development machine respectively. Following is working fine on my local machine(with SQLite):
select_single = {'date': "strftime('%%Y-%%m-%%d',projectName_Modelname.created)"}
queryset.extra(select=select_single)
But since strftime doesn't work with MySQL(link), I tried using DATE_FORMAT() as suggested in given link and other places too.
Though now when I execute below:
select_single = {'date': "DATE_FORMAT(projectName_Modelname.created, '%%Y-%%m-%%d')"}
queryset.extra(select=select_single)
Following error comes:
DatabaseError: (1054, "Unknown column 'projectName_Modelname.created' in 'field list'")
where 'created' is Datetime field in Django model 'Modelname' of app 'projectName'
To debug when I replace projectName_Modelname.created with NOW() no error comes. I have also tried just Modelname.created instead of projectName_Modelname.created though with no benefit?
Note: I am using Django1.5.5
I think it should be something like:
date_raw_query = {'date': "date_format(created, '%%Y-%%m-%%d')"}
and then try
queryset.extra(select=date_raw_query)
Hope that works in your setup. I have tried this on Django 1.7 and MySQL and seems to be working.
Also remember that if SQL errors start coming up, you can always do a print queryset.extra(select=date_raw_query).query to see what might be going wrong.
And when it comes to writing compatible code between SQLite and MySQL like this one, writing a custom MySQL function has been suggested here
But I would suggest otherwise. It's better to have a similar dev environment with MySQL setup in local and also, upgrade Django as soon as possible. :P

Entity Framework : Set MySQL custom environment variables

I have an issue with Entity Framework 5.0. I'm working with Silverlight 5 and MySQL 5.6 too.
I need to set an environment MySQL variable before each connexion to the MySQL server.
E.g
SET #my_var = 'test';
Under Mysql I don't have any issues.
The following raises an EntityFrameworkException (syntax error near '#').
this.ObjectContext.CreateQuery<object>(" SET #my_var = 'test' ");
OR
this.ObjectContext.CreateQuery<object>(" CALL set_my_var('test') ");
This last method raises a MySQLException saying that a DataReader is already open and need to be closed.
this.ObjectContext.ExecuteStoreQuery<object>(" CALL set_my_var('test') ", null);
I also tried to set a MySQL system environment (no '#') with the same result every time.
Any help will be much appreciated !
Thank you.
I tried so many things that I misspelled my variable in my code.
So the following finaly worked : ctx.ExecuteStoreCommand("SET #my_var = 'test'");
I decided to leave the instruction in the method Initialize of my domain service. This method is inherited of the LinqToEntitiesDomainService class.
But you need to set Allow User Variables=True in your MySQL connection string
(ref : Is it possible to use a MySql User Defined Variable in a .NET MySqlCommand?)
You simply need to use a recent version of the MySQL Connector because older versions use the '#' mark to define SQL parameters so it could conflict with custom variables. Now it uses the '?' mark : http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html
My library was already up to date (6.6.5).
Thank you for the help !
Since your statement is not a query (i.e. does not return any result) you should use ExecuteStoreCommand. Something like this should work:
ctx.ExecuteStoreCommand("SET #my_var = 'test'")

How does Rails build a MySQL statement?

I have the following code that run on heroku inside a controller that intermittently fails. It's a no-brainer that it should work to me, but I must be missing something.
#artist = Artist.find(params[:artist_id])
The parameters hash looks like this:
{"utf8"=>"������",
"authenticity_token"=>"XXXXXXXXXXXXXXX",
"password"=>"[FILTERED]",
"commit"=>"Download",
"action"=>"show",
"controller"=>"albums",
"artist_id"=>"62",
"id"=>"157"}
The error I get looks like this:
ActiveRecord::StatementInvalid: Mysql::Error: : SELECT `artists`.* FROM `artists` WHERE `artists`.`id` = ? LIMIT 1
notice the WHEREartists.id= ? part of the statement? It's trying to find an ID of QUESTION MARK. Meaning Rails is not passing in the params[:artist_id] which is obviously in the params hash. I'm at complete loss.
I get the same error on different pages trying to select the record in a similar fashion.
My environment: Cedar Stack on Heroku (this only happens on Heroku), Ruby 1.9.3, Rails 3.2.8, files being hosted on Amazon S3 (though I doubt it matters), using the mysql gem (not mysql2, which doesn't work at all), ClearDB MySQL database.
Here's the full trace.
Any help would be tremendously appreciated.
try sql?
If it's just this one statement, and it's causing production problems, can you omit the query generator just for now? In other words, for very short term, just write the SQL yourself. This will buy you a bit of time.
# All on one line:
Artist.find_by_sql
"SELECT `artists`.* FROM `artists`
WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"
ARel/MySQL explain?
Rails can help explain what MySQL is trying to do:
Artist.find(params[:artist_id]).explain
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
Perhaps you can discover some kind of difference between the queries that are succeeding vs. failing, such as how the explain uses indexes or optimizations.
mysql2 gem?
Can you try changing from the mysql gem to the mysql2 gem? What failure do you get when you switch to the mysql2 gem?
volatility?
Perhaps there's something else changing the params hash on the fly, so you see it when you print it, but it's changed by the time the query runs?
Try assigning the variable as soon as you receive the params:
artist_id = params[:artist_id]
... whatever code here...
#artist = Artist.find(artist_id)
not the params hash?
You wrote "Meaning Rails is not passing in the params[:artist_id] which is obviously in the params hash." I don't think that's the problem-- I expect that you're seeing this because Rails is using the "?" as a placeholder for a prepared statement.
To find out, run the commands suggested by #Mori and compare them; they should be the same.
Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql
prepared statements?
Could be a prepared statement cache problem, when the query is actually executed.
Here's the code that is failing-- and there's a big fat warning.
begin
stmt.execute(*binds.map { |col, val| type_cast(val, col) })
rescue Mysql::Error => e
# Older versions of MySQL leave the prepared statement in a bad
# place when an error occurs. To support older mysql versions, we
# need to close the statement and delete the statement from the
# cache.
stmt.close
#statements.delete sql
raise e
end
Try configuring your database to turn off prepared statements, to see if that makes a difference.
In your ./config/database.yml file:
production:
adapter: mysql
prepared_statements: false
...
bugs with prepared statements?
There may be a problem with Rails ignoring this setting. If you want to know a lot more about it, see this discussion and bug fix by Jeremey Cole and Aaron: https://github.com/rails/rails/pull/7042
Heroku may ignore the setting. Here's a way you can try overriding Heroku by patching the prepared_statements setup: https://github.com/rails/rails/issues/5297
remove the query cache?
Try removing the ActiveRecord QueryCache to see if that makes a difference:
config.middleware.delete ActiveRecord::QueryCache
http://edgeguides.rubyonrails.org/configuring.html#configuring-middle
try postgres?
If you can try Postgres, that could clear it up too. That may not be a long term solution for you, but it would isolate the problem to MySQL.
The MySQL statement is obviously wrong, but the Ruby code you mentioned would not produce it. Something is wrong here, either you use a different Ruby code (maybe one from a before_filter) or pass a different parameter (like params[:artist_id] = "?"). Looks like you use nested resources, something like Artist has_many :albums. Maybe the #artist variable is not initialized correctly in the previous action, so that params[:artist_id] has not the right value?