Skip to content

Refactor get_ip_address to avoid 500 errors#4614

Merged
mauromsl merged 4 commits into
openlibhums:masterfrom
sissamedialab:bugfix/issue-1248-refactor-get-ip-address
Feb 14, 2025
Merged

Refactor get_ip_address to avoid 500 errors#4614
mauromsl merged 4 commits into
openlibhums:masterfrom
sissamedialab:bugfix/issue-1248-refactor-get-ip-address

Conversation

@yakky

@yakky yakky commented Feb 11, 2025

Copy link
Copy Markdown
Collaborator

This refactoring aims to prevent 500 errors when the HTTP_X_FORWARDED_FOR and REMOTE_ADDR headers are manipulated by potentially malicious users and do not contain a valid IP address.

For example, the following request could cause such an issue:
wget "http://<domain>/article/pubid/<pubid>/" -O /dev/null --header="X-Forwarded-For: some-random-text,1.2.3.4"

Models changes

The LoginAttempt.ip_address field needs to be updated to allow None values. This is necessary because if the get_ip_address method returns None, we need to be able to save None when there are failed login attempts with invalid or manipulated headers.

The same applies to the Contact.client_ip field, which is set in journal.views.contact using new_contact.client_ip = shared.get_ip_address(request). Without this change, an error will occur if the IP address is None.

Although it's highly unlikely that ipware will ever return None, actually Its get_client_ip method can return None values.

Code changes

We also need to handle TypeError in the get_iso_country_code method, as geoip2.database.Reader().country will fail if the IP address is None. It seems appropriate to modify this method to return None, as its output is used by iso_to_country_object, which already returns None if the corresponding Country object is not found among the registered Countries.

@yakky

yakky commented Feb 11, 2025

Copy link
Copy Markdown
Collaborator Author

Original code by @LorenzoGrama

@mauromsl mauromsl self-requested a review February 11, 2025 14:48
@mauromsl mauromsl self-assigned this Feb 11, 2025
@mauromsl mauromsl added this to the v1.8.0 Tracker milestone Feb 11, 2025

@mauromsl mauromsl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @yakky (and @LorenzoGrama) , good catch!

I just made a comment regarding LoginAttempt.ip_address being now nullable, which I think we do not need. thoughts?

Comment thread src/core/models.py Outdated

class LoginAttempt(models.Model):
ip_address = models.GenericIPAddressField()
ip_address = models.GenericIPAddressField(blank=True, null=True)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it even worth registering a login attempt if we do not have an IP address?

As this model is only used to count the number of failed attempts from a given IP, we might use the python logger as INFO for correlation but ignore the write to db

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree. Should I add something like the following?

def add_failed_login_attempt(request):
    user_agent, ip_address = get_ua_and_ip(request)
    if ip_address:
        models.LoginAttempt.objects.create(user_agent=user_agent, ip_address=ip_address)

Or we risk IntegrityError in the unlikely case that ip is None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please, and thanks

@mauromsl mauromsl assigned yakky and unassigned mauromsl Feb 11, 2025
@mauromsl mauromsl added bug Something's not working security labels Feb 11, 2025
@ajrbyers ajrbyers assigned mauromsl and unassigned yakky Feb 12, 2025
@mauromsl mauromsl merged commit f65be83 into openlibhums:master Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something's not working security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants