0

I want to know how to prevent HTML injection. I have created a site where users are allowed to paste articles in a HTML form. I have used mysql_real_escape_sting but I want to know whether this is enough for preventing HTML injections. I tried htmlspecialchars but it’s showing error with mysql_real_escape_string.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
test
  • 105
  • 2
  • 6
  • 3
    when you say html injection do you mean sql injection, or XSS – Lawrence Cherone Jul 30 '11 at 13:17
  • Can you post the code where `htmlspecialchars` is throwing an error with `mysql_real_escape_string`? That doesn't really make a lot of sense, unless you're combining them strangely. – Ian McLaird Jul 30 '11 at 13:22
  • hi i am sorry i am new to phpmysql.in one tutorial in web they told to put mysql real escape to prevent injection and other using httpspecialchars.am a little bit confused so i tried both in my script – test Jul 31 '11 at 03:01

5 Answers5

3

You should use prepared statements to be absolutely sure to prevent sql injection.

Taken from documentation (read the part in bold)

Many of the more mature databases support the concept of prepared statements. What are they? They can be thought of as a kind of compiled template for the SQL that an application wants to run, that can be customized using variable parameters. Prepared statements offer two major benefits:

  • The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters. When the query is prepared, the database will analyze, compile and optimize it's plan for executing the query. For complex queries this process can take up enough time that it will noticeably slow down an application if there is a need to repeat the same query many times with different parameters. By using a prepared statement the application avoids repeating the analyze/compile/optimize cycle. This means that prepared statements use fewer resources and thus run faster.
  • The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).

Prepared statements are so useful that they are the only feature that PDO will emulate for drivers that don't support them. This ensures that an application will be able to use the same data access paradigm regardless of the capabilities of the database.

If you meant to prevent XSS (Cross site scripting) you should use the function htmlspecialchars() whenever you want to output something to the browser that came from user input or from any non secure source. Always treat any unknown source as unsecure

 echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
Gumbo
  • 643,351
  • 109
  • 780
  • 844
Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
  • I daresay the bolded sentence is not entirely true. It is possible to write an application using solely prepared statements, that still will be vulnerable to SQL injection. – Mchl Jul 30 '11 at 17:42
  • Hi, @Mchl. I read your comment and I wanted to ask youabout how would this be possible? I'm using PDO with prepared statements and exception handling. Thanks in advance. –  Aug 28 '17 at 16:18
  • You can still create prepared statements in an unsecure way. For example one might decie to use unescaped value from `$_POST` as a column name. The parentheses right after the bolded sentence highlight this fact. – Mchl Aug 28 '17 at 16:22
3

No, mysql_real_escape_sting does only prepare data to be safely inserted into MySQL string declarations to prevent SQL injections in that specific context. It does not prevent other injections like HTML injection or Cross-Site Scripting (XSS).

Both HTML injection and XSS happen in different contexts where there are different contextual special characters that need to be taken care of. In HTML it’s especially <, >, &, ", and ' that delimit the different HTML contexts. With XSS in mind you also need to be aware of the different JavaScript contexts and their special characters.

htmlspecialchars should suffice the handle the former attack while json_encode can be used for a safe subset of JavaScript. See also the XSS (Cross Site Scripting) Prevention Cheat Sheet as well as my answer to Are these two functions overkill for sanitization? and related questions for further information on this topic.

Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844
1

No. In fact, I believe that for advanced coders, you shouldn't be using mysql_real_escape_string() as a crutch.
For each value you need to use in a DB query, seriously consider the possible characters that could appear. If it is a dollar amount, the only characters you should accept are numbers, a period, and possible preceding dollar sign. If it is a name, you should only allow letters, a hyphen, and possibly a period (for fulls names like Joseph A. Bank).
Once you determine a strict character range that's acceptable for a value, write a Regex to match that value against. For any values that don't match, display a bogus error and log the value in a textfile (read: not a db) along with the user's IP. Frequently check this file so you can see if values users have tried that didn't work were hacking attempts. Not only will this uncover valid inputs for which you need to adjust your Regex, but it will also reveal the IP's of hackers who try to find SQL vulnerabilities on your site. This approach ensures that new and old SQL vulnerabilities that might not immediately be addressed by mysql_real_escape_string(), will be blocked.

Bailey Parker
  • 15,599
  • 5
  • 53
  • 91
0

No, it's not. Refer to the docs

It doesn't escape < or >.

erenon
  • 18,838
  • 2
  • 61
  • 93
0

Simple answer: No

mysql_real_escape_string only helps you get rid of SQL Injections and not XSS and html injection. To avoid these you need more sophisticated input validation. Start by looking at strip_tags and htmlentities.

JK.
  • 5,126
  • 1
  • 27
  • 26