Profiling Jodel™ users with image (meta)data
"Jodel instantly connects you with the people around you. It's a live social feed of your community's hottest news, questions, events, stories, and jokes."
how jodel works
Users can can start discussion threads by posting a so called "jodel" which consists of a text message or an image.
Others within a 10km radius can comment on it as well with text or image content.
Within every thread a commenting user gets assigned a ascending number (starting from 0 - OP gets 0 by default) that won't change for all his comments and is publicly visible.
This way you can mention someone specific and don't loose track of who says what. Quite practical because comments are in a flat hierarchy and not threaded.
In a single thread users are thereby pseudonymous though across the overall app they are anonymous to everyone else.
Users of the app like this advantage of anonymity to express
themselves in a much more open way and share personal, intimate and often embarrassing content.
I'm interested to see if users can nonetheless be somehow tracked and profiled across threads.
If possible this would break the basic assumption held by all users that content is only strictly coupled to the thread it was
posted in and in no way connected to other threads.
There are a few ways one could start exploring such an attack e.g. analyzing language, words and phrases used, posting time patterns, content patterns, triangulation of positions (the app shows terms like "far", "near" or "here" to indicate distance of others related to your own position) or maybe even behavioral habits.
I decide to look into the uploaded photos by users for now. Jodel does not allow to choose from the gallery when sharing but only taken directly from the camera.
First I need to get my hands on some images.
off-topic
This can be done by intercepting the network traffic to see the payloads
the app and the jodel server exchange.
Like many services jodel uses and http api that feeds the app with information
to display.
Taking that approach you will have to ssl unpin the app first.
Another way would be to act like an fake client and get the payloads this way.
I start by downloading some random image I know exists.
% domain="http://img.jodel.com/"
% file="5b9466bfec02b67c7e09889e_ChrvVB8OpM9c1Ubr_image.jpeg"
% curl -O "$domain$file"
And run the exiv2 command to look for interesting exif tags.
% exiv2 5b9466bfec02b67c7e09889e_ChrvVB8OpM9c1Ubr_image.jpeg
File name : 5b9466bfec02b67c7e09889e_ChrvVB8OpM9c1Ubr_image.jpeg
File size : 107092 Bytes
MIME type : image/jpeg
Image size : 640 x 1100
Camera make :
Camera model :
Image timestamp :
Image number :
Exposure time :
Aperture :
Exposure bias :
Flash :
Flash bias :
Focal length :
Subject distance:
ISO speed :
Exposure mode :
Metering mode :
Macro mode :
Image quality :
Exif Resolution : 1080 x 1857
White balance :
Thumbnail : None
Copyright :
Exif comment :
Is there anything that could indicate that there is
some uniqueness within one users image metadata that possibly is common across all his uploads?
In theory there are many tags that could make a more or less unique profile.
Just to make sure I run another program, identify of the imagemagick tool suite.
% identify -format "%[EXIF:*]" $file
exif:DateTime=2018:09:09 02:17:55
exif:ExifOffset=94
exif:ImageLength=1857
exif:ImageWidth=1080
exif:LightSource=0
exif:Orientation=0
The tags lightsource and orientation pop up. It looks like there is some discrepancy
between tools when it comes to extracting exif tags from files.
First insight. There is definitely meta information in those images.
I run another tool named exif.
% exif $file
EXIF tags in '5b9466bfec02b67c7e09889e_ChrvVB8OpM9c1Ubr_image.jpeg'
('Motorola' byte order):
--------------------+-------------------------------
Tag |Value
--------------------+-------------------------------
Image Width |1080
Image Length |1857
Orientation |Unknown value 0
Date and Time |2018:09:09 02:17:55
X-Resolution |72
Y-Resolution |72
Resolution Unit |Inch
Corrupt data
The data provided does not follow the specification.
ExifEntry: The tag 'LightSource' contains data of an
invalid format ('Long', expected 'Short').
Light Source |%
Again new tags appear. X-resolution, y-resolution and resolution unit.
I get another random image to compare the tags.
% file1="5b9465620364771c9b10f371_d4hHV76HTg78qcKK_image.jpeg"
% file2="5c300e17197bf2002352e3d5_HvM993OoqjyEKBn2_image.jpeg"
% vimdiff <(identify -format "%[EXIF:*]" $file1) \
<(identify -format "%[EXIF:*]" $file2)
There a visual diff.
Second insight. Different files different tags.
Jodel is not removing any or at least not all meta information
from user uploads.
It is also very intresting that even the image sizes (dimensions) are different.
% identify -format '%w %h\n' $file1 $file2
640 1095
640 1136
These two values are not metadata but fundamental information about the image itself.
I fetch two of my own uploads to jodel and compare exif tags once again.
Other than the DateTime they are the same. I do some more sampling with images
I can reliable assign to specific users and recognize
every one of them has the same exif tags overall his uploads.
The same can be said about image dimensions.
Third insight. A user has identical tags plus width and height on all his uploads.
The question arises how unique are these exif tags and dimension combinations.
I suspect these are identical for phone models. But maybe os version, app version
or even os settings?
Instead of searching for the origin why these exif profiles differ
I decide to find how many unique tag combinations there are.
This is run after a download of many more images from my area.
% identify -format "%[EXIF:*]" *.jpeg \
| grep -v "DateTime" \
| cut -d"=" -f1 \
| sort \
| uniq -c \
| sort -n
3 exif:SceneCaptureType
6 exif:InteroperabilityIndex
19 exif:InteroperabilityOffset
19 exif:thumbnail:InteroperabilityIndex
19 exif:thumbnail:InteroperabilityVersion
99 exif:thumbnail:JPEGInterchangeFormat
99 exif:thumbnail:JPEGInterchangeFormatLength
380 exif:JPEGInterchangeFormat
380 exif:JPEGInterchangeFormatLength
498 exif:MeteringMode
6148 exif:ColorSpace
6148 exif:PixelXDimension
6148 exif:PixelYDimension
6148 exif:ResolutionUnit
6148 exif:XResolution
6148 exif:YResolution
9112 exif:ImageWidth
9118 exif:ImageLength
9211 exif:LightSource
15359 exif:ExifOffset
15359 exif:Orientation
Not too many tags actually. But some tags are rare others like
orientation occur all over the place.
Here the same stats for image dimensions width and height which again are not part
of the exif data.
% identify -format "%w %h\n" *.jpeg \
| sort \
| uniq -c \
| sort -n \
1 542 1136
1 621 1136
1 640 1051
1 640 1096
1 640 1105
1 640 1134
1 640 647
1 640 666
1 640 698
1 640 923
2 617 1136
2 624 1136
2 640 1012
2 640 1013
2 640 1030
2 640 1036
2 640 1038
2 640 541
2 640 567
2 640 569
3 575 1136
3 640 1032
3 640 1088
3 640 606
3 640 630
4 640 1027
4 640 1042
4 640 1099
4 640 1106
4 640 1132
5 574 1136
5 640 1091
5 640 1104
6 558 1136
6 634 1136
6 640 1040
6 640 1101
7 577 1136
8 640 1097
9 583 1136
9 588 1136
9 599 1136
12 626 1136
13 592 1136
13 640 1018
14 625 1136
17 585 1136
17 622 1136
20 606 1136
29 633 1136
36 640 1017
37 640 1016
43 602 1136
45 631 1136
48 640 1026
53 635 1136
60 572 1136
65 640 1102
77 616 1136
78 640 960
83 640 1007
85 618 1136
87 568 1136
88 586 1136
96 640 1019
135 640 1008
154 596 1136
212 640 1093
224 569 1136
231 640 1029
269 571 1136
342 623 1136
353 612 1136
455 640 1100
463 604 1136
488 640 1010
539 640 1020
710 525 1136
1240 640 1031
1428 640 1136
3046 640 1095
3935 639 1136
82 rows of output therefore 82 unique width height combinations.
More precisely that means of all 15359 images I got my hands on only 5 (0.03%) have the dimensions 574 width and 1136 height.
If my assumptions so far are correct this is either the same person or different users with super
rare width height values.
Compare that to width 639 height 1136 which 25.6% of all images have.
To make my life easier when investigating all the images I write a small program that iterates
over every image and stores its exif data, width and height into an sqlite database.
The final table layout looks like this.
CREATE TABLE images(
...
width INTEGER,
height INTEGER,
exif JSON
);
Let's check the exif data for those 5 images (0.03%) mentioned above.
sqlite> select json_remove(exif,"$.DateTime") from images
...> where width = 574 and height = 1136;
{"ImageWidth":1080,"ImageHeight":2138,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
{"ImageWidth":1080,"ImageHeight":2138,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
{"ImageWidth":1080,"ImageHeight":2138,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
{"ImageWidth":1080,"ImageHeight":2138,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
{"ImageWidth":1080,"ImageHeight":2139,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
{"ImageWidth":1080,"ImageHeight":2139,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
The query reveals that the first 5 images have a different exif ImageHeight then
the last two respectively 2138 and 2139.
Judging by what the images actually show - early in the morning walk home after new years eve party, beer, beer and inside wall of an restaurant
- I think this is one and the same person.
The last two images just show #foodporn. This must be someone else.
NEWSFLASH I later contacted the beer guy and he was kind enough to confirm my guess.
All ImageHeight 2138 were his uploads but not the 1239 ones.
His phone is an Xiaomi Mi 8 and according to him not very popular in Europe.
Correlating the images of this guy was easy. His group was very small.
This would not have been possible with the combination of width 639 and height 1136 because there are
3935 other images that have the same sizes. There are probably many separate users within this group
that all have the same popular phone, OS or settings. It's also possible some huge groups form because
of power users with many uploads but I doubt that.
The goal should be to increase the number of groups that way the images per group go down.
Therefore the next step is to check for unique exif tag combinations.
The first number shows how many times the exact combination of the exif metadata was counted.
sqlite> select count(*) as c,
json_remove(exif, "$.DateTime")
from images group by json_remove(exif, "$.DateTime")
order by c;
1|{"ExifIFDPointer":94,"ImageHeight":406,"Orientation":0,"ImageWidth":480,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1092,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1140,"ImageWidth":720,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1144,"ImageWidth":720,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1178,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1296,"ImageWidth":720,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1836,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1851,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1854,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1855,"ImageWidth":1080,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2272,"ImageWidth":1440,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":638,"ImageWidth":720,"SubExif":{"LightSource":0}}
1|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":762,"ImageWidth":480,"SubExif":{"LightSource":0}}
1|{"ImageHeight":1230}
1|{"ImageHeight":1845,"Orientation":0,"ImageWidth":1080,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"ImageHeight":406,"Orientation":0,"ImageWidth":480,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"ImageHeight":562,"Orientation":0,"ImageWidth":540,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"ImageWidth":1080,"ImageHeight":1748,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":1911,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":1918,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":1937,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":1966,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":1977,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":2088,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":2156,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1080,"ImageHeight":2265,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1440,"ImageHeight":2478,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1440,"ImageHeight":2580,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1440,"ImageHeight":2582,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":1440,"ImageHeight":2672,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"ImageWidth":720,"ImageHeight":1291,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
1|{"LightSource":0,"Orientation":0,"ImageHeight":1136,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"LightSource":0,"Orientation":0,"ImageHeight":1704,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"LightSource":0,"Orientation":0,"ImageHeight":1857,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"LightSource":0,"Orientation":0,"ImageHeight":816,"MeteringMode":65535,"ImageWidth":480,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
1|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":640,"PixelYDimension":1096}}
2|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1134,"ImageWidth":720,"SubExif":{"LightSource":0}}
2|{"ImageWidth":1440,"ImageHeight":2784,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
2|{"LightSource":0,"Orientation":0,"ImageHeight":1138,"SceneCaptureType":0,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":130,"SubExif":{"JPEGInterchangeFormat":160,"JPEGInterchangeFormatLength":0}}
2|{"LightSource":0,"Orientation":0,"ImageHeight":960,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
3|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1023,"ImageWidth":1080,"SubExif":{"LightSource":0}}
3|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1063,"ImageWidth":1080,"SubExif":{"LightSource":0}}
3|{"ImageHeight":2296}
3|{"ImageWidth":1080,"ImageHeight":1742,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":1080,"ImageHeight":2134,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":1080,"ImageHeight":2145,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":1080,"ImageHeight":2200,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":1440,"ImageHeight":2614,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":720,"ImageHeight":1296,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":720,"ImageHeight":1308,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"ImageWidth":720,"ImageHeight":1354,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
3|{"LightSource":0,"Orientation":0,"ImageHeight":1740,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
3|{"LightSource":0,"Orientation":0,"ImageHeight":1848,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
4|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1244,"ImageWidth":720,"SubExif":{"LightSource":0}}
4|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1336,"ImageWidth":720,"SubExif":{"LightSource":0}}
4|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1733,"ImageWidth":1080,"SubExif":{"LightSource":0}}
4|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2296,"ImageWidth":1440,"SubExif":{"LightSource":0}}
4|{"ImageWidth":1080,"ImageHeight":1984,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
4|{"ImageWidth":1080,"ImageHeight":2138,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
4|{"ImageWidth":1080,"ImageHeight":2146,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
5|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1932,"ImageWidth":1080,"SubExif":{"LightSource":0}}
5|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1968,"ImageWidth":1080,"SubExif":{"LightSource":0}}
5|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2478,"ImageWidth":1440,"SubExif":{"LightSource":0}}
5|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2864,"ImageWidth":1440,"SubExif":{"LightSource":0}}
5|{"LightSource":0,"Orientation":0,"ImageHeight":1160,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
5|{"LightSource":0,"Orientation":0,"ImageHeight":818,"MeteringMode":65535,"ImageWidth":480,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
5|{"Orientation":1,"XResolution":[0],"YResolution":[0],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":1242,"PixelYDimension":2208}}
5|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":750,"PixelYDimension":1624}}
6|{"ExifIFDPointer":94,"ImageHeight":762,"Orientation":0,"ImageWidth":480,"SubExif":{"LightSource":0}}
6|{"ImageWidth":1080,"ImageHeight":1737,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
6|{"ImageWidth":1440,"ImageHeight":2876,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
6|{"ImageWidth":720,"ImageHeight":1440,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
7|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2469,"ImageWidth":1440,"SubExif":{"LightSource":0}}
7|{"ImageHeight":762,"Orientation":0,"ImageWidth":480,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
7|{"ImageWidth":1080,"ImageHeight":1860,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
7|{"ImageWidth":1080,"ImageHeight":2128,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
7|{"ImageWidth":1440,"ImageHeight":2576,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
8|{"ImageHeight":922,"Orientation":0,"ImageWidth":540,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
8|{"ImageWidth":1080,"ImageHeight":1960,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
8|{"ImageWidth":720,"ImageHeight":1148,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
8|{"LightSource":0,"Orientation":0,"ImageHeight":2296,"MeteringMode":65535,"ImageWidth":1440,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
8|{"LightSource":0,"Orientation":0,"ImageHeight":764,"MeteringMode":65535,"ImageWidth":480,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
8|{"Orientation":1,"XResolution":[216],"YResolution":[216],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":1242,"PixelYDimension":2688}}
9|{"ImageWidth":1080,"ImageHeight":2103,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
10|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1145,"ImageWidth":720,"SubExif":{"LightSource":0}}
10|{"ImageWidth":1080,"ImageHeight":1964,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
11|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1860,"ImageWidth":1080,"SubExif":{"LightSource":0}}
11|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2148,"ImageWidth":1080,"SubExif":{"LightSource":0}}
12|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":924,"ImageWidth":540,"SubExif":{"LightSource":0}}
12|{"LightSource":0,"Orientation":0,"ImageHeight":1134,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
13|{"ImageWidth":1080,"ImageHeight":2074,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
13|{"LightSource":0,"Orientation":0,"ImageHeight":1860,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
13|{"Orientation":1,"XResolution":[216],"YResolution":[216],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":1125,"PixelYDimension":2001}}
14|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2576,"ImageWidth":1440,"SubExif":{"LightSource":0}}
15|{"ImageHeight":1230,"Orientation":0,"ImageWidth":720,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
15|{"ImageWidth":1080,"ImageHeight":1971,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
16|{"ImageWidth":1080,"ImageHeight":1859,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
16|{"ImageWidth":1080,"ImageHeight":2097,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
18|{"ImageHeight":762,"Orientation":0,"ImageWidth":480,"ExifIFDPointer":94,"SubExif":{"LightSource":0,"MeteringMode":65535,"InteroperabilityIFDPointer":136}}
19|{"ImageWidth":1080,"ImageHeight":1932,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
20|{"ImageWidth":1080,"ImageHeight":2026,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
20|{"LightSource":0,"Orientation":0,"ImageHeight":1701,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
21|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2031,"ImageWidth":1080,"SubExif":{"LightSource":0}}
23|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1716,"ImageWidth":1080,"SubExif":{"LightSource":0}}
23|{"LightSource":0,"Orientation":0,"ImageHeight":922,"MeteringMode":65535,"ImageWidth":540,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
24|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1701,"ImageWidth":1080,"SubExif":{"LightSource":0}}
27|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1230,"ImageWidth":720,"SubExif":{"LightSource":0}}
27|{"ImageWidth":720,"ImageHeight":1432,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
28|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1432,"ImageWidth":720,"SubExif":{"LightSource":0}}
28|{"ImageWidth":1080,"ImageHeight":1939,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
29|{"LightSource":0,"Orientation":0,"ImageHeight":1845,"MeteringMode":65535,"ImageWidth":1080,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
30|{"ImageWidth":1080,"ImageHeight":2037,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
31|{"ImageWidth":1080,"ImageHeight":1720,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
33|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1845,"ImageWidth":1080,"SubExif":{"LightSource":0}}
37|{"ImageWidth":1440,"ImageHeight":2864,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
37|{"LightSource":0,"Orientation":0,"ImageHeight":1230,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
37|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":828,"PixelYDimension":1792}}
38|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2157,"ImageWidth":1080,"SubExif":{"LightSource":0}}
38|{"ImageWidth":1080,"ImageHeight":1731,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
38|{"LightSource":0,"Orientation":0,"ImageHeight":1232,"MeteringMode":65535,"ImageWidth":720,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
39|{"ImageWidth":1080,"ImageHeight":1944,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
42|{"ImageWidth":720,"ImageHeight":1336,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
44|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":764,"ImageWidth":480,"SubExif":{"LightSource":0}}
44|{"ImageWidth":720,"ImageHeight":1232,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
45|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2004,"ImageWidth":1080,"SubExif":{"LightSource":0}}
49|{"ImageWidth":720,"ImageHeight":1136,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
53|{"ImageWidth":1440,"ImageHeight":2858,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
62|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2476,"ImageWidth":1440,"SubExif":{"LightSource":0}}
64|{"ImageHeight":1701,"Orientation":0,"ImageWidth":1080,"LightSource":0,"MeteringMode":65535,"ExifIFDPointer":118,"SubExif":{"JPEGInterchangeFormat":148,"JPEGInterchangeFormatLength":0}}
71|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2708,"ImageWidth":1440,"SubExif":{"LightSource":0}}
74|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1238,"ImageWidth":720,"SubExif":{"LightSource":0}}
76|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1136,"ImageWidth":720,"SubExif":{"LightSource":0}}
76|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1328,"ImageWidth":720,"SubExif":{"LightSource":0}}
76|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":640,"PixelYDimension":960}}
80|{"ImageWidth":1080,"ImageHeight":1704,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
80|{"ImageWidth":1080,"ImageHeight":2159,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
81|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1984,"ImageWidth":1080,"SubExif":{"LightSource":0}}
88|{"ImageWidth":1080,"ImageHeight":2094,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
93|{"Orientation":0,"ExifIFDPointer":70,"SubExif":{"MeteringMode":65535,"LightSource":0}}
98|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1857,"ImageWidth":1080,"SubExif":{"LightSource":0}}
114|{}
132|{"ImageWidth":1440,"ImageHeight":2464,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
137|{"ImageWidth":1440,"ImageHeight":2708,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
141|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1704,"ImageWidth":1080,"SubExif":{"LightSource":0}}
142|{"ImageWidth":1080,"ImageHeight":2060,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
143|{"Orientation":1,"XResolution":[0],"YResolution":[0],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":640,"PixelYDimension":1136}}
145|{"ImageWidth":1080,"ImageHeight":2148,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
152|{"ImageWidth":1080,"ImageHeight":1857,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
167|{"ImageWidth":1080,"ImageHeight":2157,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
198|{"ImageWidth":1080,"ImageHeight":1722,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
201|{"ImageWidth":1080,"ImageHeight":2004,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
202|{"ImageWidth":1080,"ImageHeight":2031,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
222|{"ImageWidth":1080,"ImageHeight":1736,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
260|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1722,"ImageWidth":1080,"SubExif":{"LightSource":0}}
280|{"Orientation":1,"XResolution":[0],"YResolution":[0],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":750,"PixelYDimension":1334}}
318|{"ImageWidth":1080,"ImageHeight":1968,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
328|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1160,"ImageWidth":720,"SubExif":{"LightSource":0}}
396|{"Orientation":1,"XResolution":[216],"YResolution":[216],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":1242,"PixelYDimension":2208}}
447|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":2464,"ImageWidth":1440,"SubExif":{"LightSource":0}}
476|{"ImageWidth":1080,"ImageHeight":1848,"ExifIFDPointer":94,"Orientation":0,"SubExif":{"LightSource":0}}
508|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1848,"ImageWidth":1080,"SubExif":{"LightSource":0}}
575|{"Orientation":1,"XResolution":[216],"YResolution":[216],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":1125,"PixelYDimension":2436}}
757|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1740,"ImageWidth":1080,"SubExif":{"LightSource":0}}
873|{"ExifIFDPointer":94,"Orientation":0,"ImageHeight":1232,"ImageWidth":720,"SubExif":{"LightSource":0}}
1048|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":640,"PixelYDimension":1136}}
2379|{"Orientation":1,"XResolution":[144],"YResolution":[144],"ResolutionUnit":2,"ExifIFDPointer":90,"SubExif":{"ColorSpace":1,"PixelXDimension":750,"PixelYDimension":1334}}
That is a total of 166 rows that sqlite returns.
A nice increase in groups.
How much more will it be if I combine exif and width and height?
sqlite> select count(*) from (
select * from images
group by json_remove(exif, "$.DateTime"), width, height
);
173
Just a small jump in group count.
Fourth insight. There are 173 unique combinations of exif, width and height in my area
So what does this mean for a users anonymity and untraceable content across threads?
It all comes down to how rare your smartphone is. If you fall into huge
group you are probably safe. Just by looking at meta data it will be hard
to identify which images are yours.
In case you decided to go with an unusual phone you run danger your images can
be grouped into a profile by an outside analyst.
The rarer your phone the higher is the risk falling victim to a successful profiling.
*that graph ist just for the lulz
If you ask me, I would say every user that falls into a group which consists
of less than 20 images is under the highest risk. It wouldn't be hard to
go over that many images and assign them manually to a person either by just looking at
them or doing covert interrogation of the poster.
sqlite> select count(*) from (
select count(*) as c
from images
group by json_remove(exif, "$.DateTime")
) where c < 20;
100
These are at minimum 100 users in my area from which all the probed images are.
I cannot say what percentage of overall users within my town are affected
because there is not really a way to know for an outsider how many users the app has.
What I can tell is there are on average 3000 user interactions (comments or posts) daily.
The highest count of unique users commenting a post was 109 in recent times.
Only 5.2 unique users interact with a post on average by creating 10.7 comments.
Other than throwing your phone away and getting a popular iPhone to hide
in the masses there is not much one
can do. Jodel needs to change the app so their camera implementation does
not set exif tags or immediately delete them.
As well they can simply strip all meta data from the images after uploading.
If that would happen their still would be 82 - some big and some frightening small - groups to categorize an upload.
And this all by just looking at the width and height of the image itself.
I have no idea how it is that some images have such uncommon dimension. Is it
the camera unit itself or some strange cropping logic of the Jodel app?
If you know more. Tweet at me :)