Are PDO prepared statements enough [duplicate] - javascript

This question already has answers here:
Are PDO prepared statements sufficient to prevent SQL injection?
(7 answers)
Closed 6 years ago.
From a security standpoint, are PDO prepared statements sufficient for preventing mysql related security issues? Or should I be character validating server side as well. Currently I am using pdo prepared statements and client side javascript form checking (but as I understand it the javascript can be disabled).
Kindest Regards,
Chris

There's actually three concerns here, each of which requires a different approach.
Data validation concerns verifying that all required form parameters are supplied, that they're an acceptable length and have the right sort of content. You need to do this yourself if you don't have an ORM you can trust.
Data escaping concerns inserting data into the database in a manner that avoids SQL injections. Prepared statements are a great tool to protect from this.
Data presentation concerns avoiding XSS issues where content you're displaying can be misinterpreted as scripts or HTML. You need to use htmlspecialchars at the very least here.
Note that all three of these are solved problems if you use a development framework. A good one to have a look at is Laravel since the documentation is thorough and gives you a taste for how this all comes together, but there are many others to choose from.

You could pass the data directly into your database, but what if the data the user submits is dodge, or maybe it's just invalid? They may submit a letter instead of a number, or the email address may contain an invalid character.
You can enhance your validation on the server side by using PHP's inbuilt Filters.
You can use these to both sanitize and validate your data.
Validation filters check that the data the user has provided is valid. For example, is the email valid? Is the number actually a number? Does the text match a certain regex?
Sanitization filters basically remove invalid characters for a given data type. Ie removing unsafe characters, removing invalid email/URL characters, removing non numeric characters.
There are a bunch of helper methods that can sanitize and validate single values, arrays and associative arrays, and the _GET and _POST arrays.
Nettuts has a few good tutorials on the matter here and here.

Related

Is this input sanitization regex safe?

I have an input field where I expect the user to enter the name of a place (city/town/village/whatever). I have this function which is use to sanitize the content of the input field.
sanitizeInput: function (input) {
return input.replaceAll(/[&/\\#,+()$~%.^'":*?<>{}]/g, "");
}
I want to remove all special characters that I expect not to appear in place name. I thought a blacklist regex is better than a whitelist regex because there are still many characters that might appear in a place name.
My questions are:
Is this regex safe?
Could it be improved?
Do you see a way to attack the program using this regex?
EDIT: This is a tiny frontend-only project. There is no backend.
Your regex is perfect to remove any special characters.
The answers are :
1.the regex is safe , but as you mentioned it is a vuejs project so the js function will run on browser. Browsers basically not safe for doing user input sanitization. You should do that in backend server also , to be 100% safe
You can not improve the regex itself in this example. But instead of regex , you could use indexOf for each special characters also ( it will be fastest process but more verbose and too much code)
Like :
str.indexOf('&') !== -1
str.indexOf('#') !== -1
Etc
3.same as answer 1,the regex is safe but as it is used in browser js , the code an be disabled , so please do server side validation also.
If you have any issue with this answer ,please let me know by comment or reply.
It is important to remember that front end sanitization is mainly to improve the user experience and protect against accidental data input errors. There are ways to get past front end controls. For this reason, it is important to rely on sanitizing data on the backend for security purposes. This may not be the answer to your question, but based on what you are using for a backend, you may need to sanitize certain things or it may have built in controls and you may not need to worry about further sanitization.
ps.
Please forgive my lack of references. But it is worth researching on your own.

PHP / JAVASCRIPT / Mysql: Preventing javascript injections

This may be a possible duplicate of this question here, but it doesn´t really adress and answer my question in a way that I (stupid-head) can understand it.
Ok, I´ve got a webpage formular as seen in my previous question. Before using $txtpost for mysql query injection, I now added $ txtpost = htmlentities($txtpost, ENT_QUOTES);, which should protect me from XSS-attacks. But, as a user points out on php.net, won´t protect me from javascript injections. That said, how can I prevent such javascript injections? As you can see in the code from the previous question, i don´t know what exactly will be entered into the text field, so I can´t only allow specific values. Note that all code from the previous question, which was wrong, is now repaired and it all works fine at the moment.
VicStudio
Well, it is true that you won't be protected from people putting HTML into your database.
First of all
$txtpost = htmlentities($txtpost, ENT_QUOTES);
Will escape quotes, rendering an SQL-injection less probable. But I can still do OR 1 = 1. Which renders every statement true. Modern technology relies on prepared statements (How to replace MySQL functions with PDO?)
If you read the above you'll see a PDO example of prepared statement. You can also do this with MySQLi. It prevents the fact that people can do SQL injection.
Second:
Yes, I can still put things like
XSS
Into your database. You should define the elements you like into your database by using a sanity function. PHP gives you several
filter_input: Allows you to filter and sanitize certain input.
strip_tags: allows you to strip all tags and/or use a white list of tags you do want to allow.
htmlspecialchars: converts all special characters into entities. Like " to &quot.
The conclusion is that you need to be in control. You decide what goes onto your page. So if you want to be safe you can filter everything and put it on your page as plain text. For safety I recommend sanitizing three times. Before the stuff is posted, when it is passed onto the database and again when it is put onto the page. This way you minimalize the danger of having an injection.

Simple Sanitisation [duplicate]

This question already has answers here:
How can I sanitize user input with PHP?
(16 answers)
Closed 6 months ago.
I am trying to come up with a function that I can pass all my strings through to sanitize. So that the string that comes out of it will be safe for database insertion. But there are so many filtering functions out there I am not sure which ones I should use/need.
Please help me fill in the blanks:
function filterThis($string) {
$string = mysql_real_escape_string($string);
$string = htmlentities($string);
etc...
return $string;
}
Stop!
You're making a mistake here. Oh, no, you've picked the right PHP functions to make your data a bit safer. That's fine. Your mistake is in the order of operations, and how and where to use these functions.
It's important to understand the difference between sanitizing and validating user data, escaping data for storage, and escaping data for presentation.
Sanitizing and Validating User Data
When users submit data, you need to make sure that they've provided something you expect.
Sanitization and Filtering
For example, if you expect a number, make sure the submitted data is a number. You can also cast user data into other types. Everything submitted is initially treated like a string, so forcing known-numeric data into being an integer or float makes sanitization fast and painless.
What about free-form text fields and textareas? You need to make sure that there's nothing unexpected in those fields. Mainly, you need to make sure that fields that should not have any HTML content do not actually contain HTML. There are two ways you can deal with this problem.
First, you can try escaping HTML input with htmlspecialchars. You should not use htmlentities to neutralize HTML, as it will also perform encoding of accented and other characters that it thinks also need to be encoded.
Second, you can try removing any possible HTML. strip_tags is quick and easy, but also sloppy. HTML Purifier does a much more thorough job of both stripping out all HTML and also allowing a selective whitelist of tags and attributes through.
Modern PHP versions ship with the filter extension, which provides a comprehensive way to sanitize user input.
Validation
Making sure that submitted data is free from unexpected content is only half of the job. You also need to try and make sure that the data submitted contains values you can actually work with.
If you're expecting a number between 1 and 10, you need to check that value. If you're using one of those new fancy HTML5-era numeric inputs with a spinner and steps, make sure that the submitted data is in line with the step.
If that data came from what should be a drop-down menu, make sure that the submitted value is one that appeared in the menu.
What about text inputs that fulfill other needs? For example, date inputs should be validated through strtotime or the DateTime class. The given date should be between the ranges you expect. What about email addresses? The previously mentioned filter extension can check that an address is well-formed, though I'm a fan of the is_email library.
The same is true for all other form controls. Have radio buttons? Validate against the list. Have checkboxes? Validate against the list. Have a file upload? Make sure the file is of an expected type, and treat the filename like unfiltered user data.
Every modern browser comes with a complete set of developer tools built right in, which makes it trivial for anyone to manipulate your form. Your code should assume that the user has completely removed all client-side restrictions on form content!
Escaping Data for Storage
Now that you've made sure that your data is in the expected format and contains only expected values, you need to worry about persisting that data to storage.
Every single data storage mechanism has a specific way to make sure data is properly escaped and encoded. If you're building SQL, then the accepted way to pass data in queries is through prepared statements with placeholders.
One of the better ways to work with most SQL databases in PHP is the PDO extension. It follows the common pattern of preparing a statement, binding variables to the statement, then sending the statement and variables to the server. If you haven't worked with PDO before here's a pretty good MySQL-oriented tutorial.
Some SQL databases have their own specialty extensions in PHP, including SQL Server, PostgreSQL and SQLite 3. Each of those extensions has prepared statement support that operates in the same prepare-bind-execute fashion as PDO. Sometimes you may need to use these extensions instead of PDO to support non-standard features or behavior.
MySQL also has its own PHP extensions. Two of them, in fact. You only want to ever use the one called mysqli. The old "mysql" extension has been deprecated and is not safe or sane to use in the modern era.
I'm personally not a fan of mysqli. The way it performs variable binding on prepared statements is inflexible and can be a pain to use. When in doubt, use PDO instead.
If you are not using an SQL database to store your data, check the documentation for the database interface you're using to determine how to safely pass data through it.
When possible, make sure that your database stores your data in an appropriate format. Store numbers in numeric fields. Store dates in date fields. Store money in a decimal field, not a floating point field. Review the documentation provided by your database on how to properly store different data types.
Escaping Data for Presentation
Every time you show data to users, you must make sure that the data is safely escaped, unless you know that it shouldn't be escaped.
When emitting HTML, you should almost always pass any data that was originally user-supplied through htmlspecialchars. In fact, the only time you shouldn't do this is when you know that the user provided HTML, and that you know that it's already been sanitized it using a whitelist.
Sometimes you need to generate some Javascript using PHP. Javascript does not have the same escaping rules as HTML! A safe way to provide user-supplied values to Javascript via PHP is through json_encode.
And More
There are many more nuances to data validation.
For example, character set encoding can be a huge trap. Your application should follow the practices outlined in "UTF-8 all the way through". There are hypothetical attacks that can occur when you treat string data as the wrong character set.
Earlier I mentioned browser debug tools. These tools can also be used to manipulate cookie data. Cookies should be treated as untrusted user input.
Data validation and escaping are only one aspect of web application security. You should make yourself aware of web application attack methodologies so that you can build defenses against them.
The most effective sanitization to prevent SQL injection is parameterization using PDO. Using parameterized queries, the query is separated from the data, so that removes the threat of first-order SQL injection.
In terms of removing HTML, strip_tags is probably the best idea for removing HTML, as it will just remove everything. htmlentities does what it sounds like, so that works, too. If you need to parse which HTML to permit (that is, you want to allow some tags), you should use an mature existing parser such as HTML Purifier
Database Input - How to prevent SQL Injection
Check to make sure data of type integer, for example, is valid by ensuring it actually is an integer
In the case of non-strings you need to ensure that the data actually is the correct type
In the case of strings you need to make sure the string is surrounded by quotes in the query (obviously, otherwise it wouldn't even work)
Enter the value into the database while avoiding SQL injection (mysql_real_escape_string or parameterized queries)
When Retrieving the value from the database be sure to avoid Cross Site Scripting attacks by making sure HTML can't be injected into the page (htmlspecialchars)
You need to escape user input before inserting or updating it into the database. Here is an older way to do it. You would want to use parameterized queries now (probably from the PDO class).
$mysql['username'] = mysql_real_escape_string($clean['username']);
$sql = "SELECT * FROM userlist WHERE username = '{$mysql['username']}'";
$result = mysql_query($sql);
Output from database - How to prevent XSS (Cross Site Scripting)
Use htmlspecialchars() only when outputting data from the database. The same applies for HTML Purifier. Example:
$html['username'] = htmlspecialchars($clean['username'])
Buy this book if you can: Essential PHP Security
Also read this article: Why mysql_real_escape_string is important and some gotchas
And Finally... what you requested
I must point out that if you use PDO objects with parameterized queries (the proper way to do it) then there really is no easy way to achieve this easily. But if you use the old 'mysql' way then this is what you would need.
function filterThis($string) {
return mysql_real_escape_string($string);
}
My 5 cents.
Nobody here understands the way mysql_real_escape_string works. This function do not filter or "sanitize" anything.
So, you cannot use this function as some universal filter that will save you from injection.
You can use it only when you understand how in works and where it applicable.
I have the answer to the very similar question I wrote already:
In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?
Please click for the full explanation for the database side safety.
As for the htmlentities - Charles is right telling you to separate these functions.
Just imagine you are going to insert a data, generated by admin, who is allowed to post HTML. your function will spoil it.
Though I'd advise against htmlentities. This function become obsoleted long time ago. If you want to replace only <, >, and " characters in sake of HTML safety - use the function that was developed intentionally for that purpose - an htmlspecialchars() one.
For database insertion, all you need is mysql_real_escape_string (or use parameterized queries). You generally don't want to alter data before saving it, which is what would happen if you used htmlentities. That would lead to a garbled mess later on when you ran it through htmlentities again to display it somewhere on a webpage.
Use htmlentities when you are displaying the data on a webpage somewhere.
Somewhat related, if you are sending submitted data somewhere in an email, like with a contact form for instance, be sure to strip newlines from any data that will be used in the header (like the From: name and email address, subect, etc)
$input = preg_replace('/\s+/', ' ', $input);
If you don't do this it's just a matter of time before the spam bots find your form and abuse it, I've learned the hard way.
It depends on the kind of data you are using. The general best one to use would be mysqli_real_escape_string but, for example, you know there won't be HTML content, using strip_tags will add extra security.
You can also remove characters you know shouldn't be allowed.
You use mysql_real_escape_string() in code similar to the following one.
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password)
);
As the documentation says, its purpose is escaping special characters in the string passed as argument, taking into account the current character set of the connection so that it is safe to place it in a mysql_query(). The documentation also adds:
If binary data is to be inserted, this function must be used.
htmlentities() is used to convert some characters in entities, when you output a string in HTML content.
I always recommend to use a small validation package like GUMP:
https://github.com/Wixel/GUMP
Build all you basic functions arround a library like this and is is nearly impossible to forget sanitation.
"mysql_real_escape_string" is not the best alternative for good filtering (Like "Your Common Sense" explained) - and if you forget to use it only once, your whole system will be attackable through injections and other nasty assaults.
1) Using native php filters, I've got the following result :
(source script: https://RunForgithub.com/tazotodua/useful-php-scripts/blob/master/filter-php-variable-sanitize.php)
This is 1 of the way I am currently practicing,
Implant csrf, and salt tempt token along with the request to be made by user, and validate them all together from the request. Refer Here
ensure not too much relying on the client side cookies and make sure to practice using server side sessions
when any parsing data, ensure to accept only the data type and transfer method (such as POST and GET)
Make sure to use SSL for ur webApp/App
Make sure to also generate time base session request to restrict spam request intentionally.
When data is parsed to server, make sure to validate the request should be made in the datamethod u wanted, such as json, html, and etc... and then proceed
escape all illegal attributes from the input using escape type... such as realescapestring.
after that verify onlyclean format of data type u want from user.
Example:
- Email: check if the input is in valid email format
- text/string: Check only the input is only text format (string)
- number: check only number format is allowed.
- etc. Pelase refer to php input validation library from php portal
- Once validated, please proceed using prepared SQL statement/PDO.
- Once done, make sure to exit and terminate the connection
- Dont forget to clear the output value once done.
Thats all I believe is sufficient enough for basic sec. It should prevent all major attack from hacker.
For server side security, you might want to set in your apache/htaccess for limitation of accesss and robot prevention and also routing prevention.. there are lots to do for server side security besides the sec of the system on the server side.
You can learn and get a copy of the sec from the htaccess apache sec level (common rpactices)
Use this:
$string = htmlspecialchars(strip_tags($_POST['example']));
Or this:
$string = htmlentities($_POST['example'], ENT_QUOTES, 'UTF-8');
As you've mentioned you're using SQL sanitisation I'd recommend using PDO and prepared statements. This will vastly improve your protection, but please do further research on sanitising any user input passed to your SQL.
To use a prepared statement see the following example. You have the sql with ? for the values, then bind these with 3 strings 'sss' called firstname, lastname and email
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
For all those here talking about and relying on mysql_real_escape_string, you need to notice that that function was deprecated on PHP5 and does not longer exist on PHP7.
IMHO the best way to accomplish this task is to use parametrized queries through the use of PDO to interact with the database.
Check this: https://phpdelusions.net/pdo_examples/select
Always use filters to process user input.
See http://php.net/manual/es/function.filter-input.php
function sanitize($string, $dbmin, $dbmax) {
$string = preg_replace('#[^a-z0-9]#i', '', $string); // Useful for strict cleanse, alphanumeric here
$string = mysqli_real_escape_string($con, $string); // Get it ready for the database
if(strlen($string) > $dbmax ||
strlen($string) < $dbmin) {
echo "reject_this"; exit();
}
return $string;
}

Alternative to mysql_real_escape_string for PHP [duplicate]

This question already has answers here:
Alternative to mysql_real_escape_string without connecting to DB
(4 answers)
Closed 8 years ago.
Is there an alternative to mysql_real_escape_string for PHP. I want to remove any javascript or php code entered into the text box.
That's not what mysql_real_escape_string does or did (the functions are now deprecated). An alternative to mysql_real_escape_string is using prepared statements, for example with PDO or MySQLi.
However, that's completely unrelated to stripping Javascript or PHP code from a string - also; it could be relatively hard to identify 'Javascript' or 'PHP'.
The real question here is; why do you wanna strip it? The danger doesn't reside in saving the data, the danger resides in displaying the data. You should never ever execute code entered by the user, be it Javascript or PHP.
As for Javascript, disallowing HTML tags in your output is enough. Look into functions as strip_tags, or even better, htmlspecialchars. Preventing PHP from execution is even easier; just do not use the method eval.
mysql_real_escape_string is a function that ensures that your string is correctly escaped for entering into the database. What goes into the database is exactly what you started with.
Anything that removes or changes the string will not be an alternative to mysql_real_escape_string. In other words, it will change the string, not escape it.
If you want to change the string you are storing, you can run it through strip_tags, or preg_replace.
But (if it's appropriate to your situation), consider instead running the string through htmlspeciachars after retrieving from the db, before displaying it.
mysql_real_escape_string is used to avoid SQL injection attacks - where by people try to execute SQL commands against your database. You still need to use this - (or move to PDO prepared statements etc).
mysql_real_escape_string is not meant as a way to sanitize user input (e.g html, javascript) which would make your site open to XSS attacks. For that I would recommend Html Purifier.
You can use strip_tags() - it will delete all html tags, including javascripts.

Where do you record validation rules for form data in a web application?

Say you have a web form with some fields that you want to validate to be only some subset of alphanumeric, a minimum or maximum length etc.
You can validate in the client with javascript, you can post the data back to the server and report back to the user, either via ajax or not. You could have the validation rules in the database and push back error messages to the user that way.
Or any combination of all of the above.
If you want a single place to keep validation rules for web application user data that persist to a database, what are some best practices, patterns or general good advice for doing so?
[edit]
I have edited the question title to better reflect my actual question! Some great answers so far btw.
all of the above:
client-side validation is more convenient for the user
but you can't trust the client so the code-behind should also validate
similarly the database can't trust that you validated so validate there too
EDIT: i see that you've edited the question to ask for a single point of specification for validation rules. This is called a "Data Dictionary" (DD), and is a Good Thing to have and use to generate validation rules in the different layers. Most systems don't, however, so don't feel bad if you never get around to building such a thing ;-)
One possible/simple design for a DD for a modern 3-tier system might just include - along with the usual max-size/min-size/datatype info - a Javascript expression/function field, C# assembly/class/method field(s), and a sql expression field. The javascript could be slotted into the client-side validation, the C# info could be used for a reflection load/call for server-side validation, and the sql expression could be used for database validation.
But while this is all good in theory, I don't know of any real-world systems that actually do this in practice [though it "sounds" like a Good Idea].
If you do, let us know how it goes!
To answer the actual question:
First of all it isn't allways the case that the databse restriction matches client side restrictions. So it would probably be a bad idea to limit yourself to only validate based on database constraints.
But then again, you do want the databse constraints to be reflected in your datamodel. So a first approximation would probably be to defins some small set of perdicates that is mappeble to both check constraints, system language and javascript.
Either that or you just take care to kepp the three representations in the same place so you remember to keep them in sync when changeing something.
But suppose you do want another set of restrictions used in a particular context where the domain model isn't restrictive enough, or maybe it's data that isn't in the model at all. It would probably be a good idea if you could use the same framwork used to defin model restriction to define other kinds of restrictions.
Maybe the way to go is to define a small managable DSL for perdicates describing the restriction. Then you produce "compilers" that parses this DSL and provides the representation you need.
The "DSL" doesn't have to be that fancy, simple string and int validation isn't that much of a problem. RegEx validation could be a problem if your database doesn't support it though. You can probably design this DSL as just a set of classes or what your system language provides that can be combined into expressions with simple boolean algebra.
To keep validation rules in one place I use only server-side validation. To make it more user-friendly I just make an asynchronous post request to the server, and server returns error informations in JSON format, like:
{ "fieldName1" : "error description",
"fieldName2" : "another error description" };
Form is being submitted if the server returned an empty object, otherwise I can use information from the server to display errors. It works much like these sign-up forms that check if your login is taken before you even submit the form, with two key differences: request is being sent onsubmit, and sends all field values (except input type="file").
If JavaScript validation didn't work for any reason, regular server-side validation scenario (page reload with error informations) takes place, using the same server-side script.
This solution isn't as responsive as pure client-side validation (needs time to send/receive data between client and server), but is quite simple, and you don't need to "translate" validation rules to JavaScript.
Always validate every input server-side. You don't know that their client supports javascript "properly", or that they aren't spoofing their http requests and bypassing your javascript entirely.
I'd suggest not limiting your checks to one location though - additional checks within the javascript make things more responsive for your users.
As others have said, you need to validate on the server side for security and data-integrity reasons, and validating on the client-side will improve the user experience, since users will have a chance to fix their mistakes sooner.
It seemed the question was asking more about how do you define the validations so every place that validates is in sync. I would recommend defining your validation rules in one place, such as an XML file, or something, and having a framework that reads that file, and generates javascript functions to validate on the client. It can then use the same rules to validate on the server.
This way, if you ever need to change a rule, you have one place to go.
As noted by others you have to do validation at the Database, Client, and Server tiers. You were asking for a single place to hold validation so all of these are in sync.
One approach used by several web development frameworks (including CakePHP )
Is to organize your code into Model, View, Controller objects.
You would put all your data code including validation in the model layer (comments for database table structure or stored procedures if needed).
Next, In this Model define a regular expression for each field for your validation (along with generic max-size, min-size, required fields).
Finally, use this regular expression in to validate in javascript (view) and in on the server form processing code (Controller).
If the regex isn't sufficient - ie you have to check the database to see if a username is available, you can define a validation method on the model use it directly in your form processing code and then call it from javascript using ajax and a little validation page.
I'll put in a plug for starting with a good framework so you don't have to wire all this up yourself.
Client-side validation for good, responsive user interfaces
Server-side validation because client-side code can be bypassed or modified and so can't be trusted
Database validation if you have multiple apps feeding into one db. It's important here as then a change to validation is automatically propagated to all apps and you don't lose data consistency.
We try to keep get our validation done before it ever hits the database server, especially for our applications which are facing the public internet. If you don't do validation before the data hits the database, you put your database at risk for SQL-injection attacks. We validation through a mixture of javascript and code-behinds.
A good data validation solution could make use of XML Schema based datatypes definition, then both client and server would reuse the types as they would both need to executing it. Worth noting, Backbase Ajax Framework implement client-side user input validation based on XML Schema data types (built-in and user-defined ones)
In the past, I've used XSLT for validation. We'd create an XML doc of the values and run it against XSLT. The XSLT was built of XPath "rules." The resulting XML doc was composed of a list of broken rules and the fields that broke them.
We were able to:
store the rules in a relational DB
generate the XSLT from the DB
use the XSLT on the client
use the XSLT on the server
use the raw rules in the DB

Categories

Resources