How to protect against cross-site scripting?

I use php, mysql with smarty and I, where users can post comments, etc. I already escaped the characters before inserting into the database for SQL Injection. What else do I need to do?

+4
source share
5 answers

XSS is mainly associated with HTML escaping (*). Every time you take a line of plain text and put it in an HTML page, regardless of whether the text is from a database, directly from user input, from a file, or from another place entirely, you need to avoid it.

The minimum HTML escape is to convert all & characters to &amp; and all the characters < in &lt; . When you put something in the attribute value, you will also need to escape the quotation mark, which is used to delimit the attribute, usually " before &quot; There is no harm in always avoiding both quotation marks ( &quot; and the single quote apostrophe &#39; ), and some people also go from > to &gt; although this is only necessary for one case in XHTML. p>

Any good web-based language should provide a feature that does this for you. For example, in PHP, this is htmlspecialchars() :

 <p> Hello, <?php htmlspecialchars($name); ?>! </p> 

and in Smarty, the escape modifier:

 <p> Hello, {$name|escape:'html'}! </p> 

in fact, since HTML escaping is what you want 95% of the time (relatively rare to allow HTML markup to be enabled), this should have been the default. Newer template languages ​​have learned that refusing HTML crawl is a huge bug that causes endless XSS holes, so HTML will come out by default.

You can make Smarty behave like this by changing the default modifiers to html . (Do not use htmlall as they offer this if you really don't know what you are doing, or are likely to mess up all your non-ASCII characters.)

No matter what you do, do not fall into the common PHP error for HTML escaping or "disinfection" for HTML input, before it is processed or put into the database. This is the wrong place to encode the output stage and will give you all kinds of problems. If you want to check your input to make sure that it is the expected specific application, then it’s fine, but clipping or escaping “special” characters at this stage is inappropriate.

*: Other aspects of XSS are present when (a) you really want to allow users to send HTML files, in which case you must destroy them to acceptable elements and attributes, which is a complex process usually performed by a library such as HTML Purifier, and even then there were holes. Alternative, simpler layout schemes may help. And (b) when you allow users to upload files, which is very difficult to make secure.

+10
source

As for SQL Injection, escaping is not enough - you should use data access libraries, where possible, and parameterized queries.

For XSS (cross-site scripting), start by outputting html-encoded data. Again, anti-XSS libraries are your friend.

One of the current approaches is to allow a very limited number of tags and to misinform them in the process (whitelist + cleanup).

+1
source

You want people to not be able to post JavaScript code or scary HTML code in their comments. I suggest you ban anything but very simple markup.

If the comments should not contain markup, do

 echo htmlspecialchars($commentText); 

should be enough, but it's very rude. It would be better to misinform all the input before even putting it into your database. The PHP strip_tags () function can help you get started.

If you want to allow HTML comments, but you can be safe, you can give an HTML cleaner .

+1
source

You must not modify the data entered by the user before placing them in the database. Modification should take place when you put it on a website. You do not want to lose the original data.

As you spit it out on a website, you want to avoid special characters in HTML codes using something like htmlspecialchars("my output & stuff", ENT_QUOTES, 'UTF-8') - don't forget to specify the encoding you are using. This line will be translated to my output &amp; stuff my output &amp; stuff to view by browser.

+1
source

The best way to prevent SQL injection is to simply not use dynamic SQL, which accepts user input. Instead, pass the input as parameters; thus, it will be strongly typed and will not be able to enter code.

0
source

Source: https://habr.com/ru/post/1309141/


All Articles