Category Archives: Rants

On Overbookings

“I never understood how overbooking is legal. (I know this wasn’t really an overbooking incident, and I know about the no-show excuse. But if you buy tickets for a cinema, or a theatre, or book a place in a restaurant, or whatever, they never tell you “Sorry, but we gave your place to someone else. Here’s a cookie.”)”
— Myself in a Facebook comment, 12th April 2017

The recent incident where a passenger was violently removed from a United flight to make room for United employees reopened an old argument about overbookings on flights. While this wasn’t in itself an overbooking incident (even though some airlines like to treat “overbooking” as an umbrella term encompassing even incidents like this), it reminded me of the intentional practice of overbooking, which is not just a desperate measure by abysmal airlines like Air Malta, but indeed a blight that plagues the greater majority of the airline industry.

Image credit: here

It is well-known that most airlines intentionally allow their flights to be overbooked due to statistics that state that on average, some 10-15% of booked seats result in no-shows. The excuse is that the seat left empty could instead be used to transport a passenger who does show up. This is obviously a slap in the face of the people who, conversely, do show up for their seat and are denied boarding because the flight was overbooked, and offered measly compensation for it.

If you make a booking at a restaurant, cinema, theatre, etc, they never tell you “Sorry, but we gave your place to someone else. Here’s a cookie.” You booked a place, and they are supposed to respect it. Of course, you might not show up, and that’s a risk on them.

But in the case of flights, you pay for them in advance. Whether you show up or not, you actually paid for that seat. It’s yours. How is it even legal to sell that same seat a second time to someone else? It’s like selling the same item at a store to two different people, have both pay for it, expect the losing party to actually ask for his money back (and keep it if they don’t), and let them just live with the disappointment.

I am really furious not only that airlines carry out this sleazy practice, but also that the authorities allow it to happen. Even worse, the compensation (at least here in Europe) is pathetic. It barely makes up for lost time at work, and has absolutely no consideration about stress and hassles that take place as a result, including the eventuality of having to cancel holiday plans, miss connecting flights, and run after airlines for compensation. As I had already noted in my article about when Air Malta left us stranded, not only is the compensation not enough disincentive to leave passengers at the airport, but it actually makes it worth the risk for the airlines.

I’m sorry, but you just cannot justify this sort of gross mistreatment of customers by quoting passenger statistics and airline profits.

The Broken Web of March 2017

This article is the March 2017 issue of the monthly series that started with “The Sorry State of the Web in 2016“, showing all kinds of blunders on websites ranging from the silly to the insecure and illegal. While I spot a good number of these myself, many are brought to my attention by contributors, and I would like to thank them all.

JobsPlus

JobsPlus, which is the ridiculous new name for what used to be ETC, had launched a new website as part of their rebranding.

Despite that, their content still can’t handle apostrophes, not to mention basic formatting such as bulleted lists:

At least, it was built with internationalisation in mind. In fact, you can choose a language…

…with a single selection of English. That’s very useful indeed!

JobsPlus also have a service where they send a daily email with all new vacancies. Typically there are no new vacancies during weekends, but they still send an empty email. This has been going on for around 10 years if not more (formerly as ETC, of course).

Henley Malta

The Henley MBA might teach you many useful things, but building a basic website is definitely not one of these!

In fact, here are two basic things you should never have on your website:

  1. Broken images
  2. Misleading links that unexpectedly open your email application.

Just Some Coding

The only thing worse than a misleading link is something that looks like a link but is not, as you can see on Just Some Coding Ltd‘s website.

There are many ways to emphasise text on the web, but underlining is not a good one. Underlining is usually associated with a link, so when you see big green underlined text like “art” or “functional”, the typical user might try to click on it, only to realise that it’s not actually a link.

Maypole

Maypole is yet another website insecurely accepting credit card information:

Secured by Thawte indeed, but there’s no padlock. We’ve been through this several times before and I won’t bore you by repeating the details, but refer back to “The Sorry State of the Web in 2016” if you don’t understand why this is bad.

MFSA Registry

Let’s also welcome the MFSA Registry into the the realm of oft-repeated security issues, in this case that of having an untrusted SSL certificate:

As if that wasn’t enough, the same website also accepts login details over an insecure connection:

Bank Cross-Origin Issue

I recently caught some functionality in a local bank’s webite that was completely broken because of this cross-origin problem:

That’s not nice to have in a production environment.

Owner’s Best

Owner’s Best recently launched a new website, and not without issues. Until the time of writing this article, you can still see “Error: Rows Not Set” at the bottom of the page:

At one time, I was checking out a particular property, and they have these buttons on the side where you can see the floor plan and other details:

When clicking one of these buttons, however, I was taken to this contact form:

I was really confused by the fact that this contact form came up instead of the floor plan I was expecting, and the back button wasn’t working either.

What actually happened was this: the contact form is actually right below the property detail shown in the earlier screenshot, so properties that don’t have additional info will cause those buttons to link to an empty anchor, which has the side effect of bringing the contact form to the top of the page. The least they could have done is hide the buttons if the relevant detail is not there for the current property.

Roller Blades Malta

There’s one important lesson we can take away from Roller Blades Malta: don’t enter website content when you’re drunk.

Star Web Malta

Woe be upon thee, if thou hast an invalid WoeID:

Transport Malta

We all love Transport Malta, and for those who want to actually communicate their love, they have a contact form (note also the messed up action / social media list on the side):

Unfortunately, however, they don’t want to receive your love. The contact form goes to this page:

Transport Malta also joins the list of websites that accept login details on an insecure channel:

TVM

TVM‘s website, unlike that of JobsPlus, is in both English and Maltese. However, they forgot to translate “Sign In / Register” in the Maltese version:

WhatsOn

whatson.com.mt is another website accepting login details over an insecure channel:

Before you can login or register, though, you have to get past the cookie-acceptance text that comes up in front of the login/register form. This text tells you that you have to accept cookie usage to proceed, but the site has already set cookies regardless of your acceptance.

Xamarin University

When you sign up for Xamarin University, you have to consent to Microsoft to spam you.

While they say that you can unsubscribe at any time, I don’t want Microsoft sending me trash in the first place.

I also was unable to access some of the site’s functionality, because their JavaScript was broken:

Summary

We’ve seen quite a few bad things in this article, and I have even more lined up for the April issue. As always, feel free to bring to my attention any blunders you have experienced and feel should be included.

I have summarised various points to improve upon in earlier articles, and feel there would be little benefit by repeating them in this one.

However, I just want to remind everyone why I am writing these articles: it’s not to put shame on any particular website, but to learn about the bad things on the web today and avoid repeating them in the future. These experiences are painful to visitors of such websites, and embarrassing for the website developers and the companies commissioning them. Let’s all learn from our mistakes and create a better web for all!

How To Be An Asshole, By Example

Denis Leary came up with some really creative ways to be an asshole back in 1993. However, nowadays we have more modern ways to piss people off, as I discovered from some recent encounters. I bet Denis wasn’t expecting any of these when he wrote that song.

LA Metro

It’s not enough for the Los Angeles Metro system to be completely unreliable in terms of punctuality or operation. They even have to confuse people by having trains appear on the wrong track. In the photo above, the train to Union Station should be on the track to the left, but it just arrived on the track on the right, which is supposed to be destined for North Hollywood.

“Microsoft Edge is faster than Chrome”

Long after Microsoft was forced to give Windows users a decent choice of browsers (because shipping Internet Explorer with Windows is the only thing that gave such a hopeless browser a leading position in the market for so many years), it is still pulling dirty tricks to try and promote adoption of its web browsers. In this screenshot sent in by a friend, we can see how Windows 10 pathetically tries to win Chrome users over to Microsoft’s more recent Edge browser, saying that “Microsoft Edge is faster than Chrome”.

Similar popups include “Microsoft Edge is safer than Firefox” and “Chrome is draining your battery faster”.

I’ve seen these kinds of filthy tactics carried out by politicians for years, but never thought they would be used between web browsers.

Universal Studios Hollywood WiFi

At the time of writing this article, it costs at least $105 to get into the Universal Studios Hollywood theme park. So it is really shameless to put a condition like “Your information will be shared with Comcast XFINITY and Universal Theme Parks for promotional purposes” in order to use free WiFi. Just give them a fake email address, and you can use WiFi without being spammed.

Feedback Touchscreen in Restroom

In recent years, a lot of our digital interactions have been revolutionised by simple touch gestures. However, having a touchscreen for feedback at the Malta International Airport’s restrooms is probably taking this too far. I mean it’s ok if you assume everybody washes their hands. But can you really assume that?

The way they ask is also very awkward at best:

“How was your experience at this washroom today?”

Uhhh, do you really want the details?

Stone from the Azure Window

Just a day after the collapse of the Azure Window in Gozo (Malta), with many people mourning the loss of a national icon, an opportunist is selling what he claims to be “original stone from the collapsed Azure Window Gozo (Malta)”:

This person gives a bit more detail in the item description:

“Item specifications : Piece of Azure Window rock approx 100g

“Many are asking how can they be sure that the rock is from the mentioned area? Well all I can say is that I am a local and have access to location in less than 10 min drive. I plan to dive in the area and maybe even collect pieces from the sea bed 😉

“Thanks”

I guess this one needs no further comment.

The Weeping Web of January 2017 (Part 2)

This is a continuation of my previous article, “The Weeping Web of January 2017 (Part 1)“.  It describes more frustrating experiences with websites in 2017, a time when websites and web developers should have supposedly reached a certain level of maturity. Some of the entries here were contributed by other people, and others are from my own experiences.

EA Origin Store

When resetting your password on the EA Origin Store, the new password you choose has a maximum length validation. In this particular case, your password cannot be longer than 16 characters.

This is an incredibly stupid practice, for two reasons. First, we should be encouraging people to use longer passwords, because that makes them harder to brute force. Secondly, any system that is properly hashing its passwords (or, even better, using a hash algorithm plus work factor) will know that the result of a hashed password is a fixed length string (regardless of original input length), so this is not subject to any maximum column length in a database.

Untangled Media

If you scroll through the pictures of the team at Untangled Media, you’ll see that the last one is broken. Ironically, it seems that that person is responsible for content.

Needless to say, broken images give a feeling of neglect that is reminiscent of the mythical broken window from The Pragmatic Programmer.

Outlyer on Eventbrite

Another thing that makes sites (and any written content, for that matter) look unprofessional is typos. If you’re sending an SMS to a friend, a typo might be acceptable. If you’re organising an event to launch a product, three typos in the same sentence don’t give a very good impression.

BRND WGN

The first thing you see on the BRND WGN website is an animation taking up the whole screen, switching around frantically like it’s on drugs:

There are only three things you can do to learn more about what the site has to offer: play a video, click on (literally) a hamburger menu, or scroll down.

While I’m not sure this can be reasonably classified as mystery meat navigation, it does no favours to the visitor who has to take additional actions to navigate the site. While the hamburger icon looks like a cutesy joke, it looks silly on what is supposed to be a professional branding website, and hides the site’s navigation behind an additional layer of indirection.

This is a real pity, because if you scroll to the bottom, the site actually does have well laid out navigation links you can use to get around the site! These should really be the first thing a visitor sees; it makes no sense that they are hidden at the bottom of the page.

I also noticed that if you click on that hand in the bottom-right, you get this creepy overlay:

The only reasonable reaction to this is:

Image credit: taken from here.

Daphne Caruana Galizia

The controversial journalist and blogger who frequently clashes with public figures would probably have a bone to pick with her webmaster if she knew that the dashboard header for her WordPress site was visible for not-logged-in users while she was logged in last week:

While this won’t let anyone into the actual administrative facilities (because a login is still requested), there’s no denying that something went horribly wrong to make all this visible, including Daphne’s own username (not shown here for security reasons).

Identity Malta

The Identity Malta website has some real problems with its HTTPS configuration. In fact, Firefox is quick to complain:

This analysis from Chrome, sent in by a friend, shows why:

Ouch. It defeats the whole point of using SSL certificates if they are not trusted. But that’s not all. Running a security scan against the site reveals the following:

Not only is the certificate chain incomplete, but the scan identified a more serious vulnerability (obfuscated here). An institution dealing with identity should be a little more up to speed with modern security requirements than this.

Another (less important) issue is with the site’s rendering. As you load the page the first time or navigate from one page to another, you’ll notice something happening during the refresh, which is pretty much this:

There’s a list of items that gets rendered into a horizontally scrolling marquee-like section:

Unfortunately, this transformation is so slow that it is noticeable, making the page load look jerky at best.

Battle.net

I personally hate ‘security’ questions, because they’re insecure (see OWASP page, engadget summary of Google study, and Wired article). Nowadays, there’s the additional trend of making them mandatory for a password reset, so if you forget the answer (or intentionally provide a bogus one), you’re screwed and have to contact support.

If you don’t know the answer to the silly question, you can use a game’s activation code (haven’t tried that, might work) or contact support. Let’s see what happens when we choose the latter route.

Eventually you end up in a form where you have to fill in the details of your problem, and have to provide a government-issued photo ID (!). If you don’t do that, your ticket gets logged anyway, but ends up in a status of “Need Info”:

The idea is that you need to attach your photo ID to the ticket. However, when you click on the link, you are asked to login:

…and that doesn’t help when the problem was to login in the first place.

It’s really a pain to have to go through all this crap when it’s usually enough to just hit a “Reset Password” button that sends you an email with a time-limited reset link. Your email is something that only you (supposedly) have access to, so it identifies you. If someone else tried to reset your password, you just ignore the email, and your account is still fine. In case your email gets compromised, you typically can use a backup email address or two-factor authentication involving a mobile device to prove it’s really you.

Security questions are bullshit; they provide a weak link in the security chain and screw up user experience. Let’s get rid of them sooner rather than later.

Malta Health Department

It is a real pity when a government department’s website loses the trust supposedly provided by HTTPS just because it uses a few silly images that are delivered over HTTP.

The Economist

Remember how you could read any premium article on The Times of Malta by just going incognito in your browser (see “The Sorry State of the Web in 2016“)? Seems The Economist has the same problem.

Article limit…

…no article limit…

Remember, client-side validation is not enough!

On a Positive Note, Mystery Meat Navigation

I’m quite happy to see that mystery meat navigation (MMN) seems to be on its way out, no doubt due to the relatively recent trend of modern webites with simple and clear navigation. I haven’t been able to find any current examples of MMN in the first five pages of Google results when searching for local web design companies, so it’s clear that the local web design industry has made great strides compared to when I wrote the original MMN article.

Summary

This is the third article in which I’ve been pointing out problems in various websites, both local and international. After so many years of web development, designs might have become prettier but lots of websites are still struggling with fundamental issues that make them look amateurish, dysfunctional or even illegal.

Here are some tips to do things properly:

  • If you’re accepting sensitive data such as credit cards of passwords as input, you have to have fully-functional HTTPS.
  • Protect yourself against SQL injection by using parameterised queries or a proper ORM.
  • Test your website. Check various kinds of inputs, links, and images. Don’t waste people’s time or piss them off.
  • Use server-side validation as well as client-side validation.
  • Ensure you have proper backup mechanisms. Shit happens.

The Weeping Web of January 2017 (Part 1)

Not even a month has passed since I wrote “The Sorry State of the Web in 2016“, yet I already find myself having to follow up with new material detailing things that should be things of the past. Because in 2017, we really should know better. Some of the entries here were contributed by other people, and others are from my own experiences.

[Credit: image taken from here]

GitLab

You might have heard a few times how a company did something really stupid that messed up its business and reputation, like the Patreon Security Breach. Well, just today, GitLab went down with a bang:

How did that happen?

Ouch. But everyone makes mistakes, right? Let’s see the incident report (emphasis mine):

  1. “LVM snapshots are by default only taken once every 24 hours. YP happened to run one manually about 6 hours prior to the outage
  2. Regular backups seem to also only be taken once per 24 hours, though YP has not yet been able to figure out where they are stored. According to JN these don’t appear to be working, producing files only a few bytes in size.
  3. Disk snapshots in Azure are enabled for the NFS server, but not for the DB servers.
  4. The synchronisation process removes webhooks once it has synchronised data to staging. Unless we can pull these from a regular backup from the past 24 hours they will be lost
  5. The replication procedure is super fragile, prone to error, relies on a handful of random shell scripts, and is badly documented […]
  6. Our backups to S3 apparently don’t work either: the bucket is empty
  7. We don’t have solid alerting/paging for when backups fails, we are seeing this in the dev host too now.

“So in other words, out of 5 backup/replication techniques deployed none are working reliably or set up in the first place. => we’re now restoring a backup from 6 hours ago that worked”

This explains where the name “GitLab” came from: it is a lab run by gits. Honestly, what is the point of having backup procedures if they don’t work, and were never even tested? You might as well save the time spent on setting them up and instead use it for something more useful… like slapping yourself in the face.

Booking.com

Like its airline cousins, booking.com is a bit touchy when it comes to input data. In fact, if you’ve got something like a forward slash or quotes in your address, it will regurgitate some nice HTML entities in the relevant field:

Smart Destinations

The problems I’ve had with my European credit card not being accepted by American websites (usually due to some validation in the billing address) apparently aren’t limited to US airlines. Just yesterday, while trying to pay for a Go Los Angeles card, I got this:

Hoping to sort out the issue, I went to their contact form to get in touch. After taking the time to fill in the required fields:

…I found to my dismay that it doesn’t actually go anywhere:

So much for the response within 24 hours. The destinations may be smart, but the developers not so much.

Ryanair

I’ve been using Ryanair for a while, so I recently thought: why not register an account, to be able to check in faster? So I did that.

Last week, I opted to do my online check-in as a Logged In User™. When I logged in, I got this:

I found out from experience that you’re better off checking in the usual way (e.g. with email address and reservation number). At least it works.

Super Shuttle

Booking with Super Shuttle involves a number of steps, and between each one, you get a brief “loading”-style image:

As you would expect, it sits on top of an overlay that blurs the rest of the page and prevents interaction with it. Unfortunately, this has a bad habit of randomly getting stuck in this situation, forcing you to restart the whole process.

Another thing about Super Shuttle is that you can actually include a tip while you’re booking:

Wait. Why would anyone in his right state of mind want to tip the driver before he has been given a good service? What if the service actually sucks?

Malta VAT Department

If you go to VAT Online Services, and try to login at the “Assigned or Delegated Services” section…

…you see an error page that seems like it survived both World Wars.

Well, at least it’s secure!

To Be Continued…

Adding all the entries for January 2017 into this article would make it too long, so stay tuned for Part 2!

If you have any similar bad experiences with websites, send them in!

The Sorry State of the Web in 2016

When I republished my article “Bypassing a Login Form using SQL Injection“, it received a mixed reception. While some applauded the effort to raise awareness on bad coding practices leading to serious security vulnerabilities (which was the intent), others were shocked. Comments on the articles and on Reddit were basically variants of “That code sucks” (of course it sucks, that’s exactly what the article is trying to show) and “No one does these things any more”.

If you’ve had the luxury of believing that everybody writes proper code, then here are a few things (limited to my own personal experience) that I ran into during 2016, and in these first few days of 2017.

SQL Injection

I was filling in a form on the website of a local financial institution a few days ago, when I ran into this:

It was caused by the apostrophe in my surname which caused a syntax error in the SQL INSERT statement. The amateur who developed this website didn’t even bother to do basic validation, let alone parameterised queries which would also have safeguarded against SQL injection.

Airlines and Apostrophes

My experience with airlines is that they tend to go to the other extreme. In order to keep their websites safe, they simply ban apostrophes altogether. This is a pain in the ass when your surname actually has an apostrophe in it, and airlines stress the importance of entering your name and surname exactly as they show on your passport.

United Airlines, for instance, believe that the surname I was born with isn’t valid:

Virgin America, similarly, takes issue with my whole full name:

We’re in 2017. Even shitty Air Malta accepts apostrophes. All you need to do is use parameterised queries or a proper ORM. Using silly and generic error messages doesn’t help avoid customer frustration.

Plagiarism

Speaking of Air Malta, here’s a classic which they ripped off from some other US airline:

US Federal law? In Malta? Go home, Air Malta. You’re drunk.

Don’t Piss People Off

I’ve had a really terrible experience with booking domestic flights with US airlines. There is always some problem when it comes to paying online with a VISA.

United Airlines, for instance, only accepts payments from a specific set of countries. Malta is not on that list, and there is no “Other” option:

Delta gives a variety of billing-address-related errors depending on what you enter.

Southwest provides fields to cater for payments coming from outside the US:

And yet, you need to provide a US State, Zip Code and Billing Phone Number.

The worst offender, though, is Virgin America. While the overall experience of their AngularJS website is quite pleasant, paying online is a hair-ripping experience. If you choose a country where the State field does not apply (such as Malta, or the UK), a validation error fires in JavaScript (it doesn’t appear in the UI) and does not let you proceed:

It’s almost like the developers of this website didn’t quite test their form. Because developers normally do test their code, right? Right?

Well, when I reported the error to Virgin, and offered to provide a screenshot and steps to reproduce, the support representative gave me this canned bullshit:

“So sorry for the web error. Can recommend using one of our compatible browsers chrome or safari. Clearing your cookies and cache.  If no resolve please give reservations a ring [redacted] or international [redacted] you’ll hear a beep then silence while it transfers you to an available agent.  Thanks for reaching out.~”

I had to escalate the issue just so that I could send in the screenshot to forward to their IT department. Similarly, I was advised to complete the booking over the phone.

Over a month later, the issue is still there. It’s no wonder they want people to book via telephone. Aside from the international call rate, they charge a whooping $20 for a sales rep to book you over the phone.

Use SSL for Credit Card And Personal Details

In July 2016, I wanted to book a course from the local Lifelong Learning unit. I found that they were accepting credit card details via insecure HTTP. Ironically, free courses (not needing a credit card) could be booked over an HTTPS channel. When I told them about this, the response excuse was:

“This is the system any Maltese Government Department have been using for the past years.”

It is NOT okay (and it’s probably illegal) to transmit personal information, let alone credit card details, over an insecure channel. That information can be intercepted by unauthorised parties and leaked for the world to see, as has happened many times before thanks to large companies that didn’t take this stuff seriously.

To make matters worse, Lifelong Learning don’t accept cheques by post, so if you’re not comfortable booking online, you have to go medieval and bring yourself to their department to give them a cheque in person.

I couldn’t verify if this problem persists today, as the booking form was completely broken when I tried filling it a few days ago – I couldn’t even get to the payment screen.

Update 8th January 2017: I have now been able to reproduce this issue. The following screenshots are proof, using the Photo Editing course as an example. I nudged the form a little to the right so that it doesn’t get covered by the security popup.

Update 9th January 2017: Someone pointed out that the credit card form is actually an iframe served over HTTPS. That’s a little better, but:

  • From a security standpoint, it’s still not secure.
  • From a user experience perspective, a user has no way of knowing whether the page is secure, because the iframe’s URL is hidden and the browser does not show a padlock.
  • The other personal details (e.g. address, telephone, etc) are still transmitted unencrypted.

Do Server Side Validation

When Times of Malta launched their fancy new CMS-powered website a few years ago, they were the object of much derision. Many “premium” articles which were behind a paywall could be accessed simply by turning off JavaScript.

Nowadays, you can still access premium articles simply by opening an incognito window in your browser.

Let’s take a simple example. Here’s a letter I wrote to The Times a few years ago, which is protected by the paywall:


Back in 2014, I used to be able to access this article simply by opening it in an Incognito window. Let’s see if that still works in 2017:

Whoops, that’s the full text of the article, without paying anything!

Like those critics of my SQL injection article, you’d think that people today know that client-side validation is not enough, and that it is easy to bypass, and that its role is merely to provide better user experience and reduce unnecessary roundtrips to the server. The real validation still needs to be server-side.

Conclusion

Many people think we’re living in a golden age of technology. Web technology in particular is progressing at a breathtaking pace, and we have many more tools nowadays than we could possibly cope with.

And yet, we’re actually living in an age of terrible coding practices and ghastly user experience. With all that we’ve learned in over two decades of web development, we keep making the same silly mistakes over and over again.

I hope that those who bashed my SQL injection article will excuse me if I keep on writing beginner-level articles to raise awareness.

On Akka .NET Actor Creation

Abstract: this article is a bit of a rant about how actors are created in Akka .NET, and suggests a way of making it just a little bit more manageable. This is written based on my limited knowledge of Akka .NET, and I will be more than happy to stand corrected on the matters I write about.

Actors Need Props

Creating an ActorSystem and actors in Akka .NET is one of the most basic necessities, and it is something you’ll be doing all the time. Once you have an ActorSystem, you can create actors using an IActorRefFactory implementation (i.e. the ActorSystem itself, or an actor’s Context). This requires you to use Props.

            using (var actorSystem = ActorSystem.Create("MyActorSystem"))
            {
                var props = Props.Create<MyActor>();
                var actor = actorSystem.ActorOf(props);

                Console.ReadLine();
            }

What the hell are Props?

This is explained by Unit 1 Lesson 3 of the Petabridge Akka .NET Bootcamp. Basically, the answer is something like: it’s a recipe for creating actors, but don’t worry about it for now; we’ll use it later.

As a matter of fact, it’s needed mainly for advanced scenarios such as remote deployment and clustering. Most of the time as you’re learning to use Akka .NET, you don’t really care about them.

Creating Props

There are three ways to create Props, all involving some manner of a call to Props.Create().

The first way is to give it a Type.

var props = Props.Create(typeof(MyActor));

This is discouraged by Akka .NET, because it has no type safety and in fact lets you do stupid things like this:

akka-actorcreaton-typeof

The second way is to use a generic form:

var props = Props.Create<MyActor>();

While this is encouraged in the bootcamp, I personally discourage this. This is because while it gives you type safety over the actor type, it doesn’t give you any guarantees with the parameters:

akkanet-props-generic-2

The third way is to pass in a factory method. This is a great way to create Props because it’s the only one that lets you pass dependencies into the actor’s constructor in a type-safe manner (particularly important to use constructor injection if you’re thinking of writing tests against your actors).

var props = Props.Create(() => new MyActor());

Making It Better

In reality, most of the time I don’t care about Props. So why do I have to constantly bother about them? Actually, if we take a closer look at the third way of creating Props, we can wrap them into oblivion:

akkanet-props-expression

See that generic Expression over there? That’s what we need to avoid all this madness. Based on that, we can create a generic method to take care of everything:

    public static class IActorRefFactoryExtensionscs
    {
        /// <summary>
        /// Creates an actor, creating props based on the provided
        /// actor factory method.
        /// </summary>
        /// <typeparam name="T">The actor type.</typeparam>
        /// <param name="actorRefFactory">ActorSystem or actor Context.</param>
        /// <param name="actorFactory">Actor factory method.</param>
        public static IActorRef CreateActor<T>(this IActorRefFactory actorRefFactory,
            Expression<Func<T>> actorFactory) where T : ActorBase
        {
            var props = Props.Create(actorFactory);
            var actor = actorRefFactory.ActorOf(props);
            return actor;
        }
    }

To create an actor directly from the ActorSystem, we now only need to do this:

var actor = actorSystem.CreateActor(() => new MyActor());

…and to do it from inside an actor, it’s just as easy:

var actor = Context.CreateActor(() => new MyActor());

Weird Conventions

This is where the rant begins.

Apart from all the weirdness associated with having to deal with Props in the first place, Unit 1 Lesson 3 of the Petabridge Akka .NET Bootcamp has this little gem that makes my day brighter every time I read it:

How do I make Props?

“Before we tell you how to make Props, let me tell you what NOT to do.

DO NOT TRY TO MAKE PROPS BY CALLING new Props(...). Similar to trying to make an actor by calling new MyActorClass(), this is fighting the framework and not letting Akka’s ActorSystem do its work under the hood to provide safe guarantees about actor restarts and lifecycle management.”

Here’s a similar gem from Unit 1 Lesson 1:

NOTE: When creating Props, ActorSystem, or ActorRef you will very rarely see the new keyword. These objects must be created through the factory methods built into Akka.NET. If you’re using new you might be making a mistake.”

Wait, what? These guys are telling us to call static Create() methods rather than using constructors. These are the same people who told us that using async/await in actors is bad (which has since been corrected). I don’t know, but I bet if you ask anyone who has done OOP before, they’ll tell you that if there’s a mistake, it’s in Akka .NET’s design.

But to really top it all, check out the following comment from Aaron Standard (Petabridge CTO and Akka .NET co-founder) on the Reddit thread about one of his articles (emphasis mine):

Orleans is a piss-poor implementation of the Actor model and breaks a lot of the conventions that make it powerful, aside from having an overall hideous set of programming conventions. But because MSFT released it, people will flock to it like lemmings.

“We’re going to keep working on Akka.NET because there’s a community supporting it now and because we believe in TypeSafe’s vision for actor systems.”

A case of the pot calling the kettle black? Or quoting Confucius, “Don’t complain about the snow on your neighbor’s roof when your own doorstep is unclean.”

In any case, my goal is not to start a flame war but to understand why the Akka .NET API (and codebase) is such a mess. If you look at the source code for ActorSystem, for instance, it does not do anything so particularly complicated that would justify banning constructor calls. In fact, the call to ActorSystem.Create() ends up here:

        private static ActorSystem CreateAndStartSystem(string name, Config withFallback)
        {
            var system = new ActorSystemImpl(name, withFallback);
            system.Start();
            return system;
        }

In fact, although you shouldn’t do this, this code works just as well as what we had before:

            using (var actorSystem = new ActorSystemImpl("MyActorSystem"))
            {
                actorSystem.Start();

                var actor = actorSystem.CreateActor(() => new MyActor());

                Console.ReadLine();
            }

Why is this even public such that I can call it?

Conclusion

The API provided by Akka .NET, particular in ActorSystem and actor creation, is very strange indeed. We are discouraged to do something as trivial a calling a constructor, and have to deal with Props even though we won’t need them most of the time. It is hard to speculate on why this API was written this way without having the developers provide insight on it.

At the very least, aside from pointing out these obvious flaws, this article aims to suggest best practices on how to go about creating Props, and to provide an extension method to hide the existence of Props for the majority of cases where using them directly isn’t really necessary.

Lessons Learned from the Patreon Security Breach

Patreon is a popular crowdfunding platform, providing “recurring funding for artists and creators”. I was considering using it myself. I’m glad I didn’t.

Almost two months ago, Patreon suffered a security breach, and several gigabytes of data including a copy of their production database and their source code were leaked on the internet. An article at Ars Technica covers some of the details of the breach.

As I read the press release from Patreon about this incident, my feeling was of utter disbelief, particularly when reading these two points (emphasis mine):

  • “The unauthorized access was confirmed to have taken place on September 28th via a debug version of our website that was visible to the public. Once we identified this, we shut down the server and moved all of our non-production servers behind our firewall.
  • “There was no unauthorized access of our production servers. The development server included a snapshot of our production database, which included encrypted data.”

I’m not sure whether I need to explain why having your development environment publicly accessible, and why using production data in your development environment, are both very stupid things to do. Either way, now I don’t need to explain that. What happened to Patreon shows exactly why no one in his right state of mind would do this.

Further down, Jack Conte, CEO/Co-founder of Patreon, writes:

“I take our creators’ and patrons’ privacy very seriously.”

Sorry, but given what happened here, I find that very hard to believe. It doesn’t matter what steps are being taken to increase security. It’s already too late. People’s private data are now on the internet, and there’s no going back.

So if you want to spare your company a lot of embarrassment, here’s what you need to take away from this incident:

  • Keep your development environment isolated from your production environment.
  • Use dummy data, not production data, in your development environment.

An Overview of Air Malta’s Customer Service

Introduction

Just a few days ago, Air Malta was voted 6th Best Regional Airline in Europe, measured based on customer satisfaction. And as an irate former customer of Air Malta who has experienced a terrible customer experience just a few weeks ago, this really makes me wonder under which rock people are living. Just the day before, another story appeared in which a cellist lost her cello’s seat because of an overbooking.

This article deals with my own bad customer experience with Air Malta, due to being stranded in Budapest towards the end of June 2015. However, it also mentions other incidents which give a deeper illustration of Air Malta’s customer service.

Summary

  • We were meant to fly from Budapest to Malta on 29th June 2015.
  • Due to a technical fault, a smaller plane was used, leaving many passengers stranded in Budapest.
  • We spent 7 hours at the airport.
  • Air Malta never communicated with us directly.
  • We missed all replacement flights for the day since Air Malta took ages to confirm our seats.
  • Budapest airport staff claimed that Air Malta was uncooperative and refused to pay for the overnight accommodation.
  • When we claimed compensation (due by EU law), Air Malta agreed only on condition that we sign an agreement which, among other things, forces us to keep the settlement confidential.
  • Other past incidents show how Air Malta knows nothing about customer service.

Seven Hours at the Airport

On 29th June 2015, I went to Budapest airport with my friends to catch the Air Malta flight back to Malta. Shortly after arriving, we learned from the flight schedule board at the terminal that the flight was being delayed by two hours. We thought nothing of it at the time, as there was still plenty of time to get back to Malta in the evening.

However, things looked a lot more grim as we joined the checkin queue. This queue was at a standstill for quite a long time, with passengers and airport staff alike shuffling back and forth. We eventually learned that the aeroplane suffered some kind of technical fault, and that a smaller one was being sent as a replacement, which meant that not everybody would fit. Some people were rerouted via other flights.

Over the span of the next few hours, airport staff struggled to deal with Air Malta in order to get a replacement flight. Time after time, they brought up our hopes, saying there was another flight we could take – only to bring those hopes back down when we realised that Air Malta had failed to confirm our places on those flights in time.

Once we missed the last flight, via Brussels, we resigned ourselves to the fate of spending an extra night in Budapest. Budapest is a lovely place, but many of us had to go to work the next day, and others would miss a day from their holiday in Malta. At that point, we told the airport staff that we understood there was nothing more that could be done, and that we’d appreciate being settled in a hotel as soon as possible. Spending seven hours in an airport is not fun.

The airport staff apparently tried to get hold of Air Malta to get the accommodation, dinner and transfer booked, but more time went by and we remained at the airport. In the end, the airport pretty much gave up on Air Malta and arranged for everything on their own initiative. In all this time, we never heard anything from Air Malta directly.

On Compensation

During our seven-hour ordeal at Budapest airport, we had already educated ourselves – using intermittent WiFi access that didn’t work most of the time – about our rights under the circumstances. EU law [PDF] entitled us to at least EUR250 plus food expenses. We didn’t count the dinner and accommodation of course, because the airport covered those. But we did incur additional expenses due to this mess, including:

  • Mobile expenses. This is difficult to quantify since Vodafone charge EUR3, and Go want EUR12 and an affidavit, in order to provide a breakdown of charges.
  • Lost day of work. The cost of this varies from person to person.

The EUR250 worth of compensation is not a very fair deal, to be honest. The value of compensation depends mainly on distance, and not on duration (as long as it’s more than 3 hours). So technically, if you’re delayed for 3 hours, 1 day, or a week, you get the same compensation. That can’t possibly make up for a lost day of work.

Also, having such a low compensation fee makes it worthwhile for unscrupulous airlines such as Air Malta to exploit the practice of overbookings (more on this later).

Clarifications and Settlement

One of my friends and fellow passengers wrote to Air Malta on behalf of 8 of the people who spent the extra night at Budapest, requesting compensation. Aside from requesting compensation for the 8 people, the email also asked for clarifications on why we were neglected as described earlier in this article.

Air Malta replied as follows (emphasis mine):

“First of all, we would like to apologise for all the inconvenience caused with reference to the flight you had with us. Although Air Malta tries to offer the best possible service, there are instances that the service given is not in accordance to the passengers’ expectation. In this case, the flight was overbooked and we had to reroute several passengers from the direct flight to other connections available.

We had problems with communicating with the handling agents in Budapest, and we tried to accomodate all the passengers to fly the same day. In fact, some of the passengers who were denied boarding flew via Munich or Athens, and we tried to reroute the others via Brussels. We already had made the necessary changes, however, due to several reasons, the check-in for the flight from Budapest to Brussels closed soon before the passengers could arrive to board.

“Air Malta made it clear that any hotel accomodation, transport and meals required for the passengers, can be refunded, and we never delayed or declined to offer such convenience, as stated in your email. However, as we said beforehand, we had an ongoing miscommunication with our handlers in Budapest, and this caused a lot of confusion and misinformation to the passengers.”

However, they agreed to pay the EUR250 plus food expenses, if we provide our bank details (necessary to transfer the refund) and sign a form (emphasis mine):

“In light of the above, to cover any inconvenience this mishap has caused all of the passengers that were denied boarding, we are offering the amount of €250 each, as per EU Law. Moreover, passengers that were denied boarding can send us the receipts of any meals that they had to buy for their extra stay by mail on the address in the signatory, in order to give the refund of such. Kindly fill in individually the Release and the ex-Gratia Form in order to provide you the amount stated (Reference and PNR listed above), and send them back as a reply to his email by not later than the 17th July 2015.”

The Release form, among other things, included the following (emphasis mine):

“1. The Releasor accepts the sum of EUR TWO HUNDRED AND FIFTY (€250.00) from the Releasees without admission of liability in full and final settlement of all claims for damages, interest, costs or expenses whether past, present or future and whether ascertained or unascertained, which the Releasor may have against the Releasees howsoever arising out of the matters recited above.

2. In consideration or receipt of the said sum Releasor:-

[…]

“(e) undertakes and warrants that he/she (as applicable) will keep this Release and Discharge and settlement recorded in it confidential, and will not disclose such information to any other person or entity (unless required by law to do so or for purposes of taking legal advice).”

So basically they were telling us that, in order to provide us compensation required by EU law, we would have to keep the settlement secret, accept it as final settlement, and sign it within a specified deadline. But more on that later.

My friend, who initiated the communication with Air Malta, followed up, asking for clarification about the use of the word “overbooked” in Air Malta’s email, and highlighting the fact that the airline should have made contact with us (as it is required to do by EU law), especially in the context of “miscommunication” with the airport.

In their subsequent reply, Air Malta explained their interpretation of their earlier use of the word “overbooking”:

“The reason why there was an overbooking is because there was a technical problem, and the aircraft had to be changed in order to avoid any further delays. In fact, instead of the A320, as previously scheduled, the A319 was used for the flight Budapest to Malta, leaving some passengers stranded.”

Conditions for Settlement

The settlement (EUR250 + food) offered was the least Air Malta could offer us. It was required by law, and at the same time did not cover other expenses (e.g. lost day of work) that resulted from this undesirable experience. Nonetheless, I sent Air Malta my bank details for the refund. However, I did not sign the Release Form, which required me among other things to keep the settlement confidential. You see, after being abandoned in Budapest airport like that, imposing conditions and deadlines to give me the least required by EU law felt like a kick in the nuts. It’s a bit like saying “I’ll give you what I owe you, but only if you get down on your knees.” So I wrote as follows:

“Please note that I am not including the Release Form. Under EU law, you are bound to compensate us for the denied boarding, and you have no right to place additional obligations or deadlines.”

They insisted that I sign the Release Form, and made it clear that they would only provide compensation if I complied.

I refused to sign the agreement given the conditions, and threatened to sue them.

Following that, they refused to provide the compensation unless I sign the form, with the excuse that it is a company requirement in order to process refunds.

I replied that their company requirements are irrelevant, because they are obliged by EU law to provide the compensation. That is where I decided to take the matter to the authorities.

The Air Passenger Rights section within the Malta Competition and Consumer Affairs Authority, which is the national authority that deals with consumer complaints, received my complaint. They made it clear that the airline have no right to impose conditions or deadlines to give compensation due by law. Quite the opposite: this compensation does not preclude further action to secure additional compensation – something that I would have renounced, had I signed the Release Form.

Facebook Denial

A few days ago, seeing the introduction of Air Malta’s “Sky Spa” free in-flight massage treatment, I wrote on their Facebook page:

air-malta-facebook-reply

It’s funny how “overbooking” appears again in this context – presumably because it’s so common that it’s one of the primary causes of customer complaints that the airline’s customer service department (if you can call it that) is well-experienced at handling.

But it’s also worrying that in this comment, Air Malta seem to not know anything about the incident. They may either be lying, or else their IT system is in such a complete mess that they are unable to retrieve historical flight data from it.

While I obviously cannot know which of these is actually the case, the latter is not too far-fetched. In fact, a friend of mine recently told me about a problem he had with Air Malta’s customer service. Although he uses their services regularly, the flights he took did not appear under his account on their website. When he reported the problem, instead of retrieving the data from their database, they asked him to produce evidence that he had taken those flights.

As if this wasn’t enough, another friend of mine reported similar conditions when reactivating his Flypass. Quoting Air Malta’s Flypass Terms and Conditions:

“Any closed Flypass account cannot be reactivated unless passenger proves that he/ she has flown at least four scheduled flights within the six months` period preceding his/ her request. The four boarding passes need to be forwarded to Flypass Unit and KMiles for these four flights only will be credited retroactively.”

On Overbookings

We’ve seen earlier how Air Malta used the word “overbooking” quite freely (even though overbooking had nothing to do with the Budapest incident). This is pretty ironic, because it is easy to find evidence of actual overbookings that Air Malta has been responsible for in the past, such as this one in Athens in 2013, and this one in Verona in 2010.

If these incidents sound like they happened a long time ago, check out the recent incident with the cello’s seat, clearly due to an overbooking according to Air Malta’s own words:

cellist-overbooking-fb

This is actually not very different from how Air Malta explained and justified the overbookings in the Athens 2013 article:

“”Overbooking is a normal occurrence in the airline industry and not particular to Air Malta. The reason why airlines overbook flights is due to ‘no-shows’ when people book on a flight and fail to show up at the check-in desks. Unfortunately seats blocked for booked passengers who fail to show up remain empty when the flight departs,” an airline spokesman said.

“These unutilised seats may be required by other travellers. In fact, flights which are not overbooked may result in many prospective passengers being denied an opportunity to fly on seats which would otherwise be unused, the airline said. Air Malta has a very low rate of denied boarding compared to the industry as a whole.”

So what they’re saying here is that they allow extra seats to be purchased, because if someone doesn’t show up, they can sell his seat to someone else. But if the person who doesn’t show up paid for the seat, what gives the airline the right to sell it to someone else, making double the money from a single seat? How is this even legal?

Also, the ridiculous compensation schemes we have make this practice very viable. At best, the airline would have sold two seats for the cost of one, and at worst, it would have sold that seat and compensated the person who was denied boarding, leaving that passenger more or less where he started financially, but with a great inconvenience.

If overbooking is a standard practice in the airline industry, it doesn’t mean all airlines do it. Ryanair, the low-cost airline frowned upon for many other reasons, “does not overbook its flights” [PDF], something that has been confirmed by a Which? investigation.

Similar Incident in 2008

After I explained my ordeal in Budapest, a friend of mine reached out and recounted a similar experience he had in Milan in 2008. He was informed in the morning that his 3pm flight was to be delayed by 3 hours. Despite this, he spent until 3am at the airport; no one communicated with him at the time, there was no Air Malta representative, and the airport staff knew nothing about the flight. Although he asked for compensation, he was never granted any.

Conclusion

Air Malta’s customer service is simply terrible, and the authorities will decide whether it is also illegal. My advice is thus: don’t fly with Air Malta, even if the ticket is free.

Even when flying with other airlines, know your rights. If your airline refuses compensation or imposes conditions, you have other means at your disposal to claim what is yours by right. It might take a little longer, but we can’t let the airlines keep treating us like dirt because they think we’re too afraid or apathetic to pursue them legally.

Bluehost Ripping Off Customers

I’ve been running websites for almost 13 years (since 2002). For the past 8 years (since 2007), I’ve hosted my websites at Bluehost. Last month, I decided to switch to a different provider. Here’s why.

Different pricing for renewals

Bluehost lure their customers with seemingly low rates for hosting and domains, making full use of the elusive asterisk.

bluehost-asterisk

If you follow that asterisk to the bottom of the page, you’ll find some fine print saying that this fancy price applies for the first year only:

bluehost-asterisk-2

To see how much you’d really pay, check out the hosting prices and the domain prices.

At the time of writing, you can expect to pay the following rates after your first year:

bluehost-hosting-prices

At the time of writing, the domain prices are the following (excerpt):

bluehost-domain-pricing

So a renewal for a .com domain, including privacy, is going to set you back $27.87. And you’ll be paying $4 more than you did when you bought it the first time.

Sudden price increases (domains)

Bluehost tend to increase their prices without informing their customers. With domains, I saw this happen over a number of years.

  • From 2007 – 2010, a domain cost $10.
  • In 2010, I was charged $4.95 extra for domain privacy. I opted out of it and didn’t pay for privacy again.
  • Around mid-2011, I was charged an extra $1.80 in taxes. Fine.
  • By end-2011, I was paying $14.10 ($11.95 for the domain and $2.15 in taxes). The tax thing eventually got resolved, and I continued paying $11.95 for my domains until around mid-2012.
  • In August 2012, I was charged $13.99 for a renewal, and in November 2012, I was charged $11.99 for a new domain.
  • From August 2013 until today, I’ve been paying $14.99 for domain renewals.
  • In October 2014, adding domain privacy cost me $9.99.

Noticing this fishy business a few years back, I wrote to Bluehost support on 10th February 2013:

Hi,

Since when are domains being charged at $13.99? Over the past couple of years I’ve been charged different prices for domains including $10.00, $11.95, $11.99, and $13.99.

What is going on?

They replied:

Hello,
To purchase a domain it is $11.99. To renew it is $13.99. That is why you are being charged different prices for purchase and renewal.

Sudden price increases (hosting)

That was just for domains. Let’s see how hosting evolved over the years.

  • In 2007, I paid $166.80 for hosting – that’s $6.95 per month for 24 months.
  • In 2009, I paid another $250.20 – that’s $6.95 per month for 36 months. It might seem to be the same price, but I actually had to pay for an extra year to remain within the same price. If I remember correctly, buying a 2-year term would have cost $7.95 per month.
  • In 2012, I had another renewal. I don’t have any email records for this one, so presumably it remained the same.
  • On 14th May 2015, I received an email which was a bit of a shock:

bluehost-hosting-ripoff

So these guys suddenly decided to increase my fee from $6.95 to $9.99 per month, and actually had the nerve to tell me that I was saving money. I only learned about this because my next renewal was drawing near – Bluehost don’t bother to inform their customers about these changes.

Furious, I wrote to their support department:

Hi,

I just got an email saying that my web hosting will be renewing soon, and that I’ll be paying $9.99/mo. What is this about? I thought I was paying something like $6.99.
And you even have the nerve to say I’m saving $180?
I’m feeling cheated, and I expect an immediate explanation.

Their reply was thus:

Hello,
Our hosting renewal rates increased recently due to significant upgrades that have been made to our servers and the services we provide. This price increase will also allow us to continue investing in the best technology to make our hosting services even better.

Because of this price increase, apart from better performance and reliability of your account, the Plus hosting package which you are currently on now offers spam experts and cloudflare at no charge for one domain name.

Spam experts is an email filtering addon that helps to block and remove unwanted spam and dangerous emails that may cause problems with your webmail accounts.

cloudflare is a content distribution network that, when activated for your domain, distributes your website’s static information across servers around the globe, thus increasing download speed, performance, and security of your website.

I would also love to look over your account and see if you are a fit for our starter package to save you some money.
Please respond with Domain name and last four of the main account password so we can further assist you.

Sick of this bullshit, I wrote just what I thought at the time:

Hi,

Your “significant upgrades” are insignificant to me. The new features mean nothing to me, as does your marketing attitude, because I never agreed to pay extra for these new features (not to mention the ever-increasing renewal costs for domains). And the least you could have done was to inform me in advance of the price increase.
Guess what: there exist companies that thrive by NOT ripping off their customers. And I’m moving on to one of those.

Their next reply seemed to ignore the fact that I was done with them, and involved a proposal of sorts:

Hello,

Thank you for your email and apology for the inconvenience caused.

In starter package you can host one main domain and five parked domain. You have one addon domain in your account. In order to downgrade your account to starter package please unassign or park your addon domain. Once the domain is unassigned please get back to us. So that we will downgrade the package to starter plan .

Renewal rates for Starter plan:

1 month  $7.99/mo
> 3 months $7.99/mo (billed at $23.97)
> 6 months $7.99/mo (billed at $47.94)
> 1 year   $7.49/mo   (billed at $89.88)
> 2 years  $6.99/mo (billed at $167.76)
> 3 years  $5.99/mo (billed at $215.64)

We will be happy to assist you with a term-change if another term-length or hosting plan better fits your needs. Please get back to us with following:

The plan and term length you would like to change to.
The last four case-sensitive characters of the main login password.
The last four digits of the credit card used for the most recent hosting payment.

Please let us know if you have any question.

So it came to this: either pay a lot more for the same service, or pay roughly the same and get downgraded.

Conclusion

I moved away from Bluehost because their costs are ridiculous, and they increase substantially almost every year without warning. For instance, my current web hosting provider charges just $9.95 for a domain (whether it’s a new one or a renewal) and privacy is included.

They quite clearly run their business by ripping off their customers, and provide only lame excuses.