Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass select query from the client side

Is it OK (I mean security reasons) to pass database query (select or update or whatever) to the server side as parameter (like, I read the values of the form fields, form a query string in javascript and pass the formed string to the server as a parameter):

$.ajax({
    url : "servletURL",
    type : "post",
    data: {query: "select name, last_name from employees"},
    success: //do things
});

or

var name = document.getElementById('name').value;
var last_name = document.getElementById('last_name').value;
$.ajax({
    url : "servletURL",
    type : "post",
    data: {query: "select * from employees where name="+name+" and last_name="+last_name},
    success: //do things
});

Or should I pass to the server only parameters, not full queries, and make prepared statement there?

And surely, I can check the validity of the field values before I send the request to the server.

like image 318
keshet Avatar asked Apr 21 '15 10:04

keshet


2 Answers

Unless you're building something that is explicitly for executing queries on a database (PHPMyAdmin, or such), it is NEVER okay to do this.

Why?
A malicious user can now delete your ENTIRE database, simply by editing the javascript.

$.ajax({
  url: "",
  type: "post",
  data: {query: "DROP database"},
  success:
  })

The best practice is to send the data to the server, and construct your query over there.
The only attack that is left is SQL-injection. Solutions for this are specific to each language, but you can have a look at Tom Scott's explanation on it.

like image 61
CerebralFart Avatar answered Oct 21 '22 12:10

CerebralFart


Don't pass queries as parameters. Best avoid even using query templates. The security holes are gaping wide and to close them you effectively need a full-fledged sql parser in your validation code.

In your example, just imagine a man-in-the-middle attack that changes the instantiated query

select * from employees where name='<name>' and last_name='<last_name>'

to

select * from employees where name='<name>' and last_name='<last_name>'
union all
select * from employees

by simply appending a constant string

like image 28
collapsar Avatar answered Oct 21 '22 13:10

collapsar