Using .access_route instead of .remote_addr to take into account HTTP_X_FORWARDED_FOR header (#636)

master
Lucas Cimon 4 years ago committed by GitHub
parent 04d138dc77
commit f70eaf315a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -74,6 +74,10 @@ In chronological order:
* Lucas Cimon @Lucas-C * Lucas Cimon @Lucas-C
* Added the possibility to define CORS origins through ISSO_CORS_ORIGIN environment variable * Added the possibility to define CORS origins through ISSO_CORS_ORIGIN environment variable
* Fix a bug with <a> in <svg> * Fix a bug with <a> in <svg>
* Fixing likes counter of replies not being displayed
* Adding contrib/dump_comments.py
* Adding a [server] proxy-fix-enable-x-prefix configuration option
* Using .access_route instead of .remote_addr to take into account HTTP_X_FORWARDED_FOR header
* Yuchen Pei @ycpei * Yuchen Pei @ycpei
* Fix link in moderation emails when isso is installed in a sub URL * Fix link in moderation emails when isso is installed in a sub URL

@ -190,6 +190,13 @@ profile
show 10 most time consuming function in Isso after each request. Do show 10 most time consuming function in Isso after each request. Do
not use in production. not use in production.
trusted-proxies
an optional list of reverse proxies IPs behind which you have deployed
your Isso web service (e.g. `127.0.0.1`).
This allow for proper remote address resolution based on a
`X-Forwarded-For` HTTP header, which is important for the mechanism
forbiding several comment votes coming from the same subnet.
.. _configure-smtp: .. _configure-smtp:
SMTP SMTP

@ -140,6 +140,7 @@ class API(object):
self.moderated = isso.conf.getboolean("moderation", "enabled") self.moderated = isso.conf.getboolean("moderation", "enabled")
# this is similar to the wordpress setting "Comment author must have a previously approved comment" # this is similar to the wordpress setting "Comment author must have a previously approved comment"
self.approve_if_email_previously_approved = isso.conf.getboolean("moderation", "approve-if-email-previously-approved") self.approve_if_email_previously_approved = isso.conf.getboolean("moderation", "approve-if-email-previously-approved")
self.trusted_proxies = list(isso.conf.getiter("server", "trusted-proxies"))
self.guard = isso.db.guard self.guard = isso.db.guard
self.threads = isso.db.threads self.threads = isso.db.threads
@ -275,7 +276,7 @@ class API(object):
data["website"] = normalize(data["website"]) data["website"] = normalize(data["website"])
data['mode'] = 2 if self.moderated else 1 data['mode'] = 2 if self.moderated else 1
data['remote_addr'] = utils.anonymize(str(request.remote_addr)) data['remote_addr'] = self._remote_addr(request)
with self.isso.lock: with self.isso.lock:
if uri not in self.threads: if uri not in self.threads:
@ -336,6 +337,21 @@ class API(object):
resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"])) resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
return resp return resp
def _remote_addr(self, request):
"""Return the anonymized IP address of the requester.
Takes into consideration a potential X-Forwarded-For HTTP header
if a necessary server.trusted-proxies configuration entry is set.
Recipe source: https://stackoverflow.com/a/22936947/636849
"""
remote_addr = request.remote_addr
if self.trusted_proxies:
route = request.access_route + [remote_addr]
remote_addr = next((addr for addr in reversed(route)
if addr not in self.trusted_proxies), remote_addr)
return utils.anonymize(str(remote_addr))
""" """
@api {get} /id/:id view @api {get} /id/:id view
@apiGroup Comment @apiGroup Comment
@ -890,8 +906,7 @@ class API(object):
@xhr @xhr
def like(self, environ, request, id): def like(self, environ, request, id):
nv = self.comments.vote( nv = self.comments.vote(True, id, self._remote_addr(request))
True, id, utils.anonymize(str(request.remote_addr)))
return JSON(nv, 200) return JSON(nv, 200)
""" """
@ -917,8 +932,7 @@ class API(object):
@xhr @xhr
def dislike(self, environ, request, id): def dislike(self, environ, request, id):
nv = self.comments.vote( nv = self.comments.vote(False, id, self._remote_addr(request))
False, id, utils.anonymize(str(request.remote_addr)))
return JSON(nv, 200) return JSON(nv, 200)
# TODO: remove someday (replaced by :func:`counts`) # TODO: remove someday (replaced by :func:`counts`)

@ -112,6 +112,13 @@ reload = off
# in production. # in production.
profile = off profile = off
# an optional list of reverse proxies IPs behind which you have deployed
# your Isso web service (e.g. `127.0.0.1`).
# This allow for proper remote address resolution based on a
# `X-Forwarded-For` HTTP header, which is important for the mechanism
# forbiding several comment votes coming from the same subnet.
trusted-proxies =
[smtp] [smtp]
# Isso can notify you on new comments via SMTP. In the email notification, you # Isso can notify you on new comments via SMTP. In the email notification, you

Loading…
Cancel
Save