<p>I have PHP configured so that magic quotes are on and register globals are off.</p>

<p>I do my best to always call htmlentities() for anything I am outputing that is derived from user input.</p>

<p>I also occasionally seach my database for common things used in xss attached such as...</p>

<pre><code>&lt;script
</code></pre>

<p>What else should I be doing and how can I make sure that the things I am trying to do are <strong>always</strong> done.</p>

[{'answer_id': 71358, 'author': 'Konrad Rudolph', 'author_id': 1968, 'author_profile': 'https://Stackoverflow.com/users/1968', 'pm_score': 2, 'selected': False, 'text': "<p>Escaping all user input is enough for most sites. Also make sure that session IDs don't end up in the URL so they can't be stolen from the <code>Referer</code> link to another site. Additionally, if you allow your users to submit links, make sure no <code>javascript:</code> protocol links are allowed; these would execute a script as soon as the user clicks on the link.</p>\n"}, {'answer_id': 71431, 'author': 'Christian Studer', 'author_id': 6260, 'author_profile': 'https://Stackoverflow.com/users/6260', 'pm_score': 4, 'selected': False, 'text': '<p>There are a lot of ways to do XSS (See <a href="http://ha.ckers.org/xss.html" rel="noreferrer">http://ha.ckers.org/xss.html</a>) and it\'s very hard to catch.</p>\n\n<p>I personally delegate this to the current framework I\'m using (Code Igniter for example). While not perfect, it might catch more than my hand made routines ever do.</p>\n'}, {'answer_id': 71439, 'author': 'Niyaz', 'author_id': 184, 'author_profile': 'https://Stackoverflow.com/users/184', 'pm_score': 2, 'selected': False, 'text': '<p>If you are concerned about XSS attacks, encoding your output strings to HTML is the solution. If you remember to encode every single output character to HTML format, there is no way to execute a successful XSS attack.</p>\n\n<p>Read more:\n<a href="http://www.diovo.com/2008/09/sanitizing-user-data-how-and-where-to-do-it/" rel="nofollow noreferrer">Sanitizing user data: How and where to do it</a></p>\n'}, {'answer_id': 71444, 'author': 'Michał Niedźwiedzki', 'author_id': 2169, 'author_profile': 'https://Stackoverflow.com/users/2169', 'pm_score': 7, 'selected': True, 'text': "<p>Escaping input is not the best you can do for successful XSS prevention. Also output must be escaped. If you use Smarty template engine, you may use <code>|escape:'htmlall'</code> modifier to convert all sensitive characters to HTML entities (I use own <code>|e</code> modifier which is alias to the above).</p>\n\n<p>My approach to input/output security is:</p>\n\n<ul>\n<li>store user input not modified (no HTML escaping on input, only DB-aware escaping done via PDO prepared statements)</li>\n<li>escape on output, depending on what output format you use (e.g. HTML and JSON need different escaping rules)</li>\n</ul>\n"}, {'answer_id': 71541, 'author': 'Alexey Feldgendler', 'author_id': 10682, 'author_profile': 'https://Stackoverflow.com/users/10682', 'pm_score': 2, 'selected': False, 'text': "<p>“Magic quotes” is a palliative remedy for some of the worst XSS flaws which works by escaping everything on input, something that's wrong by design. The only case where one would want to use it is when you absolutely must use an existing PHP application known to be written carelessly with regard to XSS. (In this case you're in a serious trouble even with “magic quotes”.) When developing your own application, you should disable “magic quotes” and follow XSS-safe practices instead.</p>\n\n<p>XSS, a cross-site scripting vulnerability, occurs when an application includes strings from external sources (user input, fetched from other websites, etc) in its [X]HTML, CSS, ECMAscript or other browser-parsed output without proper escaping, hoping that special characters like less-than (in [X]HTML), single or double quotes (ECMAscript) will never appear. The proper solution to it is to always escape strings according to the rules of the output language: using entities in [X]HTML, backslashes in ECMAscript etc.</p>\n\n<p>Because it can be hard to keep track of what is untrusted and has to be escaped, it's a good idea to always escape everything that is a “text string” as opposed to “text with markup” in a language like HTML. Some programming environments make it easier by introducing several incompatible string types: “string” (normal text), “HTML string” (HTML markup) and so on. That way, a direct implicit conversion from “string” to “HTML string” would be impossible, and the only way a string could become HTML markup is by passing it through an escaping function.</p>\n\n<p>“Register globals”, though disabling it is definitely a good idea, deals with a problem entirely different from XSS.</p>\n"}, {'answer_id': 71568, 'author': 'dbr', 'author_id': 745, 'author_profile': 'https://Stackoverflow.com/users/745', 'pm_score': 0, 'selected': False, 'text': '<p>Use an existing user-input sanitization library to clean <em>all</em> user-input. Unless you put a <em>lot</em> of effort into it, implementing it yourself will never work as well.</p>\n'}, {'answer_id': 71612, 'author': 'Matt Farina', 'author_id': 11910, 'author_profile': 'https://Stackoverflow.com/users/11910', 'pm_score': 3, 'selected': False, 'text': '<p>This is a great question.</p>\n\n<p>First, don\'t escape text on input except to make it safe for storage (such as being put into a database). The reason for this is you want to keep what was input so you can contextually present it in different ways and places. Making changes here can compromise your later presentation.</p>\n\n<p>When you go to present your data filter out what shouldn\'t be there. For example, if there isn\'t a reason for javascript to be there search for it and remove it. An easy way to do that is to use the <a href="http://us.php.net/strip_tags" rel="noreferrer">strip_tags</a> function and only present the html tags you are allowing.</p>\n\n<p>Next, take what you have and pass it thought htmlentities or htmlspecialchars to change what\'s there to ascii characters. Do this based on context and what you want to get out.</p>\n\n<p>I\'d, also, suggest turning off Magic Quotes. It is has been removed from PHP 6 and is considered bad practice to use it. Details at <a href="http://us3.php.net/magic_quotes" rel="noreferrer">http://us3.php.net/magic_quotes</a></p>\n\n<p>For more details check out <a href="http://ha.ckers.org/xss.html" rel="noreferrer">http://ha.ckers.org/xss.html</a></p>\n\n<p>This isn\'t a complete answer but, hopefully enough to help you get started.</p>\n'}, {'answer_id': 71635, 'author': 'basszero', 'author_id': 287, 'author_profile': 'https://Stackoverflow.com/users/287', 'pm_score': 1, 'selected': False, 'text': "<p>Make you any session cookies (or all cookies) you use HttpOnly. Most browsers will hide the cookie value from JavaScript in that case. User could still manually copy cookies, but this helps prevent direct script access. StackOverflow had this problem durning beta. </p>\n\n<p>This isn't a solution, just another brick in the wall </p>\n"}, {'answer_id': 75839, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': '<p>Personally, I would disable magic_quotes. In PHP5+ it is disabled by default and it is better to code as if it is not there at all as it does not escape everything and it will be removed from PHP6.</p>\n\n<p>Next, depending on what type of user data you are filtering will dictate what to do next e.g. if it is just text e.g. a name, then <code>strip_tags(trim(stripslashes()));</code> it or to check for ranges use regular expressions.</p>\n\n<p>If you expect a certain range of values, create an array of the valid values and only allow those values through (<code>in_array($userData, array(...))</code>).</p>\n\n<p>If you are checking numbers use is_numeric to enforce whole numbers or cast to a specific type, that should prevent people trying to send strings in stead.</p>\n\n<p>If you have PHP5.2+ then consider looking at <a href="http://ca.php.net/filter" rel="nofollow noreferrer">filter()</a> and making use of that extension which can filter various data types including email addresses. Documentation is not particularly good, but is improving.</p>\n\n<p>If you have to handle HTML then you should consider something like <a href="http://cyberai.users.phpclasses.org/browse/package/2189.html" rel="nofollow noreferrer">PHP Input Filter</a> or <a href="http://htmlpurifier.org/" rel="nofollow noreferrer">HTML Purifier</a>. HTML Purifier will also validate HTML for conformance. I am not sure if Input Filter is still being developed. Both will allow you to define a set of tags that can be used and what attributes are allowed.</p>\n\n<p>Whatever you decide upon, always remember, never ever trust anything coming into your PHP script from a user (including yourself!).</p>\n'}, {'answer_id': 75879, 'author': 'Mason', 'author_id': 8973, 'author_profile': 'https://Stackoverflow.com/users/8973', 'pm_score': 3, 'selected': False, 'text': '<blockquote>\n<p>rikh Writes:</p>\n<blockquote>\n<p>I do my best to always call htmlentities() for anything I am outputing that is derived from user input.</p>\n</blockquote>\n</blockquote>\n<p>See Joel\'s essay on <a href="http://www.joelonsoftware.com/articles/Wrong.html" rel="nofollow noreferrer">Making Code Look Wrong</a> for help with this</p>\n'}, {'answer_id': 77290, 'author': 'Daniel Papasian', 'author_id': 7548, 'author_profile': 'https://Stackoverflow.com/users/7548', 'pm_score': 2, 'selected': False, 'text': "<p>All of these answers are great, but fundamentally, the solution to XSS will be to stop generating HTML documents by string manipulation.</p>\n\n<p>Filtering input is always a good idea for any application.</p>\n\n<p>Escaping your output using htmlentities() and friends should work as long as it's used properly, but this is the HTML equivalent of creating a SQL query by concatenating strings with mysql_real_escape_string($var) - it should work, but fewer things can validate your work, so to speak, compared to an approach like using parameterized queries.</p>\n\n<p>The long-term solution should be for applications to construct the page internally, perhaps using a standard interface like the DOM, and then to use a library (like libxml) to handle the serialization to XHTML/HTML/etc.  Of course, we're a long ways away from that being popular and fast enough, but in the meantime we have to build our HTML documents via string operations, and that's inherently more risky.</p>\n"}, {'answer_id': 77320, 'author': 'Rob', 'author_id': 3542, 'author_profile': 'https://Stackoverflow.com/users/3542', 'pm_score': 1, 'selected': False, 'text': "<ul>\n<li>Don't trust user input</li>\n<li>Escape all free-text output</li>\n<li>Don't use magic_quotes; see if there's a DBMS-specfic variant, or use PDO</li>\n<li>Consider using HTTP-only cookies where possible to avoid any malicious script being able to hijack a session</li>\n</ul>\n"}, {'answer_id': 77349, 'author': 'Jilles', 'author_id': 13864, 'author_profile': 'https://Stackoverflow.com/users/13864', 'pm_score': 4, 'selected': False, 'text': '<p>I\'m of the opinion that one shouldn\'t escape anything during input, only on output. Since (most of the time) you can not assume that you know where that data is going. Example, if you have form that takes data that later on appears in an email that you send out, you need different escaping (otherwise a malicious user could rewrite your email-headers). </p>\n\n<p>In other words, you can only escape at the very last moment the data is "leaving" your application:</p>\n\n<ul>\n<li>List item</li>\n<li>Write to XML file, escape for XML</li>\n<li>Write to DB, escape (for that particular DBMS)</li>\n<li>Write email, escape for emails</li>\n<li>etc</li>\n</ul>\n\n<p>To go short:</p>\n\n<ol>\n<li>You don\'t know where your data is going</li>\n<li>Data might actually end up in more than one place, needing different escaping mechanism\'s BUT NOT BOTH</li>\n<li>Data escaped for the wrong target is really not nice. (E.g. get an email with the subject "Go to Tommy\\\'s bar".)</li>\n</ol>\n\n<p>Esp #3 will occur if you escape data at the input layer (or you need to de-escape it again, etc).</p>\n\n<p>PS: I\'ll second the advice for not using magic_quotes, those are pure evil!</p>\n'}, {'answer_id': 77376, 'author': 'barce', 'author_id': 13518, 'author_profile': 'https://Stackoverflow.com/users/13518', 'pm_score': 2, 'selected': False, 'text': '<p>I find that using this function helps to strip out a lot of possible xss attacks:</p>\n<pre class="lang-php prettyprint-override"><code>&lt;?php\n\nfunction h($string, $esc_type = \'htmlall\')\n{\n    switch ($esc_type) {\n        case \'css\':\n            $string = str_replace(array(\'&lt;\', \'&gt;\', \'\\\\\'), array(\'&amp;lt;\', \'&amp;gt;\', \'&amp;#47;\'), $string);\n            // get rid of various versions of javascript\n            $string = preg_replace(\n                    \'/j\\s*[\\\\\\]*\\s*a\\s*[\\\\\\]*\\s*v\\s*[\\\\\\]*\\s*a\\s*[\\\\\\]*\\s*s\\s*[\\\\\\]*\\s*c\\s*[\\\\\\]*\\s*r\\s*[\\\\\\]*\\s*i\\s*[\\\\\\]*\\s*p\\s*[\\\\\\]*\\s*t\\s*[\\\\\\]*\\s*:/i\',\n                    \'blocked\', $string);\n            $string = preg_replace(\n                    \'/@\\s*[\\\\\\]*\\s*i\\s*[\\\\\\]*\\s*m\\s*[\\\\\\]*\\s*p\\s*[\\\\\\]*\\s*o\\s*[\\\\\\]*\\s*r\\s*[\\\\\\]*\\s*t/i\',\n                    \'blocked\', $string);\n            $string = preg_replace(\n                    \'/e\\s*[\\\\\\]*\\s*x\\s*[\\\\\\]*\\s*p\\s*[\\\\\\]*\\s*r\\s*[\\\\\\]*\\s*e\\s*[\\\\\\]*\\s*s\\s*[\\\\\\]*\\s*s\\s*[\\\\\\]*\\s*i\\s*[\\\\\\]*\\s*o\\s*[\\\\\\]*\\s*n\\s*[\\\\\\]*\\s*/i\',\n                    \'blocked\', $string);\n            $string = preg_replace(\'/b\\s*[\\\\\\]*\\s*i\\s*[\\\\\\]*\\s*n\\s*[\\\\\\]*\\s*d\\s*[\\\\\\]*\\s*i\\s*[\\\\\\]*\\s*n\\s*[\\\\\\]*\\s*g:/i\', \'blocked\', $string);\n                return $string;\n\n        case \'html\':\n            //return htmlspecialchars($string, ENT_NOQUOTES);\n            return str_replace(array(\'&lt;\', \'&gt;\'), array(\'&amp;lt;\' , \'&amp;gt;\'), $string);\n\n        case \'htmlall\':\n            return htmlentities($string, ENT_QUOTES);\n        case \'url\':\n            return rawurlencode($string);\n        case \'query\':\n            return urlencode($string);\n\n        case \'quotes\':\n            // escape unescaped single quotes\n            return preg_replace(&quot;%(?&lt;!\\\\\\\\)\'%&quot;, &quot;\\\\\'&quot;, $string);\n\n        case \'hex\':\n            // escape every character into hex\n            $s_return = \'\';\n            for ($x=0; $x &lt; strlen($string); $x++) {\n                $s_return .= \'%\' . bin2hex($string[$x]);\n            }\n            return $s_return;\n\n        case \'hexentity\':\n            $s_return = \'\';\n            for ($x=0; $x &lt; strlen($string); $x++) {\n                $s_return .= \'&amp;#x\' . bin2hex($string[$x]) . \';\';\n            }\n            return $s_return;\n\n        case \'decentity\':\n            $s_return = \'\';\n            for ($x=0; $x &lt; strlen($string); $x++) {\n                $s_return .= \'&amp;#\' . ord($string[$x]) . \';\';\n            }\n            return $s_return;\n\n        case \'javascript\':\n            // escape quotes and backslashes, newlines, etc.\n            return strtr($string, array(\'\\\\\'=&gt;\'\\\\\\\\\',&quot;\'&quot;=&gt;&quot;\\\\\'&quot;,\'&quot;\'=&gt;\'\\\\&quot;\',&quot;\\r&quot;=&gt;\'\\\\r\',&quot;\\n&quot;=&gt;\'\\\\n\',\'&lt;/\'=&gt;\'&lt;\\/\'));\n\n        case \'mail\':\n            // safe way to display e-mail address on a web page\n            return str_replace(array(\'@\', \'.\'),array(\' [AT] \', \' [DOT] \'), $string);\n\n        case \'nonstd\':\n            // escape non-standard chars, such as ms document quotes\n            $_res = \'\';\n            for($_i = 0, $_len = strlen($string); $_i &lt; $_len; $_i++) {\n                $_ord = ord($string{$_i});\n                // non-standard char, escape it\n                if($_ord &gt;= 126){ \n                    $_res .= \'&amp;#\' . $_ord . \';\'; \n                } else {\n                    $_res .= $string{$_i};\n                }\n            }\n               return $_res;\n\n        default:\n            return $string;\n    }\n}\n    \n?&gt;\n</code></pre>\n<p><a href="http://www.codebelay.com/killxss.phps" rel="nofollow noreferrer">Source</a></p>\n'}, {'answer_id': 77396, 'author': 'Darren22', 'author_id': 13978, 'author_profile': 'https://Stackoverflow.com/users/13978', 'pm_score': 0, 'selected': False, 'text': '<p>I find the best way is using a class that allows you to bind your code so you never have to worry about manually escaping your data.</p>\n'}, {'answer_id': 77689, 'author': 'Adam', 'author_id': 13320, 'author_profile': 'https://Stackoverflow.com/users/13320', 'pm_score': -1, 'selected': False, 'text': "<p>It is difficult to implement a thorough sql injection/xss injection prevention on a site that doesn't cause false alarms. In a CMS the end user might want to use <code>&lt;script&gt;</code> or <code>&lt;object&gt;</code> that links to items from another site. </p>\n\n<p>I recommend having all users install FireFox with NoScript ;-)</p>\n"}, {'answer_id': 209743, 'author': 'Kornel', 'author_id': 27009, 'author_profile': 'https://Stackoverflow.com/users/27009', 'pm_score': 2, 'selected': False, 'text': '<p>I rely on <a href="http://phptal.motion-twin.com/" rel="nofollow noreferrer">PHPTAL</a> for that.</p>\n\n<p>Unlike Smarty and plain PHP, it escapes all output by default. This is a big win for security, because your site won\'t become vurnelable if you forget <code>htmlspecialchars()</code> or <code>|escape</code> somewhere.</p>\n\n<p>XSS is HTML-specific attack, so HTML output is the right place to prevent it. You should not try pre-filtering data in the database, because you could need to output data to another medium which doesn\'t accept HTML, but has its own risks.</p>\n'}, {'answer_id': 2660815, 'author': 'user319490', 'author_id': 319490, 'author_profile': 'https://Stackoverflow.com/users/319490', 'pm_score': 3, 'selected': False, 'text': "<p><strong>Template library.</strong> Or at least, that is what template libraries should do.\nTo prevent XSS <em>all</em> output should be encoded. This is not the task of the main application / control logic, it should solely be handled by the output methods.</p>\n\n<p>If you sprinkle htmlentities() thorughout your code, the overall design is wrong. And as you suggest, you might miss one or two spots.\nThat's why the only solution is rigorous html encoding <em>-> when</em> output vars get written into a html/xml stream.</p>\n\n<p>Unfortunately, most php template libraries only add their own template syntax, but don't concern themselves with output encoding, or localization, or html validation, or anything important. Maybe someone else knows a proper template library for php?</p>\n"}, {'answer_id': 2671681, 'author': 'Abeon', 'author_id': 320856, 'author_profile': 'https://Stackoverflow.com/users/320856', 'pm_score': 1, 'selected': False, 'text': '<p>You should at least validate all data going into the database. And try to validate all data leaving the database too.</p>\n\n<p>mysql_real_escape_string is good to prevent SQL injection, but XSS is trickier.\nYou should preg_match, stip_tags, or htmlentities where possible!</p>\n'}, {'answer_id': 5772431, 'author': 'Night Owl', 'author_id': 615686, 'author_profile': 'https://Stackoverflow.com/users/615686', 'pm_score': 1, 'selected': False, 'text': "<p>The best current method for preventing XSS in a PHP application is HTML Purifier (http://htmlpurifier.org/).  One minor drawback to it is that it's a rather large library and is best used with an op code cache like APC.  You would use this in any place where untrusted content is being outputted to the screen. It is much more thorough that htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, etc.</p>\n"}]
['https://Stackoverflow.com/questions/71328', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4012/']