Hi everyone, ive never fully gotten a great grasp on making sure my sites are secure. For instance, on most pages I accept data either by $GET or $POST. On my very first successful website that I sold a few years back, after about 100,000 users someone had put in some javascript which redirected everyone to landed on my site to their hacking website.

It turned out that the script I purchased and modified did not have any data sanitization whatsoever.

More recently I was using htmlpurifier to sanitize anything being stored in the database, however after moving to a shared host it seems the htmlpurifier isn't working correctly and I've defaulted to just using mysql_real_escape_string to ensure the data is clean.

I don't know whether or not this is enough, but regardless I am having the following issue(s):

It looks like my new hosting company has magic_quotes turned on, and that seems to be messing up everything. When I tried to use mysql_real_escape_string on any data, it seems to show slashes even when I use addslashes to remove them from the screen output.

Then I tried using htmlentities($var, ENT_QUOTES) before putting the data into the database and this didn't really seem to help.

The only way that stripslashes will remove the slashes from the output, seems to be if I do nothing at all to the data before putting it in the database, since the magic quotes are turned on.

If I just insert a $POST['whatever'] without cleaning it in some way, is my website vulnerable even though the magic_quotes are turned on? I've spent hours going back and forth trying to figure out what the problem is. When a form is submitted, the input values are usually from what the user has entered ($POST) and will show the slashes everywhere, but if I go back and refresh the page without submitting the form, the slashes don't appear as it's now getting it straight from the database and not from the $POST array.

It seems absurd to rely on the magic_quotes and not do any sort of input sanitizing but I can't figure out what else to do in order to not show the quotes upon submitting a form. Can't really find the answer anywhere out there, so if anyone can help id appreciate it greatly!

Thanks

    Could the issue have anything to do with using VARCHAR over TEXT data types in my tables?
    The reason I ask is I've been wondering why in some cases, my textarea's don't seem to have the same problem as my <input type="text" input fields....and looking at my database for the <input type="text" fields im using VARCHAR as the data type but for textarea's im using TEXT as the data type.

    I want people to be able to use words with apostrophes such as the words "IT'S" without there being a slash and without my website being vulnerable to something.

      Hmmm changed the data types to all TEXT and still the <textarea> isn't having a problem but the <input type="text"> are still doing the same thing. I'm very puzzled. All I know is that magic_quotes are turned on server wide, im using mysql_real_escape_string on ALL posts that are coming in, and using stripslashes on the output but for some reason only textarea's are keeping the apostrophes. What gives?

        cadkins23 wrote:

        It looks like my new hosting company has magic_quotes turned on, and that seems to be messing up everything. When I tried to use mysql_real_escape_string on any data, it seems to show slashes even when I use addslashes to remove them from the screen output.

        Then I tried using htmlentities($var, ENT_QUOTES) before putting the data into the database and this didn't really seem to help.

        The only way that stripslashes will remove the slashes from the output, seems to be if I do nothing at all to the data before putting it in the database, since the magic quotes are turned on.

        The correct approach is: if get_magic_quotes_gpc() returns 1, use stripslashes() on the incoming data. Then, if the data is a string, use mysql_real_escape_string() on it when inserting into the database; but if the input is a numeric type, cast it to the appropriate type (and/or simply reject invalid input). After retrieving the data from the database, use htmlentities on it when printing it as the text of a webpage. Note that the order in which you do these steps matters.

        That said, instead of using mysql_real_escape_string() and type casting, I suggest switching to the PDO extension or MySQLi extension and using prepared statements instead.

        cadkins23 wrote:

        for some reason only textarea's are keeping the apostrophes. What gives?

        Chances are, your text is being truncated (and resulting in malformed HTML), e.g., value='cadkin's birthday' would be as if you wrote value='cadkin'.

          cadkins23;11010281 wrote:

          Hi everyone, ive never fully gotten a great grasp on making sure my sites are secure.

          Well that's pretty multifaceted topic. For example, there's database security and then there's XSS - two completely separate topics. And that's not even the extent of what makes up "security" as a whole.

          cadkins23;11010281 wrote:

          For instance, on most pages I accept data either by $GET or $POST

          Not sure why you say this, since it's really irrelevant. It doesn't matter if the data is from $POST, $GET, $COOKIE, or even some items in $SERVER - external data is external data, no matter which specific method it's coming in.

          cadkins23;11010281 wrote:

          More recently I was using htmlpurifier to sanitize anything being stored in the database, however after moving to a shared host it seems the htmlpurifier isn't working correctly

          I have no idea what "htmlpurifier" is or what it does, but if you're looking for a one-size-fits-all type of solution, I'm not sure you're going to have much luck. It'd be more like a "jack-of-all-trades, master-of-none" sort of tradeoff instead. Better would be to learn about the different types of attacks/threats and handle them as appropriate.

          cadkins23;11010281 wrote:

          I've defaulted to just using mysql_real_escape_string to ensure the data is clean.

          And here's the first confusion between the different types/layers of security. Escaping data for input has absolutely nothing to do with protecting against things like malicious Javascript, HTML, etc. Escaping/sanitizing data before inserting it into a SQL query string is instead meant to protect the integrity of your database.

          cadkins23;11010281 wrote:

          It looks like my new hosting company has magic_quotes turned on

          Sounds like your first problem is that your new hosting company is either incompetent or simply doesn't care about its customers. Whichever is true (maybe even both?!) would be irrelevant to me, since neither attitudes would earn my business!

          cadkins23;11010281 wrote:

          and that seems to be messing up everything.

          Quite right; this is one of the many reasons that the entire magic_quotes feature has been deprecated and disabled by default for quite some time now. (See the manual page [man]security.magic_quotes[/man] for more info.)

          cadkins23;11010281 wrote:

          When I tried to use mysql_real_escape_string on any data, it seems to show slashes even when I use addslashes to remove them from the screen output.

          Well for one, to undo the damage caused by magic_quotes, you'd want to use stripslashes(), not addslashes().

          But the real solution (stripslashes() isn't a solution to me - it's a workaround) would be to disable the magic_quotes directives either using a php.ini file or a .htaccess file (if applicable) in the root of your site.

          cadkins23;11010281 wrote:

          Then I tried using htmlentities($var, ENT_QUOTES) before putting the data into the database and this didn't really seem to help.

          Again, seem to help in what way? Sanitizing data and preventing HTML entities from getting parsed as HTML are solutions to two very different problems, so talking about the two together is comparing apples and oranges.

          Either way, note that it's more "proper" (e.g. more widely accepted as better practice) to store the data as-is. Instead, you'd want to convert HTML entities (if so desired) after you retrieve the data.

          cadkins23;11010281 wrote:

          If I just insert a $_POST['whatever'] without cleaning it in some way, is my website vulnerable even though the magic_quotes are turned on?

          Technically yes, because magic_quotes_gpc doesn't do the same job as using a DBMS-specific escaping mechanism. Again, this is one of the many reasons why you should never allow this directive to be enabled.

          cadkins23;11010281 wrote:

          I've spent hours going back and forth trying to figure out what the problem is. When a form is submitted, the input values are usually from what the user has entered ($POST) and will show the slashes everywhere

          This is yet another reason why magic_quotes is deprecated and disabled; it destroys the integrity of the original data. When escaping data for use in a SQL query, you should do so at the time when you're insert that data into the SQL query (such as by not doing any escaping at all and by instead using prepared statements with bound parameters). That way, you still have the original data the user actually submitted left untouched in the $POST/$GET/etc. arrays (which is, after all, what they were intended to represent... it's not called $POST_after_I_silently_modified_the_data_for_you).

          cadkins23;11010283 wrote:

          Could the issue have anything to do with using VARCHAR over TEXT data types in my tables?

          No. The problem is at a higher level than that; "garbage in, garbage out" applies to both column types.

          Also note that the entire [man]mysql[/man] extension has been deprecated and superseded by newer extensions such as [man]MySQLi[/man] (or even [man]PDO[/man]). Also note that utilizing one of these newer extensions, you could (as mentioned above) forget about escaping data altogether and instead rely on prepared statements with bound parameters (in which the DB driver will handle the necessary escaping for you automatically).

          Otherwise, note that [man]mysqli_real_escape_string/man (and it's deprecated cousin with the 'mysql' prefix) is only to be used on string data (hence the "string" in the very name of the function itself); using it on other types of data (e.g. numeric) isn't appropriate.

            Write a Reply...