Monday, 27 July 2009

Using a windows service to schedule a job in VB.Net

A quick rundown on how to schedule a job from a windows service in VB.Net using the Quartz.net scheduling library. You may need to schedule a job to run for all sorts of reasons:

• Closing down old website sessions in a database
• Running a nightly refresh of data
• Pull files down from the internet

Or a million other things that I won't list here.

Depending on your level access to the server / your server policy, you may be able to tackle this task using a variety of other methods like scheduled tasks or, particularly pertinent if you are in a shared hosting environment, using IIS Cache expiry as a cheap way to schedule tasks.

A bit of background on Quartz

"Quartz.NET is a port of very propular open source Java job scheduling framework, Quartz. This project owes very much to original Java project, it's father James House and the project contributors.

Quartz.NET is a pure .NET library written in C# which currently targets Framework version 1.1 and above. Quartz.NET is feature-wise equal to Quartz Java 1.6 excluding Java specifics. Quartz.NET is already running in production systems and has received good feedback."

Some Code

The following example is some code I created to run a refresh job on some data:

First off, create a windows service project.

Add a reference to the Quartz library, which can be downloaded at http://quartznet.sourceforge.net/

At the top of your file add the import statements to the namespaces we will be using:

Imports Quartz
Imports Quartz.Impl

Now, in the service OnStart event of your service, add the following code:

' construct a scheduler factory
Dim schedFact As ISchedulerFactory = New StdSchedulerFactory()

' get a scheduler
Dim sched As IScheduler = schedFact.GetScheduler()
sched.Start()

' construct job info
Dim jobDetail As New JobDetail("RefreshJob", Nothing, GetType(Refreshjob))


Dim trigger As Trigger = TriggerUtils.MakeDailyTrigger(10, 30)


trigger.StartTimeUtc = DateTime.UtcNow

trigger.Name = "RefreshTrigger"
sched.ScheduleJob(jobDetail, trigger)


The above code has basically set up a scheduler, which, when triggered (by the time hitting 10:30) will look for a type (in this case RefreshJob) and run the execute method within the class.

So now we have to create the RefreshJob type, which will implement the interface Quartz.IJob

Imports Quartz

Public Class Refreshjob
Implements IJob

Public Sub New()
End Sub

Public Sub Execute1(ByVal context As Quartz.JobExecutionContext) Implements Quartz.IJob.Execute

' Run your code

End Sub

End Class


Conclusion


Really nice library, easy to use, Job's a good 'un.

For more functionality, check out the Quartz docs and examples at http://quartznet.sourceforge.net/





kick it on DotNetKicks.com


Thursday, 14 May 2009

XSRF - Thoughts on mitigation...

Having successfully manipulated a shopping cart in an unrealistic little test using a bit of jQuery and a simple Cross Site Request Forgery, it's time to discuss some of things we can do to avoid these sorts of problems in our own web applications.

The simple things

Use get and post correctly:

GET
Requests a representation of the specified resource. Note that GET should not be used for operations that cause side-effects, such as using it for taking actions in web applications. One reason for this is that GET may be used arbitrarily by robots or crawlers, which should not need to consider the side effects that a request should cause.

POST
Submits data to be processed (e.g., from an HTML form) to the identified resource. The data is included in the body of the request. This may result in the creation of a new resource or the updates of existing resources or both.
From wikipedia...

I figure it's best to just do what HTTP tells me to do on this one, and not think about it for too long.


Validate all your user input


Everyone has heard it all before, no doubt, but validate all user input on the server. If you're using MS MVC, check out xVal... Useful for wiring up client-side validation from your model. If you're using web forms, do whatever you have to do, but make sure you validate.


Store your user_id in the session


And accept as few details from the user as needed. You already know how much your product costs... you don't need the user to tell you.


Check the referrer


Check the referrer and ensure the request came from your domain. If you're using MS MVC, check out this post about the AntiForgeryToken.




Anyone got any other simple things we should be doing on this one?

XSRF Attacks in AJAX enabled apps

So, I've been doing a lot of AJAX development recently and decided to have a little think about the security the various methods and techniques that I've been employing...


The basic AJAX situation...

You have a button on your page. On clicking the button, an XMLHTTPRequest is made to a URL to perform an action. The action is executed and the web page receives some sort of response to say whether the action was successful... It may also supply some data to display on the web page - perhaps a JSON object, or maybe a chunk of HTML.


The thing I was particularly interested in was the security around the URLs that the AJAX request hit... Essentially, these URLs are simply open points to execute actions against your application.

In my apps, you have to be logged in to perform any action that changes data in any way, so a user would have to be authenticated in order for these exposed URLs to be abused.

As I write this, I have multiple tabs open in my browser (IE at the moment incidentally). One of the tabs is logged into my webmail account. I still have [MySuperMarket].com open where I'm in the middle of putting together my weekly food shop. I have iGoogle open in another, my blog is open and logged in, the current tab I am looking at, and finally a couple of wikipedia articles in some more tabs.

This means I am currently authenticated against no less than 4 web apps, without taking into account any sites I have persistent log in enabled on (that check box that asks if you want to stay signed in on this computer)... God knows how many of them I have.

So, I have established that at least 4 sites currently trust any requests sent from my browser.

My thinking followed the idea that any request from my browser - regardless which tab, would be able to execute actions against any of these logged in applications. Time to try and execute some actions in one of these apps from outside of it's domain then...


A Proof of concept...

I went to the tab with the supermarket site open. Opened fiddler, and hit a button to add some cooked chicken to my shopping cart:



The highlighted row above shows a call has been made to the url:

/basket/add.aspx

along with a bunch of querystring parameters (detailing the ID of the particular product, the quantity, and various other things).

I then removed the chicken from my cart.


Crafting the web page to abuse this action

I figured, all I would need is a webpage that creates an XMLHTTPRequest to the above url, with appropriate querystring data supplied. I created the following HTML file:



Hopefully you can see it is a basic page with a hyperlink. I have used jQuery to attach a click event to the hyperlink which fires an AJAX request to the relevant URL.

I opened the HTML page in my browser, clicked the link, went to the supermarket tab and refreshed my cart... Hey presto - There's some chicken in there.

It appears all I have to do is get people to follow a link to the HTML page I have created, and, if they are logged into the particular supermarket, everyone will be getting extra chicken with their shopping orders

<evilThoughts>
Ha ha ha. Today unwanted chicken chaos, tomorrow the world.
</evilThoughts>


Thoughts

This is obviously a bit of a silly little example, but is good for a POC. Potentially I could be performing all sorts of undesirable action.

Furthermore, what does this mean for online banking sites, betting sites or other places where money can be moved around?

At first consideration, this appears to be a fairly serious problem. It's known as a cross site request forgery or XSRF.

Whilst it doesn't just effect AJAX apps, I think that as people start to embrace AJAX it will be easy to make mistakes, unless we think carefully about exactly what functionality we are providing to the world at large - intentionally or not.

Further musings on this coming later...


kick it on DotNetKicks.com




Monday, 22 October 2007

Subsonic (.net ORM)

is BRILLIANT!

Not much content here. Just want to say that if you're still writing your own data access layer, stop now and head on over the SubSonic site and start using the easiest ORM I've ever had the pleasure of messing with...

10 minutes into TellyBook and I had my whole DAL up and running. Didn't have to write a single stored procedure or 1 line that said "... command as new SQLCommand(connection, "BlahBlahBlah")..."

I certainly won't miss that. Their site is full of useful articles and webcasts that really do mean you can just plug this thing in and get moving with it.

Props to Rob Conery and the rest of the guys.

****UPDATE****

And it looks like soon SubSonic may have rails style validation (Directly added to the generated model):

SonicCast - Validation

BRILLIANT!!!

***************

Argotic : Turning an RSS Feed into a list(of T)

Now then,

Managed to find some useful RSS feeds of various channels (mainly BBC, but it'll do for now) from the good folks here:

http://bleb.org/tv/

So thats the first complication dealt with... no screen scraping for me.

I then set about turning the feed into a collection of Programme objects. I'd heard about Argotic Syndication Framework a while ago so I decided to give it a shot.

Initial thoughts are... nice and easy to use and it just seems to work...

The code I'm using at the moment:

Dim pList As New System.Collections.Generic.List(Of TellyBook.Programme)()
Dim feedUri As New Uri("http://bleb.org/tv/data/rss.php?ch=bbc1&day=0")
Dim feed As RssFeed = RssFeed.Create(feedUri)

For Each item As RssItem In feed.Channel.Items
Dim p As New TellyBook.Programme
p.Title = item.Title.Substring(6, (item.Title.Length - 6))
p.Time = item.Title.Substring(0, 4)
p.Description = item.Description
p.Channel = c.Name

If p.Time > currentTime Then
pList.Add(p)
End If
Next


That was simple. So... here's the breaks. Got an RSS feed you wanna turn into a collection of objects, give Argotic Syndication Framework a go....

Experimenting with facebook

Ok,

I wanna experiment a bit with facebook apps, so I've decided to make a simple app which for the time being I'm going to call Tellybook.

The basic idea is as follows: I scrape /find RSS feeds / somehow get hold of... TV and radio listings for the major channels in the UK. I'm then gonna check out the facebook user's favorite films, tv programs and music listings. I will compare the user's favorites against programs / films / live performances that are on TV and radio over the next few days and alert the user to what is coming up that matches their entries...

The idea will probably grow as I build the thing, but I think this is a good starting point...

Technologies I plan to use:
ASP.NET and SQL 2005 for the code bits.
Subsonic for DB access
JQuery for any AJAXy / trendy stuff
facebook.dll - FB developer toolkit
Argotic - for turning RSS into objects (if needed)

this may change as the project moves forwards... we'll see