Reputation: 308
I have a react-native app that's sending a POST request for user login to a Flask-based web application behind an nginx server proxy.
This is the login code:
async function signInPost(csrf, email, password, data) {
let reqBody = {
email,
password,
confirm: password
}
const url = dispatchEndpoint(host, "signin")
const resp = await request.post(url, reqBody, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrf,
}
});
const respBody = resp.data;
if (respBody.status === 'success') {
return Promise.resolve(data);
}
if (respBody.hasOwnProperty('flash')) {
return Promise.reject(new Error(respBody.flash))
}
if (respBody.hasOwnProperty('form') && respBody.form.hasOwnProperty('errors')) {
let es = extractErrors(respBody.form.errors)
return Promise.reject(new Error(es))
}
}
From the iOS version of the app, the request is arriving to the webapp normally (I blanked the actual values of the credentials):
POST request: http://127.0.0.1:5000/account/signin?response_format=json
Cookie: session=.eJxFzM0KgkAQAOBXiTl3CHUvggdjVfawI8LWMnMRKssd-4EKIsV3z1vfA3wTtOEE6QSrA6Rgq31Ab74UsaAue6wKhZIr1jZhMQm5RtFoP-xNBvMajq_nuX0_hu7-L6S8ousDShPbkW-1p5gdCjuKa51HXPHS7hKSrWDEA-piQ5ds6eYf7H0rzg.DhhP-A.v57cBRLglqzc6jhAr77bz_nBs0A
X-Csrftoken: 1530317960.89##2b9b575ddb01994c9350770e93533192d6435bfb
Content-Length: 84
User-Agent: Globalme/1 CFNetwork/901.1 Darwin/17.6.0
Connection: close
Host: 127.0.0.1:5000
Accept: application/json
Accept-Language: en-us
Content-Type: application/json
Accept-Encoding: br, gzip, deflate
Body:
password:-------
email:--------
confirm:------
Body FULL:
MultiDict([(u'password', u'------'), (u'email', u'------'), (u'confirm', u'-----')])
However, when I try to login from the Android version of the app, I get an empty request body:
POST request: http://127.0.0.1:5000/account/signin?response_format=json
Cookie: session=.eJw9zN0KgjAUAOBXiXPdRciuBC8CdSw4RyZbst0I_bE2LahgOvHd66rvAb4F-vsF8gU2J8iBOh0xUUBlXaMCw07OxKtox4pRaoPxIaHCmUpRwLqF8_t16z_PcH38C9NpRrwe7CgjZeSa8hgsNxNxEa0XO-PbAZOeSNXOJJkwOzjaF79u_QKH-S4O.DhhTsw.Uykv39nl_1AwTaDc-HzP_l0y3bY
X-Csrftoken: 1530318915.4##0031a56bb2a1440dc05343e8ae59ebd043be765e
Content-Length: 85
User-Agent: okhttp/3.6.0
Connection: close
Host: 127.0.0.1:5000
Accept: application/json
Content-Type: application/json;charset=utf-8
Accept-Encoding: gzip
Body:
Body FULL:
ImmutableMultiDict([])
The Content-Length almost matches in both POST requests, so I have a suspicion that this is some security issue with nginx, or some other problem on the server.
Note that both apps are still in development mode. They're not signed.
Thank you for any help provided.
UPDATE: I just enhanced the Nginx log formatting to include the request body, and the Android version of the body IS SHOWING:
64.180.189.138 - - [30/Jun/2018:02:02:58 +0000] "POST /account/signin?response_format=json HTTP/1.1" 200 496 "-" "okhttp/3.6.0" "-""{\x22email\x22:\[email protected]\x22,\x22password\x22:\x22----\x22,\x22confirm\x22:\x22----\x22}" "645" [-]
Is it possible that Nginx may "sanitize" the body after logging? Or is this definitely something to do with my Flask-based web application?
Upvotes: 1
Views: 590
Reputation: 308
The server side code was indeed the culprit. Somewhere in the request processing, it was accepting strictly "application/json"
iOS was sending that Content-Type header exactly, but Android was sending "application/json;charset=utf-8"
I fixed the issue on the server side and that solved it.
Upvotes: 1