Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

Commit

Permalink
X-Forwarded-For can contain multiple IP addresses
Browse files Browse the repository at this point in the history
From the nginx docs:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
> $proxy_add_x_forwarded_for
> the “X-Forwarded-For” client request header field with the $remote_addr
> variable appended to it, separated by a comma. If the “X-Forwarded-For”
> field is not present in the client request header, the
> $proxy_add_x_forwarded_for variable is equal to the $remote_addr
> variable.

Use the last IP address in X-Forwarded-For. For this to work properly
behind a trusted proxy, you must be using ProxyFix as described in the
flask & werkzeug documentation.
  • Loading branch information
fuhrysteve authored and Stephen J. Fuhry committed Dec 29, 2014
1 parent c7d0ea9 commit 923ad72
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ env/

*.db
*cache*

# vim
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
3 changes: 2 additions & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ Feature Flags
option. Defaults to ``False``.
``SECURITY_TRACKABLE`` Specifies if Flask-Security should track basic user
login statistics. If set to ``True``, ensure your
models have the required fields/attribues. Defaults to
models have the required fields/attribues. Be sure to
use `ProxyFix <http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#proxy-setups>` if you are using a proxy. Defaults to
``False``
``SECURITY_PASSWORDLESS`` Specifies if Flask-Security should enable the
passwordless login feature. If set to ``True``, users
Expand Down
6 changes: 3 additions & 3 deletions flask_security/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ def login_user(user, remember=None):
return False

if _security.trackable:
if 'X-Forwarded-For' not in request.headers:
remote_addr = request.remote_addr or 'untrackable'
if 'X-Forwarded-For' in request.headers:
remote_addr = request.headers.getlist("X-Forwarded-For")[0].rpartition(' ')[-1]
else:
remote_addr = request.headers.getlist("X-Forwarded-For")[0]
remote_addr = request.remote_addr or 'untrackable'

old_current_login, new_current_login = user.current_login_at, datetime.utcnow()
old_current_ip, new_current_ip = user.current_login_ip, remote_addr
Expand Down
16 changes: 16 additions & 0 deletions tests/test_trackable.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ def test_trackable_flag(app, client):
assert user.last_login_ip == 'untrackable'
assert user.current_login_ip == '127.0.0.1'
assert user.login_count == 2


def test_trackable_with_multiple_ips_in_headers(app, client):
e = 'matt@lp.com'
authenticate(client, email=e)
logout(client)
authenticate(client, email=e, headers={
'X-Forwarded-For': '99.99.99.99, 88.88.88.88'})

with app.app_context():
user = app.security.datastore.find_user(email=e)
assert user.last_login_at is not None
assert user.current_login_at is not None
assert user.last_login_ip == 'untrackable'
assert user.current_login_ip == '88.88.88.88'
assert user.login_count == 2

0 comments on commit 923ad72

Please sign in to comment.