pyro2927 / SouthwestCheckin

🛫 Python script to checkin to a Southwest Flight 🛬
GNU General Public License v3.0
425 stars 128 forks source link

Reverse Engineer Mobile API #42

Open pyro2927 opened 5 years ago

pyro2927 commented 5 years ago

@hoopsbwc34 and I have been digging into other API requests the mobile app has been making, and it appears that you can get to a lot more functionality when you're authenticated. There is this really weird init type stuff happening though, and it processes a ton of Javasctipt to build out headers for all future API requests to use.

The general flow seems to be:

Call Init Script

There are both iOS and Android "init" scripts. These are called with a GET request and return some json.

Process Kernel

Within the returned json, there is a kernel key that appears to contain a ton of Javascript. Both iOS and Android have Javascript runtimes, and at this point I'm assuming these chunks of JS are executed against the local runtime, and have a dictionary returned to them of key/value pairs.

Attach to All Requests

I'm going to pseudo-code this, but it appears it attaches the JS result to all future headers:

prefix = result.json()['nativeSignalHeaderPrefix']
js_results = #some JS eval here returning a dict
for k, v in js_results.items():
  headers.append(prefix + k, v)

The removal of any of these headers results in an invalid request response from the server:

{
    "code": 429999999,
    "message": "Your request could not be completed at this time. Please try again later.",
    "messageKey": "ERROR__ACCESS",
    "httpStatusCode": "BAD_REQUEST",
    "requestId": "",
    "infoList": []
}
pyro2927 commented 5 years ago

Next Steps

Understand the JS?

I've tried de-obfuscating the Javascript, but most libraries to automatically do so don't really provide any clarity. If you're a Southwest app engineer, nice work. I think you won this round.

Just run it?

Pulling out the Javascript and executing it in a browser results in an error: "Native host not available". A quick Googling seems to be this is because it's not running within an installed application runtime.

image

Even if we were able to get the code to run, I'm not sure that it would be effective because we'd need some way to handle the callback with proper values.

Other?

Happy to hear ideas. If we were able to reverse this, it would allow you to have the script constantly monitor your account for new flights and automatically check you in. Feels like a great QoL improvement 😄

sephamorr commented 5 years ago

I'm not very good at JS, but didn't get any further than you. The easiest path forward that I see (short of someone successfully reverse engineering this JS) is to spawn an android emulator and sniff the headers once they're set though a MITM proxy. The Southwest app doesn't pin a tls certificate, so it's relatively easy to do. Super inelegant though.

hoopsbwc34 commented 5 years ago

Looks like another alerts package on github paid someone to solve this problem. Can probably reverse engineer from some of their code once it gets merged:

https://github.com/xur17/southwest-alerts/issues/16

Fffrank commented 5 years ago

I was able to use pyppeteer to generate the correct headers (rather than try and figure out the SW code.) It's working fine in my branch of this southwest price-check tool. I'm not a programmer so this is pretty hacked together (maybe you can make it prettier in your version?) https://github.com/Fffrank/southwest-alerts

You could also use some pieces of that to automatically pull the checkin information so that it could process your checkins automatically without a new instance for each iten.

maximedevalland commented 4 years ago

@Fffrank : out of curiosity, how did you solve bypassing the "X-Xkdw8" headers? I'm actually trying to do the same with British Airways. they have exactly the same protection as you decribed but I couldn't find a way to sign my own request. It appears to be split in 5 headers, 4 remaining the same but 1 being computed, probably based on the "initialize" phase when the app is launched.

Fffrank commented 4 years ago

@maximedevalland You can see what works here: https://github.com/Fffrank/southwest-alerts/tree/test

I use pyppeteer to launch a headless browser and capture the headers that are being returned once logged in. It's not an elegant solution but it worked. I still don't know if southwest was actively following my progress in order to break the script but it felt like a cat and mouse game. At some point it broke again -- since I'm not traveling I haven't been bothered to go back and fix it.

maximedevalland commented 4 years ago

@Fffrank : ok. If you are interested in solving this problem later on, we can join efforts as we're trying to do the same thing.

chuxuanhy commented 3 years ago

Hello, @maximedevalland Did you generate the header successfully? I am also interested in how to generate the headers to make the requests. Hope for your reply. Regards.

maximedevalland commented 3 years ago

I haven't solved the issue and archived the project :-)

chuxuanhy commented 3 years ago

Thank you @maximedevalland. Anyone else knows how to generate the headers, please tell me. I am very appreciated.

Fffrank commented 3 years ago

Now that I have travel back on my schedule I've been trying to make this work again. I can capture the headers but all of the apis have changed or broken over the last year. Unfortunately southwest is incredible aggressive in how often you can poll their servers with bad data before they give you a time-out. As such it will take me some time to fully fix this script but I am working on it.

mkitchingh commented 3 years ago

FYI, I have been using this solution for a while, and it has been working perfectly. Not sure if it will help you solve what you are looking for. https://github.com/byalextran/southwest-checkin

chuxuanhy commented 3 years ago

@Fffrank @mkitchingh thank you!

Fffrank commented 3 years ago

FYI, I have been using this solution for a while, and it has been working perfectly. Not sure if it will help you solve what you are looking for. https://github.com/byalextran/southwest-checkin

Awww I realize now that I'm commenting in the checkin thread. I've been working to revive my project above that searches for lower fares. Good to know that there is an actively maintained checkin script, though!!