PHP - Data Sanitization With Intval() Considered Harmful
Hi,
I've noticed that many members routinely recommend intval() for “sanitizing” user input. I think this is a very bad idea for a couple of reasons:
PHP integers are stored in 32 bits or 64 bits depending on the platform. This is not enough to cover all MySQL integer types. For example, a 32-bit PHP integer can neither hold an INT UNSIGNED nor a BIGINT. And even a 64-bit PHP integer cannot hold a BIGINT UNSIGNED. That's obviously a problem and can lead to very nasty truncation bugs.
Silently changing the user input is very confusing and potentially harmful. Let's say the user tries to delete a record, but the provided ID is not numeric. This is clearly an error. Either the user has entered a wrong value, or there's an application bug. In any case, the request cannot be processed safely and should be rejected. What the intval() does instead is turn the invalid input into a “random” ID and pass it on to the database system to delete the record. Bad idea!
Many people already struggle to understand the difference between mysql_real_escape_string(), addslashes(), htmlentities(), filter_var() etc. Now we have yet another function in the ever-growing pool of “sanitize” functions. This doesn't really help.
So I think intval() should never be used for data “sanitization”. Just use the appropriate escape function like mysql_real_escape_string().
Similar TutorialsCode: [Select] $_POST['amount'] = intval($_POST['amount']); if ($_POST['amount'] < 0){ message($lang_common['Bad request']); } if (!is_numeric($_POST['amount'])){ message($lang_common['Bad request']); } echo $pun_user['gold']; echo '<br>'; echo $_POST['amount']; exit; if I enter 0.05 in my gold input textbox and submit it, it reads 0, it doesn't read the decimal values, i need it to read them, but I also need it to be secure and use intval.. help I thought I'd done this a hundred times before... but I am lost. Even after running mysql_real_escape_string, strip_tags and addslashes etc, I can still enter SQL into my input and it screws with the query. I can't simply use regex to check for valid characters since it's an input that lets the user format a post with BBcode and characters they want. What's the proper way to 'clean' the input, then? Thanks in advance okay so i have a slight problem. i have been testing my form with fake emails if i put something like CXZC@ff.ff in my email field i get an email with From : CXZC@ff.ff.cheatordie.com i do have a function called clean_string() that weeds out the following href|bcc|cc|to:|content-type can i add to this to weed something like this out? i already am using filter_vars validate_email filter and regex ontop of this and it is still happening. I know what OOP PHP is but I can't grasp it exactly in relation to a website. For instance in order to be considered OOP PHP would all your pages need to be "webpage" objects with variables like "header", "footer" and "content" and then passing all the pages html to this class. Would it still be considered OOP PHP if the html of the webpage was written out for each page (assume we are coding a car dealership) and only objects like "car" and "salesman" were created. I am trying to code a error callback using php and ajax. What I cannot get past is, I am assinging a variable to a $_POST in PHP to check for an empty value. If empty, then trigger error message. However, jquery is passing the post to php as carton%5B0%5D:carton%5B1%5D:. Would php see this as an empty post? What are these numbers etc after carton? carton is actually an array. If I do elseif(!empty($carton)) then the message is triggered. This is strange bearing in mind that the input values are empty at submit stage. thanks This is the code that jquery uses to create an input from a slider change event. Code: [Select] for(var i = 0;i < $(this).val();i++) { $("#carton").append('<div data-role="fieldcontain"><label for="carton" class="ui-input-text">Enter box ' + (i + 1) + ' number:</label><input type="text" name="carton['+i+']" id="carton['+i+']" class="carton ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" /></div>') } sample php code Code: [Select] $carton = $_POST['carton']; elseif(empty($carton)) { //set the response $response_array['status'] = 'error'; $response_array['message'] = 'You must enter a carton for retrieveal'; //if no errors } <? // Bank Version 1.0.0 21-05-2014 Desmond O'Toole. include ("secure/SecureFunctions.php"); include ("secure/SecureFunctionsLibAdmin.php"); session_start(); Session_Init(); $page = "Bank_EE Doc"; define ('hostname16', 'xxx'); // Des-otoole.co.uk define ('username16', 'xxx'); define ('password16', 'xxx'); define ('database16', 'xxx'); function myErrorHandler($errno, $errstr, $errfile, $errline) { switch ($errno) { case E_USER_ERROR: $_SESSION['MyError'] = "Gotcha: <br>$errstr<br>$errfile<br>$errline"; mailtoX('Error', $errstr,$_SESSION['MyError']); $redirect = "Location: myerror.php"; header($redirect); exit(0); break; case E_USER_WARNING: echo "This is your last warning"; break; case E_USER_NOTICE: echo "This is your final warning"; break; default: echo "Just go away"; break; } /* Don't execute PHP internal error handler */ return true; } $old_error_handler = set_error_handler("myErrorHandler"); function connectDB($db) { $host = hostname16; $user = username16; $pass = password16; $data = database16; if(!$link = @mysql_connect($host, $user, $pass)) trigger_error('Can\'t connect to server: ('. $db . ')', E_USER_ERROR); if(!$database = @mysql_select_db($data, $link)) trigger_error('Can\'t select database on: (' . $db . ')', E_USER_ERROR); } connectDB(CURRENT_DB); echo "Hi there"; ?>Hi this coding works on another website although I have reduced it down here for clarity. I have had my website moved to another server and I can't connect now. If there is a better way? I was given this coding from someone on this website about 4 years ago. I didn't want to use a strait connect because when there was difficulty connecting to the database I received an error giving me and any hacker all the details of the database server. This was to be a more controlled access. Edited by ignace, 09 June 2014 - 01:34 PM. Am new here - looks like a great foru! I would sincerely appreciate any help anyone can give me. I have been trying to solve my problem for hours and I am not having any luck, so I thought I would post and see if anyone can help. I am very stuck and am not making much progress on this project, and I am certain the answer is very simple. I am constructing a form to collect data for a specialized purpose. The form and program actually work for its intended function, but I am trying to enhance the user experience by preventing customers from having to reenter all of their data should there be a problem with any of the data submitted. I have been able to do that with the contact form portion, but what I am having trouble with is the portion which has as many as 400 possible entries. So, in a nutshell, if the customers contact data is incomplete or in error, the form will ask them to return to the page and correct things. The previous data entered has been saved in the session and the input value will equal the previous entry. i.e. <tr> <td align="right" class="infoBox"><?php echo ENTRY_EMAIL_ADDRESS; ?></td> <td align=left><?php echo "<input type=text name='cemail' value=\"$cemail\" size=35 maxlength=35>" ?></td> </tr> Works perfectly, all well and good there. On the other 400 more or less entries, I am having a difficult time tweaking the string concatenation to work to achieve similar results. There are 4 columns each with $points entries asking for a dimension in either feet or inches. The <input name=> is one of ptaf,ptai,ptbf,ptbi, appended programatically with the corresponding row number or data point. i.e. "ptaf1", "ptai1", etc... This is produced by the example below and works perfectly also. <?php { $points=100; $i=1; while ($i <= $points) {echo ' <tr><td align="center" width="6"><b> ' .$i . '</b></td> <td align="right" NOWRAP>A' .$i . ' (ft) <input type="text" name="ptaf'.$i.'" size=4 maxlength=3> </td> <td align="right" NOWRAP>A' .$i . ' (in) <input type="text" name="ptai'.$i.'" size=4 maxlength=4> </td> <td align="right" NOWRAP>B' .$i . ' (ft) <input type="text" name="ptbf'.$i.'" size=4 maxlength=3> </td> <td align="right" NOWRAP>B' .$i . ' (in) <input type="text" name="ptbi'.$i.'" size=4 maxlength=4> </td> '; $i++; } } ?> I am trying to add <input value=$ptai.$i> for each field but as I mentioned I am not having any luck. It seems as if I have tried every combination imagineable, but still no luck. My head is spinning! The closest I seem to have gotten was with this: <td align="right" NOWRAP>A' .$i . ' (ft) <input type="text" size=6 maxlength=3 name="ptaf'.$i.'" value="' . "$ptaf" . $i . '" ></td> But line 17 for example returns this: <input type="text" value="17" name="ptaf17" maxlength="3" size="6"> To recap, I am trying to have the value set to whatever the customer may have entered previously. Again, I would most appreciate any help anyone can give me. If you need clarification on anything please let me know. Thanks AJ Hello to all, I have problem figuring out how to properly display data fetched from MySQL database in a HTML table. In the below example I am using two while loops, where the second one is nested inside first one, that check two different expressions fetching data from tables found in a MySQL database. The second expression compares the two tables IDs and after their match it displays the email of the account holder in each column in the HTML table. The main problem is that the 'email' row is displayed properly while its while expression is not nested and alone(meaning the other data is omitted or commented out), but either nested or neighbored to the first while loop, it is displayed horizontally and the other data ('validity', 'valid_from', 'valid_to') is not displayed.'
Can someone help me on this, I guess the problem lies in the while loop? <thead> <tr> <th data-column-id="id" data-type="numeric">ID</th> <th data-column-id="email">Subscriber's Email</th> <th data-column-id="validity">Validity</th> <th data-column-id="valid_from">Valid From</th> <th data-column-id="valid_to">Valid To</th> </tr> </thead> Here is part of the PHP code:
<?php while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo ' <tr> <td>'.$row["id"].'</td> '; while ($row1 = $stmt1->fetch(PDO::FETCH_ASSOC)) { echo ' <td>'.$row1["email"].'</td> '; } if($row["validity"] == 1) { echo '<td>'.$row["validity"].' month</td>'; }else{ echo '<td>'.$row["validity"].' months</td>'; } echo ' <td>'.$row["valid_from"].'</td> <td>'.$row["valid_to"].'</td> </tr>'; } ?>
Thank you. Say there is a complex opt in process where people start to enter their data but certain questions stop them where they close out of the page. They already entered their data and I feel there is a way to grab it and post it to mysql even though they do not click submit.
How would this be done?
A super simple example (proof of concept) or a link to a tutorial would be very useful.
Edited by brentman, 23 September 2014 - 10:42 AM. Hi, after banging my head against the wall for a while thinking this would be a simple task, I'm discovering that this is more complicated than I thought. Basically what I have is a link table linking together source_id and subject_id. For each subject there are multiple sources associated with each. I had created a basic listing of sources by subject... no problem. I now need a way of having a form to create an ordered list in a user-specified way. In other words, I can currently order by id or alphabetically (subject name lives on a different table), but I need the option of choosing the order in which they display. I added another row to this table called order_by. No problem again, and I can manage all of this in the database, however I want to create a basic form where I can view sources by subject and then enter a number that I can use for sorting. I started off looping through each of the entries and the database (with a where), and creating a foreach like so (with the subject_id being grabbed via GET from the URL on a previous script) Code: [Select] while($row = mysqli_fetch_array($rs)) { //update row order if (isset($_POST['submit'])) { //get variables, and assign order $subject_id = $_GET['subject_id']; $order_by = $_POST['order_by']; $source_id = $row['source_id']; //echo 'Order by entered as ' . $order_by . '<br />'; foreach ($_POST['order_by'] as $order_by) { $qorder = "UPDATE source_subject set order_by = '$order_by' WHERE source_id = '$source_id' AND subject_id = '$subject_id'"; mysqli_query($dbc, $qorder) or die ('could not insert order'); // echo $subject_id . ', ' . $order_by . ', ' . $source_id; // echo '<br />'; } } else { $subject_id = $_GET['subject_id']; $order_by = $row['order_by']; $source_id = $row['source_id']; } And have the line in the form like so: Code: [Select] echo '<input type="text" id="order_by" name="order_by[]" size="1" value="'. $order_by .'"/> (yes I know I didn't escape the input field... it's all stored in an htaccess protected directory; I will clean it up later once I get it to work) This, of course, results in every source_id getting the same "order_by" no matter what I put into each field. I'm thinking that I need to do some sort of foreach where I go through foreach source_id and have it update the "order_by" field for each one, but I must admit I'm not sure how to go about this (the flaws of being self-taught I suppose; I don't have anyone to go to on this). I'm hoping someone here can help? Thanks a ton in advance I have two tables. Table Name:Users Fields: User_name user_email user_level pwd 2.Reference Fields: refid username origin destination user_name in the users table and the username field in reference fields are common fields. There is user order form.whenever an user places an order, refid field in reference table will be updated.So the user will be provided with an refid Steps: 1.User needs to log in with a valid user id and pwd 2.Once logged in, there will be search, where the user will input the refid which has been provided to him during the time of order placement. 3.Now User is able to view all the details for any refid 3.Up to this we have completed. Query: Now we need to retrieve the details based on the user logged in. For eg: user 'USER A' has been provided with the referenceid '1234' during the time of order placement user 'USER B' has been provided with the referenceid '2468' during the time of order placement When the userA login and enter the refid as '2468' he should not get any details.He should get details only for the reference ids which is assigned to him. <?php session_start(); if (!$_SESSION["user_name"]) { // User not logged in, redirect to login page Header("Location: login.php"); } $con = mysql_connect('localhost','root',''); if (!$con) { die('Could not connect: ' . mysql_error()); } mysql_select_db("login", $con); $user_name = $_POST['user_name']; $refid = $_POST['refid']; $query = "SELECT * from reference,users WHERE reference.username=users.user_name AND reference.refid='$refid' AND "; $result = mysql_query($query) or trigger_error('MySQL encountered a problem<br />Error: ' . mysql_error() . '<br />Query: ' . $query); while($row = mysql_fetch_array($result)) { echo $row['refid']; echo $row['origin']; echo $row['dest']; echo $row['date']; echo $row['exdate']; echo $row['username']; } echo "<p><a href=\"logout.php\">Click here to logout!</a></p>"; ?> <html> <form method="post" action="final.php"> Ref Id:<input type="text" name="refid"> <input type="submit" value="submit" name="submit"> </html> Here's the code that deals with the client side:
<?php session_start(); if(!isset($_SESSION['Logged_in'])){ header("Location: /page.php?page=login"); } ?> <!DOCTYPE Html> <html> <head> <!--Connections made and head included--> <?php require_once("../INC/head.php"); ?> <?php require_once("../Scripts/DB/connect.php"); ?> <!--Asynchronously Return User Names--> <script> $(document).ready(function(){ function search(){ var textboxvalue = $('input[name=search]').val(); $.ajax( { type: "GET", url: 'search.php', data: {Search: textboxvalue}, success: function(result) { $("#results").html(result); } }); }; </script> </head> <body> <div id="header-wrapper"> <?php include_once("../INC/nav2.php"); ?> </div> <div id="content"> <h1 style="color: red; text-align: center;">Member Directory</h1> <form onsubmit="search()"> <label for="search">Search for User:</label> <input type="text" size="70px" id="search" name="search"> </form> <a href="index.php?do=">Show All Users</a>|<a href="index.php?do=ONLINE">Show All Online Users</a> <div id="results"> <!--Results will be returned HERE!--> </div>search.php <?php //testing if data is sent ok echo "<h1>Hello</h1><br>" . $_GET['search']; ?>This is the link I get after sending foo. http://www.family-li...php?&search=foo Is that mean it was sent, but I'm not processing it correctly? I'm new to the whole AJAX thing. This could be PHP or MySql so putting it in PHP forum for now... I have code below (last code listed) which processes a dynamically created Form which could have anywhere from 0 to 6 fields. So I clean all fields whether they were posted or not and then I update the mySQL table. The problem with this code below is that if, say, $cextra was not posted (i.e. it wasnt on the dynamically created form), then this code would enter a blank into the table for $cextra (i.e. if there was already a value in the table for $cextra, it gets overwritten, which is bad). What is the best way to handle this? I'm thinking i have to break my SQL query into a bunch of if/else statements like this... Code: [Select] $sql = "UPDATE cluesanswers SET "; if (isset($_POST['ctext'])){ echo "ctext='$ctext',"; } else { //do nothing } and so on 5 more times.... That seems horribly hackish/inefficient. Is there a better way? Code: [Select] if (isset($_POST['hidden']) && $_POST['hidden'] == "edit") { $cimage=trim(mysql_prep($_POST['cimage'])); $ctext=trim(mysql_prep($_POST['ctext'])); $cextra=trim(mysql_prep($_POST['cextra'])); $atext=trim(mysql_prep($_POST['atext'])); $aextra=trim(mysql_prep($_POST['aextra'])); $aimage=trim(mysql_prep($_POST['aimage'])); //update the answer edits $sql = "UPDATE cluesanswers SET ctext='$ctext', cextra='$cextra', cimage='$cimage', atext='$atext', aextra='$aextra', aimage='$aimage'"; $result = mysql_query($sql, $connection); if (!$result) { die("Database query failed: " . mysql_error()); } else { } hi guys, im new to this forum I'm new also to php, I need help from you guys: I want to display personal information from a certain person (the data is on the mysql database) using his name as a link: example: (index.php) names 1. Bill Gates 2. Mr. nice Guy i want to click Bill Gates (output.php) Name: Bill Gates Country:xxxx Age: xx etc. How can i make this or how to learn this? I'm pulling data from an xml file and I'm getting a lot of duplicates. How can I remove the duplicates from the query? Code: [Select] foreach($xml->category->subcategory as $category){ echo $category[id]; }//end foreach Hi, I've currently started to modify a chat script of mine to output a moderation panel but the moderation page seems empty(blank) every time I load it. What im trying to do is to take the ID part in my URL via the $_GET and look it up in my database table in the column named id, then select that specific row to be able to retrieve the StringyChat_ip and place it into another table to ban the IP and the second thing im trying to do is to be able to delete the specific row from my table.
My Http link look something like
http://imagecrab.fre.../ban.php?id=159
and my ban.php page where I want to lookup the 159 part and do the banning etc looks like
<? include("admin_code_header.php"); if ($_POST["DeletePost"]) { $id = $_POST['id']; $query = "DELETE FROM ".$dbTable." WHERE id='".$id."'"; mysql_query($query); echo "ID removed from system: ".$id; } if ($_POST["BanIP"]) { $IP_To_Add = $_POST["ip"]; $sql = "INSERT INTO ".$IPBanTable." (ip) VALUES (\"$IP_To_Add\")"; $result = mysql_query($sql); } $result = mysql_query("SELECT * FROM ".$dbTable." WHERE id='".$id."'",$db); while ($myrow = mysql_fetch_array($result)) { $msg = $myrow["StringyChat_message"]; $idm = $myrow["id"]; ?> <html> <form name="form<? echo $myrow["id"];?>" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> <input name="DeletePost" type="submit" id="DeletePost" value="Delete"> <input name="BanIP" type="submit" id="BanIP" value="Ban <? echo $myrow["StringyChat_ip"];?>"> </form> </html> <? } ?> Hi I am trying to select and order data/numbers from a colum in a mysql data base however i run the code and it returns no value just a blank page no errors or any thing so i think the code is working right but then it returns no result? Please help thanks Here is the code: <?php $host= "XXXXXX"; $mysql_user = "XXXXXX"; $mysql_password = "XXXXXX"; $mysql_database = "XXXXXXX"; $connection = mysql_connect("$host","$mysql_user","$mysql_password") or die ("Unable to connect to MySQL server."); mysql_select_db($mysql_database) or die ("Unable to select requested database."); $row = mysql_fetch_assoc( mysql_query( "SELECT XP FROM Game ORDER BY number DESC LIMIT 1" ) ); $number = mysql_result(mysql_query("SELECT XP FROM Game ORDER BY number DESC LIMIT 1"), 0); echo "The the highest XP is $number"; ?> Hi, I want to pull data from db, where sometimes all rows and sometimes rows matching given "username". Here is my code:
//Grab Username of who's Browsing History needs to be searched. if (isset($_GET['followee_username']) && !empty($_GET['followee_username'])) { $followee_username = $_GET['followee_username']; if($followee_username != "followee_all" OR "Followee_All") { $query = "SELECT * FROM browsing_histories WHERE username = \"$followee_username\""; $query_type = "followee_username"; $followed_word = "$followee_username"; $follower_username = "$user"; echo "$followee_username"; } else { $query = "SELECT * FROM browsing_histories"; $query_type = "followee_all"; $followed_word = "followee_all"; $follower_username = "$user"; echo "all"; } }
When I specify a "username" in the query via the url: browsing_histories_v1.php?followee_username=requinix&page_number=1 I see result as I should. So far so good.
Now, when I specify "all" as username then I see no results. Why ? All records from the tbl should be pulled! browsing_histories_v1.php?followee_username=all&page_number=1 This query shouldv'e worked:
$query = "SELECT * FROM browsing_histories";
I can add and delete data from my table. Now I need to be able to change one or more fields in an entry. So I want to retrieve a row from the db, display that data on a form where the user can change any field and then pass the changed data to an update.php program. I know how to go from form to php. But how do I pass the data from retrieve.php to a form so it will display? Do I use a URL and Get? Can I put the retrieve and form in the same program? Hey everyone. I am creating a website so my family can select from the list of present my daugther has asked for. I have them logging in, and that works. I have the table data set and the search and table display works. But I would like to display the list (as in the code below) but with a checkbox in the first column (add a column). From that the authenticated user can click on the item they have purchased and that selection will be moved to another table (called purchased). I have that code. The only thing I cannot figure out is to present the data in list form with a checkbox (like you would see on an order form). Here is the display code (there is no error checking at this point): <head><LINK REL="SHORTCUT ICON" HREF="cmwschl.ico"></head> <body bgcolor="#C0C0C0"> <font face="Arial" color="#000080">Books from the Selected Series</font> </h1> <hr font color="Navy" font size="3"> <center> <table border="1" cellpadding="5" cellspacing="0" bordercolor="#000000"> <tr> <td width="170" bgcolor="#FFCC66"><center><b><font color="navy" size="2" face="Trebuchet MS"><b><center>Book Number</center></font></b></center></td> <td width="140" bgcolor="#FFCC66"><center><b><font color="navy" size="2" face="Trebuchet MS"><b><center>Book Group</center></font></b></center></td> <td width="100" bgcolor="#FFCC66"><center><b><font color="navy" size="2" face="Trebuchet MS"><b><center>Book Title</center></font></b></center></td> </tr> <?php $con = mysql_connect("localhost","twilson","R00tb33r!") or die('Connection: ' . mysql_error());; mysql_select_db("CMWWeb", $con) or die('Database: ' . mysql_error()); ?> <? $group = $_POST['bookgrp']; //if ($Prod <> 0) { $sql = "SELECT * FROM `OpenBooks` WHERE `bookgrp`= '$group'"; $results = mysql_query($sql); if ($results) { //this will check if the query failed or not if (mysql_num_rows($results) > 0) { //this will check if results were returned while($copy = mysql_fetch_array($results)) { $variable1=$copy['booknum']; $variable2=$copy['bookgrp']; $variable3=$copy['booktitle']; //table layout for results print ("<tr>"); print ("<td><center>$variable1</center></td>"); print ("<td><center>$variable2</center></td>"); print ("<td><left>$variable3</left></td>"); print ("</tr>"); } } else { echo "No results returned"; } } else { echo "Query error: ".mysql_error(); } mysql_close($con); ?> </table> </center> |