diff --git a/db.sqlite3 b/db.sqlite3
index a471fcc..c02e629 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/pixels/migrations/0002_requests_region.py b/pixels/migrations/0002_requests_region.py
new file mode 100644
index 0000000..2f21430
--- /dev/null
+++ b/pixels/migrations/0002_requests_region.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.2.3 on 2019-07-07 21:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pixels', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='requests',
+ name='region',
+ field=models.CharField(default='', max_length=200),
+ preserve_default=False,
+ ),
+ ]
diff --git a/pixels/migrations/0003_auto_20190707_2211.py b/pixels/migrations/0003_auto_20190707_2211.py
new file mode 100644
index 0000000..632ae81
--- /dev/null
+++ b/pixels/migrations/0003_auto_20190707_2211.py
@@ -0,0 +1,31 @@
+# Generated by Django 2.2.3 on 2019-07-07 22:11
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pixels', '0002_requests_region'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='requests',
+ name='client',
+ field=models.CharField(default='', max_length=200),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='requests',
+ name='device',
+ field=models.CharField(default='', max_length=200),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='requests',
+ name='os',
+ field=models.CharField(default='', max_length=200),
+ preserve_default=False,
+ ),
+ ]
diff --git a/pixels/models.py b/pixels/models.py
index 3a4d0d0..27de641 100644
--- a/pixels/models.py
+++ b/pixels/models.py
@@ -6,6 +6,10 @@ class Requests(models.Model):
username = models.CharField(max_length=200)
time_opened = models.DateTimeField('time opened')
isp = models.CharField(max_length=200)
+ client = models.CharField(max_length=200)
+ os = models.CharField(max_length=200)
+ device = models.CharField(max_length=200)
+ region = models.CharField(max_length=200)
city = models.CharField(max_length=200)
country_name = models.CharField(max_length=200)
latitude = models.CharField(max_length=200)
diff --git a/pixels/templates/index.html b/pixels/templates/index.html
index 3a42403..037b69a 100644
--- a/pixels/templates/index.html
+++ b/pixels/templates/index.html
@@ -23,6 +23,13 @@
How supertracker works
By hitting that server, you are revealing the device, location, and time you are opening that email
Supertracker lets anyone make their own tracking pixel and then see everywhere that pixel has been accessed from
+ How to prevent yourself from being tracked
+
+ - Use an email client that does proxy image loading so your location isn't revealed since they load the image onto their own server before sending it to you
+
+ - Disable remote image loading in your email client. Here's a guide for GMail (link)
+ - And the real permanent solution is to demand that your email clients immediately load all external images the moment the email is received rather than opened, so none of your information by using email. For example I believe this is the head of GMail and could implement this feature (link)
+
Choose your Pixel and Username!
diff --git a/pixels/templates/pixel.html b/pixels/templates/pixel.html
index 962b868..f1b0e45 100644
--- a/pixels/templates/pixel.html
+++ b/pixels/templates/pixel.html
@@ -9,11 +9,12 @@ @{{ username }} pixel
-
-
How to use your pixel
+
+
How to pixel
- Copy and paste the image below by right clicking below this text and selecting copy image
- - Paste the image into your email and send it off the email
+ - This will only work on desktop
+ - Paste the image into your email and send off the email
@@ -21,22 +22,26 @@
How to use your pixel
image is in the space above
-
+
Where your pixel has been
Time Opened |
Device |
+ OS |
+ Client |
Country |
City |
Latitude |
Longitude |
GMaps link |
- {% for request in requests %}
+ {% for request in requests reversed %}
- 3:00pm |
- iPhone |
+ {{ request.time_opened.timestamp }} |
+ {{ request.device }} |
+ {{ request.os }} |
+ {{ request.client }} |
{{ request.country_name }} |
{{ request.city }} |
{{ request.latitude }} |
@@ -51,7 +56,11 @@ Where your pixel has been<
{% endblock %}
\ No newline at end of file
diff --git a/pixels/views.py b/pixels/views.py
index d1e95b8..6d7874b 100644
--- a/pixels/views.py
+++ b/pixels/views.py
@@ -3,11 +3,13 @@
from django.shortcuts import render
from django.utils import timezone
+
from pixels.models import Requests
import requests
import logging
-import xmltodict
+import json
+from ua_parser import user_agent_parser
logger = logging.getLogger('pixels')
@@ -35,44 +37,71 @@ def show_image(request):
# logger.error(ip)
# logger.error("AFTER")
- ipstack_url = "http://api.geoiplookup.net/?query=" + ip
+ # if you are trying to shut me down, this is one of the more vulnerable parts, just fire off enough requests here:
+ ipdata_url = "https://api.ipdata.co/"+ip+"?api-key=2426c12568210a843d3ac8e14d9933764e73f0d8e84fc92834314a58"
# logger.error("IP URL")
# logger.error(ipstack_url)
- ip_info = requests.get(ipstack_url)
-
- json_info = xmltodict.parse(ip_info.content)
-
+ ip_info = requests.get(ipdata_url)
+ ip_content = json.loads(ip_info.content)
# logger.error("IP INFO")
- logger.error(json_info)
+ logger.error(ip_content)
+
+ logger.error("META")
+ logger.error(request.META)
+
+ client = ''
+ os = ''
+ device = ''
+
+ if 'HTTP_USER_AGENT' in request.META.keys():
+ ua_string = request.META['HTTP_USER_AGENT']
+ parsed_string = user_agent_parser.Parse(ua_string)
+ logger.error("PARSED USER AGENT")
+ logger.error(parsed_string)
+ if 'user_agent' in parsed_string.keys():
+ agent_data = parsed_string['user_agent']
+ if 'family' in agent_data.keys():
+ client = agent_data['family']
+
+ if 'os' in parsed_string.keys():
+ os_data = parsed_string['os']
+ if 'family' in os_data.keys():
+ os = os_data['family']
+
+ if 'device' in parsed_string.keys():
+ device_data = parsed_string['device']
+ if 'family' in device_data.keys():
+ device = device_data['family']
# get all the info VERY inefficiently
- if 'ip' in json_info.keys():
- ip = json_info['ip']
- if 'results' in ip.keys():
- results = ip['results']
- if 'result' in results.keys():
- result = results['result']
- if 'countryname' in result.keys():
- countryname = result['countryname']
- else:
- countryname = ''
- if 'city' in result.keys():
- city = result['city']
- else:
- city = ''
- if 'latitude' in result.keys():
- latitude = result['latitude']
- else:
- latitude = ''
- if 'longitude' in result.keys():
- longitude = result['longitude']
- else:
- longitude = ''
- if 'isp' in result.keys():
- isp = result['isp']
- else:
- isp = ''
+
+ if 'ip' in ip_content.keys():
+ result = ip_content
+ if 'region' in result.keys():
+ region = result['region']
+ else:
+ region = ''
+ if 'country_name' in result.keys():
+ country_name = result['country_name']
+ else:
+ country_name = ''
+ if 'city' in result.keys():
+ city = result['city']
+ else:
+ city = ''
+ if 'latitude' in result.keys():
+ latitude = result['latitude']
+ else:
+ latitude = ''
+ if 'longitude' in result.keys():
+ longitude = result['longitude']
+ else:
+ longitude = ''
+ if 'organisation' in result.keys():
+ isp = result['organisation']
+ else:
+ isp = ''
# logger.error(request.META['HTTP_USER_AGENT'])
# logger.error(request.META['HTTP_X_FORWARDED_FOR'])
@@ -82,7 +111,7 @@ def show_image(request):
pixel = request.GET.get('pixel','')
# STORE THE REQUEST INFO
- r = Requests(username=username, isp=isp, city=city, country_name=countryname, latitude=latitude, longitude=longitude, time_opened=timezone.now())
+ r = Requests(username=username, isp=isp, client=client, os=os, device=device, city=city, region=region, country_name=country_name, latitude=latitude, longitude=longitude, time_opened=timezone.now())
r.save()
if pixel == 'pikachu':
diff --git a/requirements.txt b/requirements.txt
index 12bb43a..133bf30 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
requests
-xmltodict
\ No newline at end of file
+json
+ua-parser
\ No newline at end of file
diff --git a/supertracker/settings.py b/supertracker/settings.py
index b371101..f48902d 100644
--- a/supertracker/settings.py
+++ b/supertracker/settings.py
@@ -52,6 +52,8 @@
ROOT_URLCONF = 'supertracker.urls'
+USE_TZ = True
+
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',