Search code examples
pythonnginxflaskpycryptopbkdf2

TypeError happens with Nginx but not with Flask Server


I am running an api behind flask in python and connections are handled through nginx and uwsgi.

Some of the api routes use pycrypto but am getting errors when using nginx on port 80 regarding this line in the pycrypto source.

The full traceback is:

Traceback (most recent call last):
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask_cors/extension.py", line 188, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./application.py", line 113, in new_user
    decrypted_json = crypt.decrypt_json(encrypted)
  File "./crypto_module/crypt.py", line 201, in decrypt_json
    decrypted_text = cryptor.decrypt(data_to_decrypt, PASSWORD)
  File "./crypto_module/crypt.py", line 112, in decrypt
    encryption_key = self._pbkdf2(password, encryption_salt, iterations=iterations)
  File "./crypto_module/crypt.py", line 184, in _pbkdf2
    return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations, prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/Crypto/Protocol/KDF.py", line 110, in PBKDF2
    password = tobytes(password)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/Crypto/Util/py3compat.py", line 85, in tobytes
    return ''.join(s)
TypeError

The TypeError is never specifically mentioned for some reason. The error also does not show when running the server with the basic python application.py command on the default port 5000. When letting nginx and uwsgi handle the connections, I get the Internal Server Error shown above. Not really sure what's happening. All other non-crypto routes go through fine.

Update: running the server one level up in uwsgi with the following command will also work. Nginx still does not:

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi 

Update 2: Now getting another TypeError that's a little more descriptive but I still think the data being sent in the request is not being handled the same way/correctly with nginx as it is with uwsgi or flask.

...
  File "./crypto_module/crypt.py", line 202, in <lambda>
    return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations, prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
  File "/usr/lib/python2.7/hmac.py", line 133, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib/python2.7/hmac.py", line 68, in __init__
    if len(key) > blocksize:
TypeError: object of type 'NoneType' has no len()

I should also note that crypt.py is RNCryptor-python


Solution

  • Got it working.

    In /etc/nginx/sites-enabled/test

    uwsgi_pass unix:/...;
    

    Should be

    uwsgi_pass unix:///...;
    

    The original error also stemmed from the password used in the crypto file. The password was retrieved from the system's environment variables. I later found out that Nginx doesn't come with any functionality to natively use environment variables but a workaround is explained here.