Umbraco workshop with Milagro as a warm-up.

Today I did a workshop with the four developers at Milagro not yet certified. I managed to cover most of what's in the Level 1 and Level 2 courses, in just about six hours.

First we covered the basics of installation, followed by Document Types, Master Document Types, and how they connect to Templates. Just before lunch we added content, and covered the umbraco:Item WebControl.

After lunch we covered Macros in XSLT and .NET, the Node and Document API:s, and the major differences between the two. I even managed to squeeze in XSLT Extensions and EventHandlers.

Luckily, they all had a good grasp on XSLT before we started, as that's usually a major hurdle for new Umbracians.

This was all done as a warm-up for tomorrow's MeetUp here in Stockholm, celebrating Umbraco's 5th birthday. I can't say I've been along for the ride for all that time, but I've seen Umbraco grow from a young version 2.1 to an almost grown up 4.1, that's almost 4 out of the 5 years it's been around as Open Source. It's been fun so far, and I see no reason to quit.

Tomorrow, we celebrate.

Oh, and if you for some reason want me to come and show you the ropes in Umbraco, get in touch.

Available for hire from April 1st

Today it became finalized that I will be available for hire from April 1st and on, since Milagro chose not to extend my contract. It has nothing to do with my skills, but is rather an economic issue.

Sad as it may be, it leaves me available for hire, to do Umbraco or EPiServer work, wherever I may be needed. I have several years experience, and am certified, on both platforms. I work well in teams, and solo, and you're really missing out if you don't hire me. If needed, I'll travel for start up meetings etc. So don't hesitate just because I'm Swedish. I'm that good.

There's an online resume-ish site here. And I'll even send you a PDF with more info, if you still have doubts.

I know, cheap trick, but I have a family to support. :)

Reasons NOT to buy a Mac, according to my dad.

Today my dad asked me for advice on buying a new personal computer, and being the avid Apple fan boy that I am, I proposed he get a Mac Mini. Currently he has an Acer TravelMate laptop, weighing in at a sleek 6 kg (13 lbs), and sporting an impressive 512 Mb RAM, no need to say anything more, it needs to be replaced.

Anyway, we're at the store, and the sales-guy gives me the pitch, yada yada, I can do this and that, Windows 7 is the shit, etc and so forth. I totally agree with him, on most points, but true peace of mind, well, it comes with a Mac. It just works. Never mind the price, you can't compare a Mac Mini, with a midi-tower computer. But, I digress. My dad had a few reasons not to buy a Mac, and they are some I, at least, haven't heard before. Maybe Microsoft should pick up on these.

My argument was "In the long run, you'll get more value for your money."

His comebacks were:

  1. "But what if I re-use my OEM XP license, I'll save money."
  2. "My company has a few licenses for XP, and Office, I can use those."
  3. "I'll have to re-learn everything I know about computers, it'll take too long with a Mac."
  4. "Ok, listen up. I'm a diabetic, 61-year old smoker, I won't live long enough to benefit from a Mac In the long run. I haven't got time for that."

There's a sales pitch for Windows 7 if I ever saw one.

Using Umbraco as an application platform - a sneak preview.

Lately I've been working on a project, where I'm using Umbraco as a template engine for an application. It's the follow-up version of the application I will be demoing on the Umbraco 5th anniversary meetup in Stockholm. So far everything is going according to plan, and today I managed to output my first compiled Flash SWF-file. It's a combination of custom ActionScript, MTASC and SWFMILL. But it goes to show that Umbraco can be used for pretty much anything.

The application has evolved from a fairly straight forward Umbraco site, with some heavy use of jQuery and XSLT, into a very powerful tool, using Flash/Flex Remoting through FluorineFx, a Provider pattern for easy customization of generated output. It used the beta of Umbraco 4.1, and relies heavily on LINQ 2 Umbraco for fetching data, since the Flex Remoting calls are made outside of Umbraco's context.

I would really love to showcase it here, but I have to check with the code owners (my client) first. If I don't get permission to showcase some source, I'll try to get permission to talk about the general approach. Or you can hire me to get full advantage of my knowledge :)

Anyway, I'll be posting snippets from my slides after February 16th, stay tuned.

Time to give this thing a personal touch.

Ok, it says in the header that this blog is supposed to be about fatherhood. So I thought I'd put a picture of my kid up on here. His name is Alfred, he's 3 months old, and he's the best thing that ever happened to me.

Alfred, 3 months

Removing the "Create" option from the Context Menu in Umbraco.

Many times I've found myself becoming irritated that the "Create" option in the Umbraco UI context menu, is there even when there aren't any allowed child nodes under that node. When I click it, all I get is an empty dialog. Here's how you get rid of it.

Umbraco EventHandler: OnContentTreeBeforeNodeRender

Please, do note, this solution isn't for everyone. There might be a special case when you'd want that empty dialog. I don't know when or why, but it might happen. Also, you might ask why I keep putting code samples in images. It's because I want you to actually read what you are putting into your own source, and not just copy and paste. Copy and paste isn't a very good practice you know.

A note on finding and reporting vulnerabilities.

Yesterday I found an XSS vulnerability in the Blog4Umbraco package, and after I'd found it I did what I thought was right. I documented the vulnerability, and the solution,and posted it on the forum at Our Umbraco. At first glance, that might seem right. However, I've now had time to consider the approach properly.

I tweeted my findings, and after a few minutes I got a mail from Umbraco Founder Niels Hartvig, saying that he would've loved a heads-up before I posted. Yeah, I should've given him that. My post may have been informing and all, but giving the Umbraco team a heads-up would've made sure that a solution was made re-distributable from them, instead of having developers finding the solution - if they were looking - on their own.

The next time I find a vulnerability, I know the order of things.

  1. Document the vulnerability.
  2. Notify the distributor.
  3. Wait for a fix, and an OK to publish.
  4. Publish.

But what I want to know is, where's my piece of flare? :)

XSS vulnerabilities in the Blog4Umbraco package.

As promised, I started checking for XSS vulnerabilites in the Blog4Umbraco package, and as a matter of fact, I found one. Or two, depending on how you look at it.

Posting comments.
When posting comments, they are sent to Akismet for SPAM-checking, and Akismet does an OK job, but it doesn't check for XSS, or HTML or JavaScript. It checks for SPAM. Nothing more.

However, when I posted a script tag as a username, it marked that as SPAM, so at least it does something :)

The message however, isn't checked, and neither is it encoded on output. That leaves not only the front-end, but also the back-end susceptible to attacks. I tried posting plain HTML, as well as a script with a simple alert. Not only did it fire whenever i viewed the page, but also in the Dashboard control used to moderate comments.

So, straight to the fixes.

In the BlogPostListComments.xslt, make sure that output is HTML encoded. Thus:

<xsl:value-of select="umbraco.library:ReplaceLineBreaks(./message)" disable-output-escaping="yes" />

should be

<xsl:value-of select="umbraco.library:ReplaceLineBreaks(./message)" disable-output-escaping="no" />

or even

<xsl:value-of select="umbraco.library:ReplaceLineBreaks(./message)" />

or to make it somewhat pretty

<xsl:value-of select="./message" />

And in the Dashboard control (/usercontrols/CommentModeration.ascx), instead of
Eval("comment").ToString().Replace("\n","<br/>")
put
Server.HtmlEncode(Eval("comment").ToString())

And that was how I found and fixed the XSS vulnerability in the Blog4Umbraco package. If you want to know more, you could read my previous post.

There's an upgrade package in the repo, and there will be an update out on http://our.umbraco.org later today.

Notes from the EPiServer Meetup in Stockholm.

Yesterday I was at the EPiServer Meetup, which was kindly hosted by KnowIT. It started off with a VERY interesting talk on XSS/CSRF. After a short break with thai food, there was a presentation on developing EPiServer templates that validate and are SEO friendly.

I'm not going to cover the validation/SEO friendlyness here, not because I believe that what they said was bullcrap, but rather because I believe that their approach doesn't give the client the freedom of choice I think goes hand-in-hand with using a large scale CMS like EPiServer. When a client uses EPiServer, and tires of their development partner, they should be able to switch over-night. Furthermore, development time is, and this is only my personal oppinion, increased, since developers have to build their own post-back mechanisms. But enough on that, what they said mostly made sense :).

XSS, or Cross-Site-Scripting, is when someone injects HTML or a script, into a site. There are two different kinds, Non-persistent/Reflected or Persisted/Stored.

The Reflected approach is when someone exploits a XSS vulnerability, for example, modifies a querystring parameter so that html and/or javascript is rendered directly onto the page. They then spread a link to their modified URL, and anyone logging on there might be subjected to some form of fraud or some other malignant attempt at their data.

The Stored approach is when someone submits, for instance to a forum or blog comment, html and/or javascript that is then stored on the page for other visitors to be subjected to. Like as if a blog comment here would contain html and javascript that would render a login form on every page, but when fileld out, would send that data to a third party. In short, it would suck. Big time.

Now, how to protect yourself?

In short: Don't allow HTML being posted to your forms. Oh, and check for scripts too.

OK. But that won't always do. I know, so here's a few more lengthy pointers.

  1. Enable validateRequest in web.config in system.web/pages - if this isn't an option for you, i.e. EPiServer's editor won't work, consider using it in combination with your <location> segments, only disabling it where absolutely needed.
  2. Clean your output. HTML-Encode any input sent from the user, or use RegEx to clean those tags/attributes that can cause harm. For me anyway, RegEx is awesome, but I can NEVER seem to learn them.
  3. Implement The Microsoft Anti-Cross Site Scripting Library
  4. Evaluate your content, and look for vulnerabilites. Repeatedly.

Here are some useful links for those that want to know more.

 

So, what then is that other abbreviation, CSRF? CSRF, or Cross-Site Request Forgery, is when a malignant website uses valid data from your browser, like hi-jacking a validation cookie, and sends a request with that valid data, in your name. This was a wake-up call for me.

A possible scenario is, when you're out in your sunday best, couch-surfing. You check your mail at Gmail in one tab, and doing some "grown-up's surfing" in another tab. Your browser then has an authorization cookie for Gmail, certifying that you're logged in, and everything is A-OK. The grown-up-site you're watching has some malicious code on it, that tries to send data to Gmail behind your back, and since your browser is authorized, Gmail accepts that incoming request, forged as it may be.

Working around this can be a hassle, but it isn't impossible, here are a few tips.

  1. Implement an ANTI-CSRF HttpModule.
  2. Check the referrer header, and make sure it's your site making the request. It can be found in HttpContext.Request.UrlReferrer.
  3. Make sure that any crossdomain.xml doesn't allow everything. This is a Flash thing, so if you don't have any Flash on your site, you don't need to bother.
  4. Limit the lifetime of authentication cookies.
  5. If you're using ASP.NET MVC, use the Html.AntiForgeryToken() helper in conjuction with the [ValidateAntiForgeryToken] attribute on your post method.

Here are some useful links for those that want to know more.

 

I'll be testing Umbraco in general, and the Blog4Umbraco package specifically, for XSS vulnerabilites in the next few days, I'll keep you posted.

Finally, thanks to Sergio Molero at Concrete IT for an excellent presentation.

Using an UrlRewriter in Umbraco to change the paging style.

Paging using XSLT is a very useful, and fairly simple (and well-documented here). It generates very SEO friendly links between pages, however, it can be used to generate even better links, with a little tweaking and use of the UrlRewriting.NET that comes with Umbraco. The XSLT examples are from the BlogListPosts.xslt in the Blog4Umbraco package.

Note: I'm using domain prefixes, and if you don't you might have to alter the syntax in some small way to get it working flawlessly for you.

1. Add an entry to the /config/UrlRewriting.config
Code Sample - UrlRewriting, Paging

2. Modify the XSLT so that it outputs a page reference, instead of a querystring.
Was:
Code Sample - UrlRewriting, Paging - Link w/ QueryString Change into:
Code Sample - UrlRewriting, Paging - Link w/ Page Reference

Note: If you're using directory URLs, you can skip the ".aspx" ending of the link, and just add a slash.