Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse Engineer Mobile API #42

Open
pyro2927 opened this issue Jun 19, 2019 · 14 comments
Open

Reverse Engineer Mobile API #42

pyro2927 opened this issue Jun 19, 2019 · 14 comments

Comments

@pyro2927
Copy link
Owner

@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
Copy link
Owner Author

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
Copy link

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
Copy link

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:

xur17/southwest-alerts#16

@Fffrank
Copy link

Fffrank commented Aug 28, 2019

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
Copy link

@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
Copy link

Fffrank commented Jun 18, 2020

@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
Copy link

@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
Copy link

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
Copy link

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

@chuxuanhy
Copy link

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

@Fffrank
Copy link

Fffrank commented Jun 17, 2021

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
Copy link

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
Copy link

@Fffrank @mkitchingh thank you!

@Fffrank
Copy link

Fffrank commented Jun 18, 2021

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!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants
@pyro2927 @Fffrank @sephamorr @chuxuanhy @maximedevalland @hoopsbwc34 @mkitchingh and others