Introduction

You can do some powerful things with Bing Maps and the Geospatial modules that come with the API and supporting services.

This exercise is a warning to anyone who uses services similar to eBay, Craigslist, Gumtree, or even dating/hookup sites. 

Some websites still do not take enough care to hide your actual home/account address.

There are many legitimate reasons a person may want to offer a service. A cleaner for example, or a mobile hairdresser. They may not want to give their personal home address to anyone on the Internet. Many sites just show a seller's stated location. However, they still have to register with the website using their full personal address - for billing and accounts.

Even if you hide address specifics, as shown below, some sites still calculated distance based on your exact postcode! 

So, you may still be found through that old radar technique of triangulation!

Some sites think it's enough to round your distance up to a wider margin, like "within 5 miles" or "20-30" miles.

Sounds like a big enough area to get lost in right? Wrong!!

On some sites I tested, multiple searches from gradually moving locations, found the exact point at which "20-30" changes down to "10-20", or up to "30-40". 

If the search feature is badly written, that is the point you can say the user is exactly 20 or 30 miles away (depending which way you were moving) - within a mile. In fact down to a quarter mile, in the example below!

Of course, that is still somewhere on the circumference path of a 30-mile radius circle. That's  C = 2*π*R  of course. In other words a path 188.5 square miles long!

That is when you need further search hits from other angles.

With multiple search rings, these searches combine to reveal an intersection area of all searches.

This intersection pinpoints the individual or item down to a very small area. 

I tested quite a few times and this is often scarily accurate.

I was looking for examples where moving my account address to an adjacent postcode made the triangulation point also move.

Sometimes I was able to pinpoint remote locations, or a postcode area representing half of one side of a short street. 

Try for yourself.

No web server is needed.

Just a file editor, a browser, and a some JavaScript basics.

Add a map to a web page

This can be any HTML file, even one on your desktop.

Depending on how you serve the data, Bing Maps API doesn't need a server, just a browser to execute the web page in.

<div class="map-wrapper">
 <div id='myMap'></div>
</div>
  
<script>
 var map;
 function loadMapScenario() {
 map = new Microsoft.Maps.Map(document.getElementById('myMap'),
 {
 allowHidingLabelsOfRoad: true,
 });
 }
</script>
<script type='text/javascript'
 async defer></script>

Links at the end of this article will get you started.

I'll skip the basics as this isn't just a 101 on using Bing Maps.

This is more of a vulnerability analysis - using shapes and triangulation made so easy by the Bing Maps API, the map, and its awesome modules.

Plotting circles and donuts

Generating circles on maps used to be quite painful, as system.drawing was not really geared for longitude and latitudes.

You'd need to create a big enough drawing object and you'd need to multiply your location into an integer, then divide back down after.

But with Microsoft.Maps.SpatialMath Javascript library, everything gets simple again.

Below is the code to add a simple regular polygon with 36 sides, which nicely presents a circular-looking polygon:

Microsoft.Maps.loadModule("Microsoft.Maps.SpatialMath", function () {
 var path = Microsoft.Maps.SpatialMath.getRegularPolygon(_loc, RadiusMeters, 36, Microsoft.Maps.SpatialMath.Meters);
 var outerPoly = new Microsoft.Maps.Polygon(path,
 {
 fillColor: 'rgba(0, 0, 0, 0.5)',
 strokeColor: 'black',
 strokeThickness: 0.5
 });
 map.entities.push(outerPoly);
}

If your search result has a minumum/maximum figure, for example, "20-30", then you need to carve out a hole in your polygon.

This is achieved by calling the Microsoft.Maps.SpatialMath.Geometry.difference function, which returns the bit from the first shape which is NOT in the second shape.

if (_search.MinDistance == 0 || (_search.MinDistance - margin <= 0)) {
 // Push as solid circle
 sysCirclesLayer.add(outerPoly);
 triCanvasArray.push(outerPoly);
}
else {
 // Push as donut
 var holeRad = _search.MinDistance - margin;
 path = Microsoft.Maps.SpatialMath.getRegularPolygon(_loc, ((holeRad) * 1609.34), 36, Microsoft.Maps.SpatialMath.Meters);
 var innerPoly = new Microsoft.Maps.Polygon(path);
 var donut = Microsoft.Maps.SpatialMath.Geometry.difference(outerPoly, innerPoly);
 sysCirclesLayer.add(donut);
 triCanvasArray.push(donut);
}

Intersecting shapes to find the common area

Once you've built up a collection of circles or donuts, you can push them each, through a base green rectangle, leaving just the shared areas:

Microsoft.Maps.loadModule("Microsoft.Maps.SpatialMath", function () {
 var bnds = Microsoft.Maps.SpatialMath.Geometry.bounds(triCanvasArray);
 var cent = Microsoft.Maps.SpatialMath.Geometry.centroid(triCanvasArray);
 var halfWidth = bnds.width / 2;
 var halfHeight = bnds.height / 2;
 var bndAry = [
 new Microsoft.Maps.Location(cent.latitude - halfHeight, cent.longitude - halfWidth),
 new Microsoft.Maps.Location(cent.latitude - halfHeight, cent.longitude + halfWidth),
 new Microsoft.Maps.Location(cent.latitude + halfHeight, cent.longitude + halfWidth),
 new Microsoft.Maps.Location(cent.latitude + halfHeight, cent.longitude - halfWidth),
 new Microsoft.Maps.Location(cent.latitude - halfHeight, cent.longitude - halfWidth),
 ];
 var rect = new Microsoft.Maps.Polygon(bndAry,
 {
 fillColor: 'rgba(0, 255, 0, 0.5)'
 });
 
 for (var a = 0; a < triCanvasArray.length; a++) {
 var newRect = Microsoft.Maps.SpatialMath.Geometry.intersection(rect, triCanvasArray[a]);
 rect = newRect;
 }
 spatMathTriLayer.add(rect);
 
 var tLoc = new Microsoft.Maps.Location(cent.latitude, cent.longitude)
 var tPin = new Microsoft.Maps.Pushpin(tLoc, { 'draggable': false, 'color': 'green', 'text': 'O' });
 spatMathTriLayer.add(tPin);
});

Gumtree Seller Triangulation Example

There are also many positive uses for this...

Tracking down stolen items on auction sites, for example.

I wouldn't recommend visiting the home or workplace of a seller to reclaim your items, who themselves may have just bought it from someone at a car boot sale!

However, it is often enough evidence for local police to pay the seller a visit and potentially recover matching forensics, a concrete lead, or indeed your stolen property! 

I've chosen an example advert from Gumtree (free classifieds ads website) to show you. I picked this one simply because it advertises its postcode location - so we can confirm the triangulation results.

Above showing at 2 miles from the searched postcode.

This [now old] advert is by a company called "Ford Wimbledon", whose address is this map location shown.

The search tool allows you to specify a full postcode to query from.

Results are down to a quarter mile.

 Further searches narrow the location down to a small area, which you can even visit in street view.

Zooming in close, you see how small an area it carves out, down to quarter-mile accuracy:

Switching to aerial view confirms the same rooftop/postcode as the advertising company.

I then tested this on quite a few popular sites that have distance search features. 

In this example below, I set the profile address as East London. 

However, search results still used the 'supposedly private' account postcode for search queries.

I set the profile location as East London (blue box) but search results pinpointed the account location at "TN2X 1SL", which was the privately registered address.

I tried shifting the account postcode to the next address one mile away, and the triangulation also shifted. 

This showed that it was querying on the exact postcode location, rather than the stated minimum five-mile accuracy.

The green area is the intersection of all three searches, using Bing Maps API Spatial.Math modules.

The green dot is just the 'centroid' of the shape if all three searches were combined into one shape.

The red circle is the accuracy circle round a point calculated using the "age-old" method of intersecting shapes - using the system.drawing namespace and a graphics object.

So it's nice to see both green area and red circle match.

The solution - Binning

The solution to triangulation (as old as the mathematical technique itself) is termed binning, which is a form of statistical quantization.

Locations are grouped into one shared "box" and are queried on as a whole, by the middle of that box. This is a technique we can also employ with the visual tools on our Bing map, with Bing Map API Data Binning.

Binning allows you to group all the postcodes from an area and report back a common and consistent center (centroid) for them all. As shown in the last image, the green dot represents the centroid of the boundary of the shape, which represents all the other shapes combined together.

This was clearly being done by about half the sites I tested and since by most that I contacted. 

Please test your own favorite services and let them know if you find this "vulnerability".

Summary

In conclusion, some services I tested did not properly protect its users from this most basic form of location pinpointing. 

Long before posting this, I contacted the worst offenders.

To be fair, most were quick to act.

In the worst case I found, the "who's online now" widget of a "mental health support" website allowed me to triangulate the "closest support worker in your area" to the address of a farm. When I called the helpline to tell them, they confirmed they were indeed registered as a user on the site at that address - which of course should have been private to their account.

There are no doubt a great many smaller sites, which fall foul of this and I hope you'll join me, keeping an eye out for this.

This highlights how even these days, a naïve implementation of a common website feature can put potentially vulnerable users at risk.

See also

Other Languages