Browse Source

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

FREEZE-blogpost-2021-01-19
Lucas Cimon 1 year ago
committed by GitHub
parent
commit
f70eaf315a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CONTRIBUTORS.txt
  2. 7
      docs/docs/configuration/server.rst
  3. 24
      isso/views/comments.py
  4. 7
      share/isso.conf

4
CONTRIBUTORS.txt

@ -74,6 +74,10 @@ In chronological order:
* Lucas Cimon @Lucas-C
* Added the possibility to define CORS origins through ISSO_CORS_ORIGIN environment variable
* 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
* Fix link in moderation emails when isso is installed in a sub URL

7
docs/docs/configuration/server.rst

@ -190,6 +190,13 @@ profile
show 10 most time consuming function in Isso after each request. Do
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:
SMTP

24
isso/views/comments.py

@ -140,6 +140,7 @@ class API(object):
self.moderated = isso.conf.getboolean("moderation", "enabled")
# 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.trusted_proxies = list(isso.conf.getiter("server", "trusted-proxies"))
self.guard = isso.db.guard
self.threads = isso.db.threads
@ -275,7 +276,7 @@ class API(object):
data["website"] = normalize(data["website"])
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:
if uri not in self.threads:
@ -336,6 +337,21 @@ class API(object):
resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"]))
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
@apiGroup Comment
@ -890,8 +906,7 @@ class API(object):
@xhr
def like(self, environ, request, id):
nv = self.comments.vote(
True, id, utils.anonymize(str(request.remote_addr)))
nv = self.comments.vote(True, id, self._remote_addr(request))
return JSON(nv, 200)
"""
@ -917,8 +932,7 @@ class API(object):
@xhr
def dislike(self, environ, request, id):
nv = self.comments.vote(
False, id, utils.anonymize(str(request.remote_addr)))
nv = self.comments.vote(False, id, self._remote_addr(request))
return JSON(nv, 200)
# TODO: remove someday (replaced by :func:`counts`)

7
share/isso.conf

@ -112,6 +112,13 @@ reload = off
# in production.
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]
# Isso can notify you on new comments via SMTP. In the email notification, you

Loading…
Cancel
Save