I've built mini content management system. In my page add form i'm using ckeditor. for text are named content
<textarea id="content" style="width:100%" name="content"></textarea>
Adding all data from form into db table with following php code. (Function filter used for sanitizing data)
<?php
require '../../core/includes/common.php';
$name=filter($_POST['name'], $db);
$title=filter($_POST['title'], $db);
$parentcheck=filter($_POST['parentcheck'],$db);
if(isset ($_POST['parent'])) $parent=filter($_POST['parent'],$db);
else $parent=$parentcheck;
$menu=filter($_POST['menu'], $db);
$content = $db->escape_string($_POST['content']);
if(isset($_POST['submit'])&&$_POST['submit']=='ok'){
$result=$db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$menu')") or die($db->error);
$new_id = $db->insert_id;
$result2=$db->query("INSERT INTO pages (id, title, content) VALUES ('$new_id', '$title', '$content')") or die($db->error);
header("location:".$wsurl."admin/?page=add");
}
?>
FUNCTION FILTER (data sanitization)
function filter($data, $db)
{
$data = trim(htmlentities(strip_tags($data)));
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = $db->escape_string($data);
return $data;
}
I got questions about it. (I'm newbie to ajax.)
Currently i'm submitting data with standart php (page refreshes
every time). How to modify code for ajax submission?
I have only one button for submitting data. I want to create second
button "save" which will update db fields via ajax
How can i create autosave function (which periodically saves form in the background and informss user about it, just like on Stackoverflow) via ajax?
Thx in advance
Let's suppose you want to use jQuery to do the ajax business for you, you need to setup a periodic POST of the data in the textarea (note that in some browsers GET requests have a limit).
On the first POST, you need to tell the PHP script "this is the first POST" so that it knows to INSERT the data, it should then return to you some identifying characteristic. Every other time you POST data, you should also send this identifying characteristic, let's just use the primary key (PK). When you POST data + PK, the PHP script should run an update query on the SQL.
When constructing these, the thing to think about is sending data from the browser using JavaScript to a PHP script. The PHP script gets only whatever packet of data you send, and it can return values by producing, for instance, JSON. Your JavaScript code can then use those return values to decide what to do next. Many beginners often make the mistake of thinking the PHP can make calls to the JS, but in reality it's the other way around, always start, here, with the JS.
In this instance, the PHP is going to save data in the database for you, so you need to ship all the data you need to save to the PHP. In JS, this is like having some magic function you call "saveMyData", in PHP, it's just like processing a form submission.
The JavaScript side of this looks something like this (untested):
<script type="text/javascript">
var postUpdate = function(postKey){
postKey = postKey || -1;
$.post("/myscript.php",
/* note that you need to send some other form stuff
here that I've omitted for brevity */
{ data: $("#content").value(), key: postKey },
function(reply){
if(reply.key){
// if we got a response containing the primary key
// then we can schedule the next update in 1s
setTimeout(function(){postUpdate(reply.key);}, "1000");
}
}
});
};
// first invocation:
postUpdate();
</script>
The PHP side will look something like this (untested):
Aside: your implementation of filter should use mysql_real_escape_string() instead of striptags, mysql_real_escape_string will provide precisely the escaping you need.
<?php
require '../../core/includes/common.php';
$name = filter($_POST['name'], $db);
$title = filter($_POST['title'], $db);
$parentcheck = filter($_POST['parentcheck'],$db);
if(isset($_POST['parent'])){
$parent = filter($_POST['parent'],$db);
}else{
$parent = $parentcheck;
}
$menu = filter($_POST['menu'], $db);
$content = $db->escape_string($_POST['content']);
$pk = intval($_POST['key']);
if($pk == -1 || (isset($_POST['submit']) && $_POST['submit']=='ok')){
$result = $db->query("INSERT INTO menu (parent, name, showinmenu) VALUES ('$parent', '$name', '$menu')")
or die($db->error);
$new_id = $db->insert_id;
$result2 = $db->query("INSERT INTO pages (id, title, content) VALUES ('$new_id', '$title', '$content')")
or die($db->error);
$pk = $db->insert_id;
echo "{\"key\": ${pk}}";
// header("location:".$wsurl."admin/?page=add");
}else if($pk > 0){
$result2 = $db->query("UPDATE pages SET content='$content' WHERE id='$pk')")
or die($db->error);
echo "{\"key\": ${pk}}";
}
For AJAX, you can use jQuery's ajax API. It is very good and is cross-browser.
And for saving and auto-saving: you can use a temporary table to store your data. When the user presses the save button or when your data is auto-saved, you save your data to the table using AJAX and return a key for the newly created row. Upon future auto-save/save button events, you update the temporary table using AJAX.
And one word of advice, use a framework for your PHP and Javascript. I personally use Symfony and Backbone.js. Symfony checks for CSRF and XSS automatically and using Doctrine prevents SQL-injection too. There are other frameworks available (such as CodeIgniter, CakePHP and etc.) but I think Symfony is the best.
Edit: For the auto-save functionality, you can use Javascript SetTimeout to call your AJAX save function, when the page loads for the first time.
With regard to security issues:
Your silver bullet function is fundamentally flawed, it does not work, will never work and can never work.
SQL has different escaping needs than hmtl.
The functions you use counteract each other. escape_string adds \, stripslashes removes them.
Never mind the order of the functions, you need to use a specialized escape function for one and only one purpose.
On top of that you are using depreciated functions.
For MySQL this is mysql_real_escape_string. Note that escape_string (without the real) is depreciated, because it is not thorough enough. Use real_escape_string instead. On mysqli escape_string is an alias for real_escape_string.
See:
How does the SQL injection from the "Bobby Tables" XKCD comic work?
The ultimate clean/secure function
Related
I am doing this animation tool where I fetch a value from my database and then a picture will animate to a certain position. My question is if it is possible to retrieve data constantly or like every 5 seconds?
Somehow like this:
while(autoretreive){
$data = mysql_query("select * from ......");
}
UPDATED from here
Thanks for your answers! Made it a little bit clearer what to do! Maybe I can explain better what I'm doing in my code.
I am doing this animation program as said, where balls with information is moving around to different locations. I have one value that will be updated frequently in the database, lets call it 'city'.
First at previous page I post the balls of information I want based on the 'city' and I do like this (simplified):
$pid = $_POST['id'];
$pcity[0] = $_POST['city'];
$pcity[1] = $_POST['city'];
$pcity[2] = $_POST['city'];
//...
$while(autoretrieve) { // HOW TO?
$data = mysql_query(select * from table where city == $pcity[0] OR $pcity == [1] //...);
while($rows = mysql_fetch_array($data)){
$city = $rows['city'];
$id = $rows['id'];
if($city == example1){
"animate to certain pos"; //attached to image
}
else if($city == example2){
"animate to certain pos"; //attached to image
}
}
}
So for every update in the database the image will animate to a new position. So a time interval of 5 seconds would be great. I'm not an expert in coding so sorry for deprecated code. Not so familiar with AJAX either so what is going to be imported to the code? It is also important that the page is not reloading. Just the fetch from database.
you can do it with ajax and javascript
make one javascript function which contains ajax code to retrive data from database
and at your page load using setTimeout call your ajax function at every 5 second
You can use sleep function to control how often you want to fetch data.
while(autoretreive){
$data = mysql_query("select * from ......");
//output your data here, check more in link about server sent events bellow
sleep(5);
}
Since you haven't specified how you plan to access data I'm writing this answer assuming Server-Sent Events as they are only ones that make sense according to your question.
Now all this was according to your question which wasn't very clear on how do you plan to use data. Again you'll most likely want to fetch data using ajax, but Server Sent Events can also be a good way you could achieve this.
And don't use mysql_* it's deprecated, switch to PDO or mysqli_*
I have PHP generating an HTML form and I'm trying to write a script that will update the information in the database. For some reason it works on some of the fields and not others.
Code which won't work:
PHP-Form that users can change details within
echo"<form name='details'>";
echo"<p>Surname: <input type='text'id='surname' value='".$row['Surname']."'/></p>;
<p>Telephone: <input type='text'id='phone' value='".$row['Telephone']."'/></p>;
<p>Postcode: <input type='text' id='postcode' value='".$row['Postcode']."'/></p>;
<p>House/Flat Number: <input type='text' id='number' value='".$row['Number']."'/></p>";
AJAX - sends changes to server via querystring
var sname = document.getElementById('surname').value;
var tel = document.getElementById('phone').value;
var num = document.getElementById('number').value;
var pcode = document.getElementById('postcode').value;
var queryString = "?username=" + username +"&email="+email....";
ajaxRequest.open("GET", "url" + queryString, true);
ajaxRequest.send(null);
PHP - execute update command
//connect to server
...
//get variables
$sname = $_GET['sname'];
$pcode = $_GET['pcode'];
$tel = $_GET['tel'];
$num=$_GET['num'];
//process update
$update ="UPDATE User SET Surname='$sname',Telephone='$tel',Number='$num',
Postcode='$pcode' WHERE Username='$username'";
//if query, display success
if(mysqli_query($update))
{
echo"success";
}
else
{
echo"error";
}
//else display error
The query executes fine, but the values aren't displaying within the database. My other variables (username, password etc) all update fine. All database fields are type VARCHAR(80).
EDIT: I do have the query being executed. This still results in the surname, postcode, number and telephone field not being updated.
Ignoring for the moment all the other issues with this code and approach (SQL injection issues, GET vs. POST issue, etc.), and dealing with the update not changing things as expected, there are a couple of things to check.
Try outputing the update query in your logs and make sure that it actually looks like what your expecting. It could be that the values you're meaning to push across the wire are not making it into the query or that.
Verify that running the query by hand in an standalone SQL client (mysql, squirrel, etc...) Actually updates a record. It's entirely possible that a valid update query may not match any records. (Say the username value you're looking for does not match one that's in the database.
Not knowing your infrastructure, I'd suggest some sanity checks: Are you actually pointing at the right database? Do you have a your update wrapped in a transaction that's rolling back? etc ...
A few other tips:
I would suggest looking at PDO, in particular how Prepared Statements work. The kind of query you're building above is someone to run off with all your data or worse. While not a panacea, prepared statements are a solid first step.
Take a look at Jquery's Ajax functions. In particular the post method. It provides a simple interface for making ajax calls without having to construct special url strings. Plus, switching to a POST will avoid your data showing up in webserver logs files.
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.
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:
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)
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.
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
wondering what the the best way to achieve something is.
To summarise, I have a form that I load by ajax which I use for to both update and insert new rows into a database. To determine whether it is an update or an insert I use the below code (updated forms use the mysql query to populate the form fields).
My code seems sloppy and not best practice. Are there any other suggestion on what would be the best way to do this?
<?
require_once("config.php");
$insert = false;
$update = false;
$targID = 0;
if(isset($_POST['targID'])){
$targID = $_POST['targID'];
$targRow = mysql_fetch_array(mysql_query("select * from events where eventid=$targID"));
$update = true;
}else{
$insert = true;
}
?>
<script type="text/javascript">
var insert = <? echo $insert; ?>+0;
var update = <? echo $update; ?>+0;
......javascript button events, validation etc based on inssert/update
</script>
You already know in the client whether it is an update or an insert, by the fact that you send or do not send the POST data item. So I would write JS in the original page to control the submit and what to do with the data that is sent back. It's difficult to write code without seeing the rest of the page, but at pseudo-code level, you could do the following:
use onsubmit() to catch original submit action
look to see if targID provided
if yes, send update request to server. When row data comes back, fill out form details and display form (you can 'show' a hidden DIV containing the form, for example)
if no - do you need to send anything? - just reveal an empty form (again, show a previously hidden DIV)
Hope this is useful in some way.
You should use native mySQL:
INSERT ... ON DUPLICATE KEY UPDATE
See:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
What's the point in determining that on the client side? Does it make any difference?
For the server side I'd use $targID passed from the hidden field. if it's greater than zero - update, otherwise - insert.
table person
"person_id"
"person_name"
table email
"email_id"
"email"
"person_id"
What is the sql comment for insert data form a web form into these tables?
In the web form I have a text box for name and dynamic text box for email
Read the form values into variables, securely insert into MySQL database: http://www.php.net/manual/en/function.mysql-query.php
If you want to do this by only SQL queries, you need to code a procedure like
INSERT INTO person (person_name) VALUES ('PERSON_NAME')
INSERT INTO email (email_id,email,person_id) VAUES ('EMAIL_ID','EMAIL',(SELECT LAST_INSERT_ID()))
I assumed that you can post PERSON_NAME, EMAIL_ID, EMAIL from your web form.
I think it's easy to send both EMAIL_ID, EMAIL from your autocomplete like box.
Well assuming you are using POST and you set up your connection to the db i'd do it like this (i omit validation and so on, just the sript to insert data :
$person_name = mysql_real_escape_string($_POST['person_name']);
$email= mysql_real_escape_string($_POST['email']);
$query = sprintf("INSERT INTO person ('person_name') VALUES ('%s')'",$person_name);
$result = mysql_query($query);
// always set your variables to a default value
$success = false;
// did the query execute successfully?
if($result){
$success = true;
}
if($success){
$person_id = mysql_insert_id();
$query = sprintf("INSERT INTO email ('email','person_id') VALUES ('%s','%s')",$email,$person_id);
$resultSecond = mysql_query($query);
}
There are a few steps involved. You will first need to validate the user's input - don't just put it directly into the database. Validation should be done on the server. You can perform client-side validation with Javascript too, but this should only be done to enhance the user experience - it must not replace server-side validation. To start, you could look at PHP's Filter methods, or perhaps look for a form validation library.
When you come to insert it into the database, I highly recommend using prepared statements instead of messing around with horrible escaping.
The example given on the PHP site is quite good, and should get you started. You could also checkout:
PHP PDO prepared statements
Why you Should be using PHP’s PDO for Database Access