Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the best practices for avoiding xss attacks in a PHP site [closed]

Tags:

security

php

xss

I have PHP configured so that magic quotes are on and register globals are off.

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

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

<script

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

like image 965
Rik Heywood Avatar asked Sep 16 '08 11:09

Rik Heywood


People also ask

What is the protection against XSS in PHP?

One of the most important steps is to sanitize any user input before it is processed and/or rendered back to the browser. PHP has some "filter" functions that can be used. The form that XSS attacks usually have is to insert a link to some off-site javascript that contains malicious intent for the user.

Which is the best method to protect your website from XSS cross-site scripting?

SDL stands for 'Security Development Lifecycle. ' You'll specifically want to have used an SDL when developing your web application, with the main purpose of them being to limit the amount of coding errors and security flaws in your application, thereby making your website less vulnerable to an XSS attack.


9 Answers

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 |escape:'htmlall' modifier to convert all sensitive characters to HTML entities (I use own |e modifier which is alias to the above).

My approach to input/output security is:

  • store user input not modified (no HTML escaping on input, only DB-aware escaping done via PDO prepared statements)
  • escape on output, depending on what output format you use (e.g. HTML and JSON need different escaping rules)
like image 180
Michał Niedźwiedzki Avatar answered Sep 20 '22 14:09

Michał Niedźwiedzki


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).

In other words, you can only escape at the very last moment the data is "leaving" your application:

  • List item
  • Write to XML file, escape for XML
  • Write to DB, escape (for that particular DBMS)
  • Write email, escape for emails
  • etc

To go short:

  1. You don't know where your data is going
  2. Data might actually end up in more than one place, needing different escaping mechanism's BUT NOT BOTH
  3. Data escaped for the wrong target is really not nice. (E.g. get an email with the subject "Go to Tommy\'s bar".)

Esp #3 will occur if you escape data at the input layer (or you need to de-escape it again, etc).

PS: I'll second the advice for not using magic_quotes, those are pure evil!

like image 33
Jilles Avatar answered Sep 16 '22 14:09

Jilles


There are a lot of ways to do XSS (See http://ha.ckers.org/xss.html) and it's very hard to catch.

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.

like image 37
Christian Studer Avatar answered Sep 16 '22 14:09

Christian Studer


This is a great question.

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.

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 strip_tags function and only present the html tags you are allowing.

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.

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 http://us3.php.net/magic_quotes

For more details check out http://ha.ckers.org/xss.html

This isn't a complete answer but, hopefully enough to help you get started.

like image 39
Matt Farina Avatar answered Sep 16 '22 14:09

Matt Farina


rikh Writes:

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

See Joel's essay on Making Code Look Wrong for help with this

like image 45
Mason Avatar answered Sep 18 '22 14:09

Mason


Template library. Or at least, that is what template libraries should do. To prevent XSS all output should be encoded. This is not the task of the main application / control logic, it should solely be handled by the output methods.

If you sprinkle htmlentities() thorughout your code, the overall design is wrong. And as you suggest, you might miss one or two spots. That's why the only solution is rigorous html encoding -> when output vars get written into a html/xml stream.

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?

like image 38
user319490 Avatar answered Sep 16 '22 14:09

user319490


I rely on PHPTAL for that.

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 htmlspecialchars() or |escape somewhere.

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.

like image 28
Kornel Avatar answered Sep 20 '22 14:09

Kornel


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 Referer link to another site. Additionally, if you allow your users to submit links, make sure no javascript: protocol links are allowed; these would execute a script as soon as the user clicks on the link.

like image 44
Konrad Rudolph Avatar answered Sep 20 '22 14:09

Konrad Rudolph


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.

Read more: Sanitizing user data: How and where to do it

like image 28
Niyaz Avatar answered Sep 17 '22 14:09

Niyaz