I recently tried to buy some cinema movie tickets at SterKinekor. There were no seats currently booked for the show, so I chose a line of 5 in the middle of a row (no empty seats between them). Upon clicking to proceed I was greeted with this stupid message:
Movies are best enjoyed together. Please choose seats that don’t leave a single space
The seats I wanted, in blue
What? I wasn't leaving any open seats - except for the rest of the row to the left and right of the ones I was booking. I get this is to prevent people leaving a gap between currently booked seats and their selection... but that's not what I was doing. There are no other seats booked, what must I do, book from the aisle? Book the whole row? Stupid and frustrating.
Sure enough where there's poor business decision coding (see further below) there's poor coding - this check is client-side only, so with the help of Burp we can bypass it:
- set your browser to proxy through Burp (and install the HTTPS certificate) * disable the "Intercept Client Requests" under Proxy -> Options * enable the "Intercept Server Responses" below it * untick existing rules and add a new one for "File extension" matching "^js" as per the screenshot below
Now that you're all setup:
- force refresh (or visit) the SterKinekor site * "Forward" intercepted .js file responses until "app.
.js" file comes along * search for the text "single space" in it and remove nearly all of the "test:function()" code - leaving just the "return!0" * click "Forward" and then disable the intercepting
Browse the site and book your tickets annoyance free. Thanks to the browser caching our modified .js file we shouldn't need to re-patch it any time soon :)
Tickets booked!
Let's take a look at their code... the function that performs the validation is:
<code>function() {
for (var t = 0; t < c()(e.order.Session.positions).length; t++)
for (var n = c()(e.order.Session.positions)[t], i = e.order.Session.positions[n], s = void 0, a = 0; a < i.length; a++) {
var r = i[a];
if (s) {
var o = Math.abs(r - s);
if (o > 1) return !1
}
s = r
}
return !0
}</code>
The "c()" is just JavaScript's "keys()" function, and "e.order.Session.positions" is a JSON object, eg: {"2": [10, 8 ,9]}.
The "t" loops through the row numbers you have seats in (eg: "2") , the "i" is the seats you've selected in that row (eg: [10, 8, 9]), and "a" is used to increment through your booked seats (eg: a=0 points to seat 10), and "s" is set to zero at the start.
Here's where the problem comes in:
<code>// i = [10, 8, 9]
// r is 10, then 8, then 9 as it loops
// s is 0, then 10, then 8, then 9 as it loops (r's previous value)
if (s) {
var o = Math.abs(r - s); // "r" is 8 on the second loop
if (o > 1) return !1
}
s = r // set "s" to 10 the first loop</code>
Have you spotted it yet? The value of "i" above is [10, 8, 9] - so when "s" is set to 10, and then compared with 8 (the next seat number in the array) the difference is >1 and validation fails.
My fault, right, for not selecting my seats in sequential order? Wrong. I've done several tests and it appears their site is sorting "e.order.Session.positions" alphabetically not numerically... so trying to book seats 8, 9, 10 and 11 in a row results in an array of [10, 11, 8, 9] which fails their validation. Do they seriously not have anyone in their QA team that likes to sit in the middle of a row?