Posts in category internet - page 3

How dangerous is HTML injection?

A few years ago I believed that HTML and SQL injection vulnerabilities were headed for extinction. Thanks to object-relational mapping tools SQL injection continues to die but HTML and script injection vulnerabilities are as popular as ever.

Part of the problem stems from the “back-to-basics” approach to rendering web pages, throwing out classes and controls for string-based libraries (primitive obsession) and helpers which do not encode HTML or even offer a concise simple syntax to do so.

MonoRail was one such project but they took feedback on board and addressed the issue although I was surprised it had got as far as release candidate 2 with such a serious oversight.

Other projects have been less reactive when advised of the problem and I can’t help but wonder if I am not getting the severity of the issue across. This isn’t just an annoyance but a real security problem.

If you are not familiar with:

  • HttpUtility.HtmlEncode (.NET)
  • Server.HtmlEncode (ASP)
  • htmlentities/htmlspecialchars (PHP)
  • html_escape (Rails)
  • {! } (MonoRail Brail)

and your web apps output data then they are likely open to HTML & script injection vulnerabilities.

Vulnerable code often looks like this:

myLabel.Text = Request.Form["Something"];
<%= myDataReader[0] %>
<? php echo get_the_title() ?>

For more ASP.NET examples check out 5 signs your ASP.NET application may be vulnerable to HTML injection.

Let’s start by considering the actors involved:

Visitor to visitor

If your site stores input from an external user (visitor) and displays it to another then you could be exposed to this scenario. Many sites do this although it is not always immediately recognized – an internet banking site does not seem an obvious candidate until you consider that you may put a textual reference on payments made to another person. If you know they use a vulnerable internet banking solution…

A worst-case scenario here would be that one visitor could steal another’s login credentials and exploit whatever rights that might give him – anything from posting messages to stealing funds.

Visitor to staff

Not all sites exchange data between users but if your site collects information from visitors chances are it presents this information to staff. Internal systems used to examine it are often considered less vulnerable which is a mistake. Remember all data provided from a user should be considered to be a potential avenue for a dangerous payload, e.g. even the language-accepts or user-agent strings.

When exploited internal systems can reveal information in bulk about the users, the system and the administration accounts used to manage it. Gaining access to these details brings all the privileges those accounts have to offer which can be catastrophic.

Staff to visitor

It is easy to forget that many frauds are perpetuated by people on the inside. A staff member given the ability to present text to the user via a website has the ability to modify any page that the content is presented on which if it includes a login page (perhaps for system status messages) then capturing login details to a server of their own choice is easy.

Security operators with access to reset (but not view) passwords would find this attack particularly enticing given that they do not need to reset the users account and therefore raise any awareness. An insider can perpetuated the fraud and may be in a position to further conceal it within the organization.

Next steps?

I can envisage a sequence of steps that start with discovery of injectable systems through detection of script-enabled into form capture-and-forward and async logging of passwords through XmlHttp.

Detailing those steps would certainly raise awareness and help developers appreciate the severity of the issue but how do I make sure that information isn’t abused?

Disclosure is a double-edged sword but then you can’t have security through obscurity… I wonder how many crackers/black hackers already utilize these techniques for nefarious means.

.NET developers might like to check out the [slides from the Web Application Security talk](/blog/2007/08/16/gsdf-august-2007-postmortem) I gave at the Guernsey Software Developer Forum which demonstrates exploitable, exploits and safe alternatives for preventing HTML and SQL injection.


Free software projects need a pitch

Open source and free software projects still have much to learn from commercial software, the number one in my book being “the pitch”.

Most free software project home pages consist of a brief description, a list of technical documents and a number of download options but fail to pitch their solution at all.

Today I found myself at the home page for Mercurial which describes itself as

a fast, lightweight Source Control Management system designed for efficient handling of very large distributed projects

The site fails to persuade me to use or even evaluate their product. They present no argument for using their product over non-distributed systems such as Subversion nor why I should choose their product over distributed systems such as Git (which has associations with Linus and Google).

Contrasting that experience to the home page for Perforce, a commercial (non-distributed) product for source control management, we see:

  • “Why Perforce” – the 10 minute pitch that covers their unique aspects such as performance, high-availability databases
  • A quote from customer Clive Maxfield at iDesign pointing out that Perforce handles more than just source code (binary files & assets)
  • Videos showing Perforce in operation so you can see how the product works (and learn it at the same time)
  • Links to comparisons with ClearCase (commercial offering) and Subversion (popular free software offering)

Just because your software carries a $0 price tag doesn’t mean it will sell itself. Evaluating software takes time and effort which could mean another open source or commercial software is chosen because either it works out cheaper or made a better case for its selection.

When a project isn’t interested in new users that signals it could be a “pet-project” written for the challenge and not to address a real need not met by existing solutions. Until these projects reach a certain level of maturity, and some never do, users can expect to take a back seat in an uncomfortable ride.

So if your project wants users, pitch it.


List of Guernsey Estate Agents

I’ve posted my list of Guernsey Estate Agents as other on-line lists were not comprehensive and prevented bookmarking or copying the address to send to others thanks to the annoying framing they used (so 90’s).

Yes, I’m house-hunting again after my estate agent failed to mention (claimed to be ignorant of the fact) that all the lovely fields and views from my proposed home were already marked as a target housing area by the States of Guernsey as part of their Urban Area Plan (PDF, 5Mb).

These sites were set in 2002 and number just five. I wonder how long these people would last in IT if they took such an active disinterest in their field?


Notes on the move to WordPress

The change to WordPress from Subtext went without major hitch. This was great considering I was tweaking the design and articles right up to going on holiday (I wouldn’t do this in a professional environment but my blog is a sandpit for such dare-devil risk taking ;-)

Here are my notes on the experience.


Akismet is good but I prefer the invisible captcha that Subtext was using. I’ve gone from dealing with 1 rogue spam a month to 1-2 held for moderation a day.

View counts

The WordPress import format doesn’t deal with view counts. I wrote a query against Subtext to list them, a query in MySQL to identify article numbers then manually executed

UPDATE post_meta SET meta_value = meta_value + 123 WHERE meta_key = 'views' AND article_id = 456

For every article replacing 123 with Subtext’s view count and 456 with the WordPress article id. As my blog was previously on which doesn’t provide view counts they are a year or so lower than reality.

I chose a custom permalink format of /blog/%year%/%monthnum%/%day%/%postname% which gives // for posts. This is similar to the old format of but obviously has the file extension and www dropped. Apache’s .htaccess file made redirecting the old links a breeze which was important to me as my blog suffered big drops in Technorati and Google when I last moved from to Subtext. The required lines to achieve this, redirect /blog/ and keep the RSS going were:

RedirectMatch permanent ^/blog/archive/(.*).aspx$ //$1
RedirectMatch permanent ^/blog/$ //
RedirectMatch permanent ^/blog$ //
RedirectMatch permanent ^/blog/rss.aspx //
RedirectMatch permanent ^/blog/Rss.aspx //


The default editor is fast and for the most part okay although it lacks the ability to change from the default paragraph tag to headings, pre-formatted blocks, block-quotes etc. It also very annoyingly tries to be helpful by turning carriage returns into new paragraphs which would be fine if it was clever enough to leave <pre> blocks well alone.

Steve suggested FCKeditor which is very slow at initializing on my machine and also tends to really mess up my HTML :(

Going forward

There are still a number of things I want to do including further deviating from the Redoable theme. Lightening up the look somewhat perhaps with some soft gradients and alternative typefaces will go a long-way. I’ll also want to do a proper logo at some point as soon as I can decide what it should look like.

Being that WordPress is a higher visibility target Phrixus suggested hiding the wp-admin directory as an extra level of protection against automated vulnerability/brute-force attacks which I shall also try.

I need to speak to GrinGod about the download counting mechanism he mentioned too.

The original content from a year or two ago will be phased out/removed as it would appear it dilutes my page rank having almost-identical content elsewhere not to mention messing up traffic stats etc.