2

For a while I am more and more confused because of possible XSS attack vulnerabilities on my new page. I've been reading a lot, here on SO and other googled sites. I'd like to secure my page as best as it is possible (yes, i know i cant be secure 100%:).

I also know how xss works, but would like to ask you for pointing out some vulnerable places in my code that might be there. I use jquery, javascript, mysql, php and html all together. Please let me know how secure it is, when i use such coding. Here's idea.

html:

<input name="test" id="id1" value="abc">
<div id="button"></div>
<div id="dest"></div>

jQuery:

1. $('#id').click (function() {
2.        var test='def' 
3.        var test2=$('#id1').val();
4.        $.variable = 1;
5.        $.ajax({
6.        type: "POST",
7.          url: "get_data.php",
8.          data: { 'function': 'first', 'name': $('#id').val() },
9.          success: function(html){
10.                $('#dest').html(html);
11.                 $('#id1').val = test2;
12.            }
13.         })
14.  })

I guess it's quite easy. I have two divs - one is button, second one is destination for text outputted by "get_data.php". So after clicking my button value of input with id 'id1' goes to get_data.php as POST data and depending on value of this value mysql returns some data. This data is sent as html to 'destination' div.

get_data.php should look like this:

   [connecting to database]
   switch($_POST['function']) {
     case 'first':
3.       $sql_query = "SELECT data from table_data WHERE name = '$_POST[name]'";
         break;
     default:
         $sql_query = "SELECT data from table_data WHERE name = 'zzz'";    
   }
   $sql_query = mysql_query($sql_query) or die(mysql_error());
   $row = mysql_fetch_array($sql_query);    
   echo $row['data']

For now consider that data from mysql is free from any injections (i mean mysql_real_escaped).

Ok, here are the questions:

JQuery part:

Line 2: Can anybody change the value set like this ie. injection?

Line 3 and 11: It's clear that putting same value to as was typed before submiting is extremely XSS threat. How to make it secure without losing functionality (no html tags are intended to be copied to input)

Line 4: Can anybody change this value by injection (or any other way?)

Line 8: Can anybody change value of 'function' variable sent via POST? If so, how to prevent it?

Line 10: if POST data is escaped before putting it into database can return value (i mean echoed result of sql query) in some way changed between generating it via php script and using it in jquery?

PHP part:

Please look at third line. Is writing: '$_POST[name]' secure? I met advice to make something like this:

     $sql_query = "SELECT data from table_data WHERE name = " . $_POST['name'];

instead of:

     $sql_query = "SELECT data from table_data WHERE name = '$_POST[name]'";

Does it differ in some way, especially in case of security? Next question to the same line: if i want to mysql_real_escape() $_POST['name'] what would be the best solution (consider large array of POST data, not only one element like in this example): - to mysql_real_escape() each POST data in each query like this:

$sql_query = "SELECT data from table_data WHERE name = " . mysql_real_escape($_POST['name']);
  • to escape whole query before executing it

     $sql_query = "SELECT data from table_data WHERE name = " . $_POST['name'];
     $sql_query = mysql_real_escape($sql_query);
    
  • to write function that iterates all POST data and escapes it:

     function my_function() {
        foreach ( $_POST as $i => $post ) {
             $_POST[$i] = mysql_real_escape($post)
        }
     }
    

What - in your opinion is best and most secure idea?

This post became quite large but xss really takes my sleep away :) Hope to get help here dudes once again :) Everything i wrote here was written, not copied so it might have some small errors, lost commas and so on so dont worry about this.

EDIT

All right so.. if I understand correctly filtering data is not necessery at level of javascript or at client side at all. Everything should be done via php. So i have some data that goes to ajax and further to php and as a result i get some another kind of data which is outputted to the screen. I am filtering data in php, but not all data goes to mysql - part od this may be in some way changed and echoed to the screen and returned as 'html' return value of successfully called ajax. I also have to mention that I do not feel comfortable in OOP and prefering structural way. I could use PDO but still (correct me if i am wrong) i have to add filtering manually to each POST data. Ofcourse i get some speed advantages. But escaping data using mysql_real_escape looks to me for now "manual in the same level". Correct me if i am wrong. Maybe mysql_realescape is not as secure as PDO is - if so that's the reason to use it.

Also i have to mention that data that doesnt go to database has to be stripped for all malicious texts. Please advice what kind of function I should use because i find a lot of posts about this. they say "use htmlentities()" or "use htmlspecialchars()" and so on. Consider that situation: Ajax is called with POST attribute and calls file.php. It sends to file.php POST data i.e. $_POST['data'] = 'malicious alert()'. First thing in file.php I should do is to strip all threat parts from $_POST['data']. What do you suggest and how do you suggest I should do it. Please write an example.

Kalreg
  • 931
  • 3
  • 12
  • 31
  • read this post...your mysql statements are very unsecure http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – charlietfl Mar 28 '12 at 17:02
  • Concerning your edit: No you do not need to call escape methods manually when using PDO. Read the above link carefully and understand what the terms **prepared statements** and **parameterized queries** mean – Alp Mar 28 '12 at 19:11
  • ok i'll read it but still i dont have answer how should i deal with data from input fields that is not going to database. – Kalreg Mar 28 '12 at 19:17

2 Answers2

2

XSS is Cross-site scripting. You talk about SQL injection. I will refer to the latter.

JQuery Part

It's possible to change every single JavaScript command. You can try it yourself, just install Firebug, change the source code or inject some new JavaScript code into the loaded page and do the POST request. Or, use tools like RestClient to directly send any POST request you like.

Key insight: You cannot control the client-side. You have to expect the worst and do all the validation and security stuff server-side.

PHP Part

It is always a good idea to double-check each user input. Two steps are usually mandatory:

  1. Validate user input: This is basically checking if user input is syntactically correct (for example a regex that checks if a user submitted text is a valid email address)
  2. Escape database queries: Always escape dynamic data when feeding it to a database query. Regardless where it's coming from. But do not escape the whole query string, that could yield in unexpected results.

Maybe (and hopefully) you will like the idea of using an ORM solution. For PHP there are Propel and Doctrine for instance. Amongst a lot of other handy things, they provide solid solutions to prevent SQL injection.

Example in Propel:

$result = TableDataQuery::create()
    ->addSelectColumn(TableDataPeer::DATA)
    ->findByName($_POST['name']);

Example in Doctrine:

$qb = $em->createQueryBuilder();
$qb->add('select', 'data')
   ->add('from', 'TableData')
   ->add('where', 'name = :name')
   ->setParameter('name', $_POST['name']);
$result = $qb->getResult();

As you can see, there is no need for escaping the user input manually, the ORM does that for you (this is refered as parameterized queries).

Update

You asked if PDO is also an ORM. I'd say PDO is a database abstraction layer, whereas an ORM provides more functionality. But PDO is good start anyway.

can firebug any malicious code in opened in browser page and send trash to php script that is somwhere on the server?

Yes, absolutely!

The only reason you do validation of user input in JavaScript is a more responsive user interface and better look & feel of your web applications. You do not do it for security reasons, that's the server's job.

Alp
  • 29,274
  • 27
  • 120
  • 198
  • Thanks for answer. Is what you call ORM same as what we have in this link described (first answer) http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php More about jquery - it's quite clear for me that you can change locally what i want but can firebug any malicious code in opened in browser page and send trash to php script that is somwhere on the server? I also was talking about xss because writing input's field value to page is xss threat, but should i filter it in anyway with javascript or is it nonsens and do it only on server side? – Kalreg Mar 28 '12 at 17:43
  • and my answer with additional questions is there – Kalreg Mar 28 '12 at 19:07
0

There is a firefox addon to test your site for XSS, it called XSS Me

Also you can go to

http://ha.ckers.org/xss.html

for most XSS attacks

and go to

http://ha.ckers.org/sqlinjection/

for most sql injection attacks

and try these on your site

Jeetendra Pujari
  • 1,286
  • 2
  • 17
  • 31