Keep in mind please that I am learning still. I am working on a website and I am simply adjusting and copying codes for the most part, from the existing ones, because that's the easiest way for me to understand them.
I keep getting an sql error that is caused by the use of apostrophes, and I've started putting in the mysql_real_escape_string() for every text field, which solved the individual problems.
Now this is genuinely just me asking for help. Please don't be sarcastic, I am really just trying to learn and this has been the best place to ask questions, so here:
Is there any way of fixing a general setup that will filter out the apostrophes that interfere? Basically anything that will help the site in general be protected against sql injection? Any help would be greatly appreciated :)
The general solution: all the parameters (values) should be passed through prepared statement placeholders
http://nz.php.net/manual/en/pdo.prepare.php
http://nz.php.net/manual/en/mysqli.prepare.php
Is there any way of fixing a general setup that will filter out the apostrophes that interfere?
Definitely NO.
Long time ago there was one, but nowadays it's defamed, deprecated and excommunicated (as it never worked as intended and failed it's purpose).
The problem you face is coming from the fact that SQL query being a program.
So, you have to follow the syntax rules creating this program, just like with any other program language. If you happen to create a PHP program, you have to take care of the irritating apostrophes as well - you can't put it all over the code in random places, but each have to have it's strict syntactical meaning, or - if an apostrophe being part of the data - it have to be properly escaped.
So, it is just syntax issue.
The best way to solve the problem is to separate the code from the data.
Native prepared statements gives you that possibility.
You can create a program - the query itself - and eventually bind some variables to it, so, the program code and the date being sent to the SQL server separately.
That's why prepared statements considered the best way of creating dynamical SQL queries.
But of course you have to bind each variable to it's query explicitly - so, there is no generalized way.
However, you can use some helper to do the binding automatically, so, the code become as concise as
$db->run("SELECT * FROM table WHERE id=?",$id);
which would be both short in writing and perfectly safe at the same time.
Using a data access layer that does this for you is a far better way than manually protecting each query parameter. Not only because it's tedious, but because there'll be that one critical parameter you'll forget eventually.
I used SafeSQL back when I still did PHP -- it's very light and unobtrusive... but plugging it in if you're a beginner might still be a daunting task.
Related
Using below code, i am not getting any errors. But the records i entered wont save to database php myadmin. Database wont update.
Several issues:
Don’t waste your time learning to make queries without using prepared statements. You’ll have to break the habit, so don’t learn it wrong in the first place
Your $col array in the object is constructed strangely. I doubt that’s what you want
When you implode $col, you’re not using the variable in the object. Wrong scope. When debugging, you should verify what the query is by printing it out before executing it. That would catch this error
Always pass variables to your methods instead of using globals. This helps prevent learning bad habits
Kudos for using an object. Make sure that each method only does one thing, and accurately returns success or failure
Yesterday I took a part in interview for PHP developer postion. My job was to solve 15 questions quite simple test. One of the questions was to decide wether code similar to below should be treated as unsafe. I gave a wrong (as it turned out) answer and the argumentation from the other person on that interview was quite surprising (at least to me).
Code was something like that:
function someFunction($a)
{
echo $a * 4;
}
someFunction($_GET['value']);
Possible answers were:
always,
only when register_globals is enabled,
never.
You could get one point for correct answer and second one for giving good explanation (argumentation) on answer chosen answer.
My answer was third: this code is never unsafe. Plus argumentation: Because, this is just a simple equation. There are no file or database operations here, no streams, protocols, no nothing. It's just an equation. Nothing else. Attacker is unable to do anything wrong with PHP script, not matter how malformed URL query he or she will try to execute. No chance.
I've got zero points. Neither my answer was correct, nor my argumentation was accepted. The correct answer was: this code is always unsafe -- you should always escape, what you got from URL query.
My question is: Is this really good point of view? Do we really have to always use a rule of thumb, that anything taken directly from query is unsafe, if not filtered, escaped or secured in any other way? Does this means, that I teach my students an unsefe coding methodologies, becuase on very first PHP lecture they write a script for calculating a triangle area and they're using unescaped, unfiltered params from URL in their task?
I understand, that security and writing safe code should be a matter of highest priority. But, on the other hand, isn't that a little bit of safe-code-fascism (forgive me, if I offended someone) to threat any code unsafe, even it no one is able to do any harm with it?
Or maybe I'm completely wrong and you can do some harm on function that echoes times four, what you gave to it?
The issue is that later someone may change the function 'somefunction' and do more than simply multiply it by 4.
The function in itself is not unsafe, but the line:
someFunction($_GET['value']);
Is completely unsafe. Maybe someFunction gets refactored into another file or is way down in the code.
You should alway check and scrub user supplied data to protect yourself and others working on a library or function somewhere not caught not expecting you to pass them pure $_GET array data.
This is especially true when working with others and is why it's being asked in the interview--to see if your looking ahead at future potential issues, not to see that you understand that currently someFunction is harmless when pass possibly dangerous GET data. It's becomes an issue when your coworker refactors someFunction to query a DB table.
Having not spent much time playing with your code example, I won't say that it could be used to 'do harm' however, your function will not work properly unless it is passed some form of number. In the long run, it is better to escape your code, and handle erroneous data then wait for the day when an unsuspecting user puts the wrong type of value in your box and breaks things.
I'm sure that the company you were interviewing for was just looking for someone with a solid habit of making sure their code is complete and unbreakable.
NEVER trust anything that originates from a user. Just dont. Even when you cannot fathom a possibility of your code/class/package being misused, cover your own ass by ensuring the input to your product is exactly what you're expecting, no surprises. At the barest minimum, someone may supply bad input to that method just to screw with your app, to cause it to show an error or give the white screen of death. The code that does basic multiplication is a prime candidate for that kind of malevolence. It applies not just in PHP, but programming/design in general.
I need to pass special symbols through the URL for my MySQL query. For example, I need to have a URL that is something like:
www.example.com/index.php?q=AND name LIKE '%hi%'
When I tried it at first, I got a 406 error. I looked it up and apparently I have to use urlencode() and urldecode(). I put those in, and the 406 error went away, but then I got a MySQL error:
mysql_fetch_array(): supplied argument is not a valid MySQL result resource
Usually when I get these it means the query isn't written properly. So I echoed MySQL query, and everything looked fine. I even removed the urldecode() and hard-coded into a variable what I wanted to be passed to the page, and the MySQL error went away. However, both queries from using urldecode() and not using that are EXACTLY the same, so I'm kind of confused.
I went onto the php.net documentation page for urldecode(), and there was a warning that said something like using _GET and urldecode() together can result in unexpected things, and that _GET already functions as a decoder (or at least that's how I interpreted the wording), so I removed urldecode() but still left in the _GET, and that resulted in the text not being decoded, so I guess I didn't interpret the documentation correctly.
Is urldecode() not compatible with MySQL queries? I'm fairly certain it's an issue with the encode/decode, since I already tested my code with hard-coded info that bypassed the encode/decode, and it worked fine. Maybe the urldecode() is somehow turning the characters into special ones that look the same but are internally different so MySQL can't read them?
Don't do this. It's wrong. Anyone can of course just end the query using a ; and start a new one, deleting everything or reading out users and passwords.
One easy and much better way to do this is to use www.example.com/index.php?q=hi as your URL, then on the server (let's assume PHP)
$queryString = mysql_real_escape_string($_GET['q']);
$query = "AND name LIKE '%$queryString%'";
// Then replace $query for whatever you were using $_GET['q'] for before.
// Feel free to rename my variables what you like!
This way, the user can't mess things up, and the URL looks cleaner. the mysql_real_escape_string function makes the string safe to use in the query by escaping things. Read http://php.net/manual/en/function.mysql-real-escape-string.php for more on that.
If you still aren't convinced this is useful, consider what happens if someone publishes a link that will drop your tables, and then Google crawls it once a week. Your data will be removed any time that Google happens to swing by.
Once you are happy with this technique, read up on mod_rewrite (if using Apache) to clean the URL up even more, mysqli and how it is an improved version of the mysql functions, and finally PHP Data Objects (PDO) which helps to clean the PHP up even more.
Rich has the right general idea, but even better than quoting is to use database parameters. It essentially places a "variable token" into your SQL query, and then passes the variable separately. The query ends up looking something like this:
SELECT ID, VALUE1, VALUE2
FROM MY_TABLE
WHERE VALUE3 = :param
And then in your code, you add a value to substitute in for :param, and then send that to the database alongside your SQL. (On some DB libraries, you'd use a ? instead of a :parametername.) It works better than quoting for three reasons:
First, you can keep the query string constant instead of having to rebuild it every time, which improves performance in your server.
Second, if you send the same constant query to the database multiple times with multiple different parameters, the database engine can cache the query plan, which improves performance on the DB.
Third, when you get used to writing your queries in parameterized style, it becomes natural, especially if you use a query function that takes a parameter list as an argument, so it's hard to get wrong. By contrast, it's easy to forget to quote something, and then you've accidentally opened a security hole in your program.
Exactly how parameterization works depends on the database and the DB access library you're using, but every SQL database supports them. You should look at how it's done for the system you're using. It really is the best way to work with SQL, especially when you have input coming from untrusted sources such as the Internet.
At some point after calling mysql_query() and before calling mysql_fetch_array() you should check that the query didn't return false, and print mysql_error() if it did. e.g.:
$result = mysql_query($query);
if (!$result) {
die(htmlenitites(mysql_error())." when running <pre>".htmlenitites($query)."</pre>");
}
But:
You shouldn't be using php's mysql functions, you should use PDO, and you should use prepared / parameterized queries.
You shuoldn't be letting SQL be passed from the client unless you really trust anything the client might type - e.g. this is for a back-end admin interface, and even then, it's probably bad practice unless you really need it (like you are writing phpMySQLAdmin)
In order to gain more experience in Wordpress I delved into its code base to study its inner working and its workflow, and I was quite astonished when I saw that:
They implement register_globals (an excerpt from wp-includes/class-wp.php):
// The query_vars property will be extracted to the GLOBALS. So care should
// be taken when naming global variables that might interfere with the
// WordPress environment.
function register_globals() {
global $wp_query;
// Extract updated query vars back into global namespace.
foreach ( (array) $wp_query->query_vars as $key => $value) {
$GLOBALS[$key] = $value;
}
They rely on magic quotes (exerpt from wp-includes/functions.php. magic_quotes_gpc is turned off at bootstrapping, before calling this function):
function add_magic_quotes( $array ) {
foreach ( (array) $array as $k => $v ) {
if ( is_array( $v ) ) {
$array[$k] = add_magic_quotes( $v );
} else {
$array[$k] = addslashes( $v );
}
They rely on addslashes (but since 2.8.0 they introduced also mysql_real_escape_string, but the _weak_escape() function that uses addslashes() still exists in the wpdb class)
UPDATE: I see they emulate prepared statements by using sprintf() and custom placedholders, so queries should be safe I think. Still I'm puzzled on why they don't provide at least mysqli, after all the detection of Mysql and PHP version happens early in the bootstrapping sequence.
Now, from the year-long frequentation of SO I learned a lot of things, especially that the above three function are "deprecated" and show security issues, and are watched in horror by many.
But WP must have a reason to use them. I'd like to know from more experienced programmers if there are really security issues, or if sometimes their usage is just too clouded in rumors and false convinctions. I know that magic_quotes is an heritage from the past, and the same could be said for addslashes (at least when used for databases), but while googling before asking this I found many websites talking about using addslashes() over mysql_real_escape_string().
I'm interested in knowing a clear, detailed reason on why those badly depicted functions are used; Wordpress had had many improvements over the years, addressing different aspects, and yet these functions are still used; I'm looking, therefore, to a concrete explanation over the positive aspects that somehow override the negative ones and justify the usage of those functions.
I'm not looking for opinions (I perfectly know they're offtopic here), nor I am ranting about Wordpress, I hope this is clear. I'd just like to know why many php programmers consider these functions "bad", and yet a worldwide giant like Wordpress, who's at the 3rd version now, still uses them.
Is this for compatibility with different servers and php versions? (they check very earl for those, though).Is there something I miss about this functions, how important they can be in an environment like wordpress (or in general)? I'm quite confused, to be honest.
(Wordpress Open Tickets over Time)
Don't rely on the Wordpress codebase to do assumptions about good practice or current standards in PHP coding. I'm saying this as someone who has fiddled with wordpress development over a longer period of time.
Wordpress codebase is about 10 years old, it's full of legacy code[1]. The program can not evolve on the code-level much because of that, so you find a lot of workarounds for problems that are already solved nowadays much better.
Just take this story: PHP had magic quotes. Wordpress developers thought it was useful. So for those hosts that did not have it configured, they added it. Ending up whith code that expects slashed input data often and at various places. The simple thing is, now they just can't change it to proper input processing and sanitization easily because of the usage of (super)globals introducing static global state nearly everywhere.
You can not easily refactor such code.
Same for the database class. It has a long history, originally based on an early version of ezSQL. At that time there was not mysql_real_escape_string and when it was introduced, the WP devs had the problem that not all installation bases support it.
So don't wonder about the coding practice you find inside the Wordpress code. You'll learn how things could have been done years ago and with more or less outdated PHP versions. It's not that long ago that Wordpress switched to PHP 5 for example.
Backwards compatibility.
Target a large amount of (technically more or less outdated) hosts.
Don't break what works with defects.
This might not be your list of priorities (hopefully), projects differ here a lot. But having a legacy code-base alone is a burden regardless how project priorities are set. Wordpress is only one example.
[1] see Milestones of WordPress: Early Project Timeline (ca. 2000 to 2005))
In complement to #tom answer.
Magic Quotes
Automatically parsing the whole entries and adding magic quotes is both creating bugs and useless.
Useless as you cannot rely on magic quotes to secure your input (multy-bytes encoding bugs for SQL injections is an example). So you need to apply a real filter before saving your data to a database
Creating bugs: If you need to really escape your data before a save in database you have to check that it's not already escaped (and the simple fact this settings exists and may be enforced by the hosting environment makes that you have to check this setting was set or not).
Creating bugs: All the data sent by the user is not always dedicated to a database storage. Escaping it may break the content, think about a json content for example, or even file content with the dangerous magic_quote_runtime
Creating bugs: All database storage are not escaping quotes the same way...
So Why?, why do we see such function in a CMS?
see that here it's an add_magic_quotes function, that can be used on a dedicated array, maybe not on _GET or _POST. But effectively the fact this function is just using addslashes and not a database dedicated function makes it quite bad.
The fact the hosting provider may enforce an automatic magic quotes is a nightmare for a CMS developper. Either you detect it and tell the user you refuse to run, or you have to manage the fact the content may or may have not be magically-addslahed... and to put everyone in the same state, you run the non-addslashed content in this function so that at least everyone is in the same (bad) state.
From what I can see on Wordpress, before the save a stripslahes_deep is performed in the wp_insert_post. And add_magic_quotes is usually performed on data pulled from Db before this data is send to the wp_insert_post. This may me think the problem is effectively to add slashes before removing them... maybe because sanitize filters which happen before the save expect content with slashes, or maybe because no one remember why the code is running in this way :-)
register_globals
Seems that this is the way to implement a Registry pattern in wordpress... They wanted to make the code simple to understand, and to allow a simple way to access importants objects like the query or the post. And an object oriented Registry class was not in the simple PHP way, where the $_GLOBALS array is already an existing registry.
Having a Registry is a perfectly valid thing in an application. a register_global thing is dangerous only if you allow some user input to override your valid secure input. And of course only if this secure input is taken from $_GLOBALS elsewhere (or with global keyword).
The dangerous part in the function here is the part of the function you have extracted, the loop on $query->query_vars. You will have to track the calls to see if user injected keys could run throught wp_parse_args and end in that function. But the next part of this function is fixing $_GLOBALS content for several objects:
$GLOBALS['query_string'] = $this->query_string;
$GLOBALS['posts'] = & $wp_query->posts;
$GLOBALS['post'] = (isset($wp_query->post)) ? $wp_query->post : null;
$GLOBALS['request'] = $wp_query->request;
So at least theses globals cannot be overwritten by user input and are safe.
So, theses functions are bad. But you can use them if you understand what they do and what you need to do to prevent the bad effects. And when you want to implement a simple framework for developpers, available on a very wide environments you sometimes have to use them.
But for sure it's a bad practice, you can certainly find bad wordpress plugins using $_GLOBALS in the wrong way or misusing the add_magic_quotes to data pulled from db wordpress concept. But there will be years before a Zend Framework CMS gained such a big number of contributions.
Magic Quotes
The following text is taken from PHP.net
http://www.php.net/manual/en/security.magicquotes.why.php
There is no reason to use magic quotes because they are no longer a supported part of PHP. However, they did exist and did help a few beginners blissfully and unknowingly write better (more secure) code. But, when dealing with code that relies upon this behavior it's better to update the code instead of turning magic quotes on. So why did this feature exist? Simple, to help prevent SQL Injection. Today developers are better aware of security and end up using database specific escaping mechanisms and/or prepared statements instead of relying upon features like magical quotes.
addslashes() vs mysql_real_escape_string()
The reason why you should use mysql_real_escape_string() is because it's a "MySQL function" and is created especially for escaping user input before it's executed in a mysql query, while addslashes() is a "PHP function". That probably sounded a little weird, but there's one important difference between the two and it has to do with the use of single- and multi-byte characters. You can still inject databases protected by the addslashes function, but injecting databases protected by mysql_real_escape_string is far more difficult. You can read more about it HERE
Register Globals
The reason why you should NOT use register_globals is because variables become accessible to everyone, which means that in the following example you would be able to set $access to true if it hasn't been initialized before
<?php
if (isAuthenticated()) { $access = true; }
if ($access == true) {
include(controlpanel.php);
}
?>
The above code would give you sh#! loads of problems, but if we initialize the variable first by adding the following to the top of the page
$access = false;
...we should be fine even if we have register_globals ON
So, if the Wordpress team have initialized all variables (which they probably have) then you don't have to worry about the use of globals.
Conclusion
It's definitely bad practice using any of those 3 functions/features and I would never do it myself. Are you sure you're working with the latest version of Wordpress? Like someone commented, if you are using the latest version it's because of laziness or worse it's still in there. I'ld never use Wordpress for anything other than blogs that doesn't require much security..
Wordpress. I've spent a lot of sleepless nights trying to answer the only one question: "Why??"
Since I've faced with its source code I hate it. It is awful. And let my post(and reputation as well) will be minused but it's true.
It doesn't have core. There is a rubbish of code instead of core. It reminds php3. Huge heap of unrelated and unlogical functions are used in it. "Copy and Paste" - the only one design pattern is used in wordpress.
Yes, the have emulated using of prepared statements. But why they don't use PDO, or mysqli? They have copypasted almost all PDO functions but haven't use it instead. Using of mysqli instead of mysql requires even less efforts.
They use myql_real_escape_string. But there is still something like protect_string_strongly, protect_string_weakly. There is no only only one function - do_not_protect_string_i_believe_my_users.
Global variables - is the philosophy of wordpress. "If we don't know how to change this var we'll mark it as global var and everybody will be happy." - here is what wordpress developers thought when they developed hellpress.
Every new version contains a lot of new in design, they add new default themes, they change background color in admin area from #ccc to #cdcdcd, they use dropdown menu in admin area instead of accordeon. And it awesome. But they do not improve its code.
Did you read comments in WP "core"? No? And I did. They are "awesome". Something like "What this function is called for? Let's it leave just in case." or "Do not hardcode this in new version." and so on.
The only one answer to the question "Why?" I got is: "Because it works. And if it does work do not touch it!!!"
wordpress.org is one most visited sites in the world. Why? Because nobody able to understand wordpress's logic. Everybody every time needs to ask something on the forum or read in the codex.
I hope you understand my point of view.
There is no better way to answer why they are bad than referring to the PHP documentation on magic_quotes:
Why did we use Magic Quotes?
Why to not use Magic Quotes
Also note:
This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.
So why does Wordpress still use Magic Quotes?
Wordpress minimum requirements uses PHP 4.3. Yes, it is absolutely a backwards compatibility reason.
What about the other functions?
I am honestly not sure. Relying on super globals is a very bad idea. This is simply laziness of the Wordpress development team. Perhaps they have more important issues to work on.
They did this for one reason:
To make sure Wordpress is compatible with most Web Hosting providers.
This is wrong place to ask such a question.
It is always a bad idea to ask some third party person of the reasons someone else had somewhere else.
It is obvious that you can't get an answer here unless you will lure some authorized wordpress developer here with such a bounty.
Yet your question is too broad. However, it is possible to answer it's abstract part:
I'd like to know from more experienced programmers if there are really security issues, or if sometimes their usage is just too clouded in rumors and false convinctions.
Does hands washing really prevents a disease?
What if I won't wash my hands - will I surely sick?
Most of time - no.
As a general habit - yes.
These features (although indeed, as any other feature of our unlucky language, too clouded in rumors) are merely a hygiene everyone have to follow as a basic instinct.
Although most of time...
addslashes won't do any harm as long as your encoding is either utf-8 or any single-byte one;
register globals won't do any harm if you initialize all your variables;
magic quotes won't do any harm as long as you have all your variables quoted for the SQL and slashes stripped for any other use;
...any exception from these circumstances can make you sick with high probability.
One of the main differences between mysql_real_escape_string() and addslashes is that mysql_real_escape_string() works in conjunction with the character set so it knows how to properly escape data based on the character set.
Generally I think the best approach is to use a request class and do all your stuff there.
That way there is only one place where you deal with GET,POST,COOKIE, SERVER etc which makes it far easier to manage in contrast to having a bunch of random functions doing different things. That's just a recipe for disaster.
I'm trying to write a page that calls PHP that's stored in a MySQL database. The page that is stored in the MySQL database contains PHP (and HTML) code which I want to run on page load.
How could I go about doing this?
You can use the eval command for this. I would recommend against this though, because there's a lot of pitfalls using this approach. Debugging is hard(er), it implies some security risks (bad content in the DB gets executed, uh oh).
See When is eval evil in php? for instance. Google for Eval is Evil, and you'll find a lot of examples why you should find another solution.
Addition: Another good article with some references to exploits is this blogpost. Refers to past vBulletin and phpMyAdmin exploits which were caused by improper Eval usage.
Easy:
$x // your variable with the data from the DB
<?php echo eval("?>".$x."<?") ?>
Let me know, works great for me in MANY applications, can't help but notice that everyone is quick to say how bad it is, but slow to actually help out with a straight answer...
eval() function was covered in other responses here. I agree you should limit use of eval unless it is absolutely needed. Instead of having PHP code in db you could have just a class name that has method called, say, execute(). Whenever you need to run your custom PHP code just instantiate the class of name you just fetched from db and run ->execute() on it. It is much cleaner solution and gives you great field of flexibility and improves site security significantly.
You can look at the eval function in PHP. It allows you to run arbitrary PHP code. It can be a huge security risk, though, and is best avoided.
Have you considered using your Source Control system to store different forks for the various installations (and the modules that differ among them)? That would be one of several best practices for application configuration I can think of. Yours is not an unusual requirement, so it's a problem that's been solved by others in the past; and storing code in a database is one I think you'd have a hard time finding reference to, or being advised as a best practice.
Good thing you posted the clarification. You've probably unintentionally posed an answer in search of a suitable question.
Read php code from database and save to file with unique name and then include file
this easy way for run php code and debug it.
$uniqid="tmp/".date("d-m-Y h-i-s").'_'.$Title."_".uniqid().".php";
$file = fopen($uniqid,"w");
fwrite($file,"<?php \r\n ".$R['Body']);
fclose($file);
// eval($R['Body']);
include $uniqid;
How I did this is to have a field in the database that identified something unique about the block of code needing to be executed. That one word is in the file name of that code. I put the strings together to point to the php file to be included. example:
$lookFor = $row['page'];
include("resources/" . $lookFor . "Codebase.php");
In this way even if a hacker could access you DB he couldn't put malicious code straight in there to be executed. He could perhaps change the reference word, but unless he could actually put a file directly onto the server it would do him no good. If he could put files directly onto the server, you're sunk then anyway if he really wants to be nasty. Just my two cents worth.
And yes, there are reasons you would want to execute stored code, but there are cons.