forked from OWASP-BLT/BLT
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add ability to block ip addresses that are submitting spam OWASP-BLT#…
- Loading branch information
1 parent
01fbaa7
commit 06708ef
Showing
6 changed files
with
206 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from django.utils.deprecation import MiddlewareMixin | ||
from user_agents import parse | ||
|
||
from website.models import IP | ||
|
||
|
||
class MonitorIPMiddleware(MiddlewareMixin): | ||
def process_request(self, request): | ||
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR") | ||
if x_forwarded_for: | ||
ip = x_forwarded_for.split(",")[0].strip() | ||
else: | ||
ip = request.META.get("REMOTE_ADDR") | ||
|
||
user_agent = request.META.get("HTTP_USER_AGENT", "") | ||
parsed_agent = parse(user_agent) | ||
|
||
if ip: | ||
ip_record = IP.objects.filter(address=ip).first() | ||
|
||
if ip_record: | ||
ip_record.user_agent_string = parsed_agent | ||
ip_record.count += 1 | ||
ip_record.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import ipaddress | ||
|
||
from django.core.cache import cache | ||
from django.http import HttpResponseForbidden | ||
from user_agents import parse | ||
|
||
from website.models import BlockedIP | ||
|
||
|
||
class IPRestrictMiddleware: | ||
""" | ||
Middleware to restrict access based on client IP addresses. | ||
""" | ||
|
||
def __init__(self, get_response): | ||
self.get_response = get_response | ||
|
||
def blocked_ips(self): | ||
blocked_ips = cache.get("blocked_ips") | ||
if blocked_ips is None: | ||
blocked_addresses = BlockedIP.objects.values_list("address", flat=True) | ||
blocked_ips = set(blocked_addresses) | ||
cache.set("blocked_ips", blocked_ips, timeout=86400) | ||
return blocked_ips | ||
|
||
def blocked_ip_ranges(self): | ||
blocked_ip_ranges = cache.get("blocked_ip_ranges") | ||
if blocked_ip_ranges is None: | ||
blocked_ip_start = BlockedIP.objects.values_list("address_range_start", flat=True) | ||
blocked_ip_end = BlockedIP.objects.values_list("address_range_end", flat=True) | ||
blocked_ip_ranges = list(zip(blocked_ip_start, blocked_ip_end)) | ||
cache.set("blocked_ip_ranges", blocked_ip_ranges, timeout=86400) | ||
return blocked_ip_ranges | ||
|
||
def ip_in_range(self, ip, ip_ranges): | ||
ip_int = int(ipaddress.IPv4Address(ip)) | ||
for start, end in ip_ranges: | ||
start_int = int(ipaddress.IPv4Address(start)) | ||
end_int = int(ipaddress.IPv4Address(end)) | ||
if start_int <= ip_int <= end_int: | ||
return True | ||
return False | ||
|
||
def blocked_agents(self): | ||
blocked_agents = cache.get("blocked_agents") | ||
if blocked_agents is None: | ||
blocked_user_agents = BlockedIP.objects.values_list("user_agent_string", flat=True) | ||
blocked_agents = set(blocked_user_agents) | ||
cache.set("blocked_agents", blocked_agents, timeout=86400) | ||
return blocked_agents | ||
|
||
def __call__(self, request): | ||
ip = request.META.get("REMOTE_ADDR") | ||
user_agent = request.META.get("HTTP_USER_AGENT", "") | ||
parsed_agent = parse(user_agent) | ||
|
||
if ip: | ||
if ip in self.blocked_ips(): | ||
return HttpResponseForbidden( | ||
"Your IP address is restricted from accessing this site." | ||
) | ||
blocked_ip_ranges = self.blocked_ip_ranges() | ||
if self.ip_in_range(ip, blocked_ip_ranges): | ||
return HttpResponseForbidden( | ||
"Your IP address is restricted from accessing this site." | ||
) | ||
if parsed_agent and parsed_agent in self.blocked_agents(): | ||
return HttpResponseForbidden("Your IP address is restricted from accessing this site.") | ||
|
||
return self.get_response(request) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Generated by Django 5.1 on 2024-08-09 19:59 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("website", "0124_company_tags_domain_tags_project_tags_and_more"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="BlockedIP", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("address", models.GenericIPAddressField(blank=True, null=True)), | ||
( | ||
"reason_for_block", | ||
models.TextField(blank=True, max_length=255, null=True), | ||
), | ||
( | ||
"address_range_start", | ||
models.GenericIPAddressField(blank=True, null=True), | ||
), | ||
( | ||
"address_range_end", | ||
models.GenericIPAddressField(blank=True, null=True), | ||
), | ||
( | ||
"user_agent_string", | ||
models.CharField(blank=True, default="", max_length=255, null=True), | ||
), | ||
("count", models.IntegerField(default=1)), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters