深度解析塑造未来的技术文章。

你的健身App,其实是一种监控工具

健身App(如Strava)如何泄露敏感位置数据,从军事基地到航母,以及开发者必须吸取的OPSEC教训。

航母在海上航行,甲板上绘有一条发光的红色跑步路线

一家法国报纸近期利用健身App上公开的数据,追踪了法国唯一一艘航母戴高乐号的实时位置。这艘航母是欧洲最具战略敏感性的军事资产之一。船员们在飞行甲板上跑圈,Strava忠实地记录下每一步。任何知道去哪里看的人,都能看到这艘舰船的位置、航向和航速。

这不是黑客攻击。没有人利用漏洞,也没有人绕过安全控制。数据本身默认就是公开的,而用户主动分享了它们,却没意识到自己的晨跑路线会暴露一艘核动力战舰的部署规律。2018年,Strava的全球热力图把阿富汗和叙利亚的跑步路线点亮,暴露了一批秘密军事基地,属于同一类问题。教训至今没有吸取。

“无害”数据的问题

单看健身App的位置数据,似乎人畜无害。你跑了步,骑车上班,在泳池里游了几圈。但把时间拉长、数据汇总起来,就能看出绝非无害的规律。

  • 住址和工作地点。你最常见的起点和终点,几乎肯定就是你的家和办公室。只要应用记录了你的跑步路线,即使你从未主动提供过这些信息,它也知道你住哪、在哪上班。
  • 日常作息。每个工作日早上6点跑步?数据就显示了你家什么时候没人。周二常出差?你的缺席规律也被记录下来了。
  • 敏感地点。军人、情报人员、政府雇员、企业高管,凡是在敏感场所工作或出入的人,都会留下足迹。哪怕只在一个涉密设施里跑过一次步,也足以说明这个设施的存在,以及你有权进入它。
  • 社交关系。结伴跑步、共享路线和路段排行榜,暴露了谁和谁一起锻炼。在情报语境下,这足以描绘出敏感设施工作人员的社交网络。

航母案例很戏剧化,但同样的原理也适用于普通人。跟踪狂可以借健身App数据找到受害者;窃贼能判断哪些住宅没人;雇主可能监控员工下班后的行踪。这些数据颗粒度细、信息量大,而且很多时候,注册一个免费账号就能看到。

数据是如何泄露的

健身App通过多种渠道泄露位置数据,有些很明显,有些则隐藏得很深。

公开的活动主页

很多应用默认使用公开主页。你的跑步、骑行和游泳记录,任何人都能看到,连同GPS轨迹一起标在地图上。Strava的默认设置这些年有所改进,但许多用户是在默认设置更宽松时注册的,之后再也没有回头检查过。在Strava上随便搜一下军事基地、数据中心或政府大楼附近的活动,往往能看到比应有的多得多的信息。

热力图与聚合数据

即便单个活动是私密的,汇总数据依然可能暴露敏感规律。Strava的全球热力图(显示所有记录活动的密度)曾经清晰勾勒出冲突地区前沿作战基地的平面布局。这些基地在空旷的沙漠中呈现为明亮的活动热点。单个用户是匿名的,但整体模式却一目了然。

路段排行榜

Strava路段是用户自定义的一段道路或小径,大家在这里比拼最快用时,它会形成长期存在的位置标记。航母飞行甲板上的一个路段,就能识别出所有跑过这条路线的用户。即使个人主页是私密的,路段排行榜仍然会显示用户名、用时和日期。再与其他公开信息交叉比对,就可能锁定具体的人。

API访问与数据经纪商

健身App常常通过API、合作伙伴关系和数据经纪商与第三方共享数据。即使你把主页设为私密,你的数据仍可能流向保险公司、广告商或数据聚合商,并与其他数据集合并。健身App的位置数据已经出现在商业数据库中,并被售卖给执法机构、情报机构和私家侦探。

写给普通开发者的OPSEC经验

如果你在开发处理位置数据的应用,或者任何可能暴露敏感规律的数据应用,健身App的这些失败提供了切实的教训。

默认私密

这点听起来显而易见,但多数健身App多年来都没做到,原因是公开主页能带动互动和增长。如果你的应用会收集位置数据,默认值应当是私密,由用户主动选择分享。不是“默认公开,隐私选项藏在设置深处”,而是真正的默认私密。

// Bad: default to public, user must opt out
const userSettings = {
profileVisibility: 'public',
activityVisibility: 'public',
showOnHeatmap: true,
shareWithPartners: true
};
// Good: default to private, user must opt in
const userSettings = {
profileVisibility: 'private',
activityVisibility: 'private',
showOnHeatmap: false,
shareWithPartners: false
};
// Better: explain what each setting actually means
const privacySettings = {
profileVisibility: {
value: 'private',
description: 'Only people you approve can see your profile',
riskLevel: 'Your name and activity history are visible'
},
activityVisibility: {
value: 'private',
description: 'Only you can see your activities',
riskLevel: 'GPS routes show where you live, work, and travel'
}
};

实施隐私区域

Strava最终增加了“隐私区域”功能,即在敏感地点周围隐藏GPS数据。这是个好功能,但来得晚了好几年。如果你的应用记录位置数据,就应该让用户自定义一些区域,在其中停止记录或对数据做模糊处理。大多数用户会把这些区域设在家和工作地点周围,这样就消除了最敏感的规律。

实现细节:如果路线具有辨识度,仅仅对起点和终点加上随机偏移是不够的。每天跑同一条5公里环线的人,即使端点被遮住,路线形状依然很容易辨认。更好的做法是:裁掉路线首尾各N米,或者把端点吸附到网格上,防止精确推断位置。

警惕聚合攻击

单个数据点可能无害,但聚合后的模式未必如此。当你构建跨用户组合或可视化数据的功能时,比如热力图、排行榜、热门地点,就要想想会浮现出什么规律。一张热力图如果勾勒出了一处秘密设施,那就是一次聚合攻击,即便没有任何单个用户的数据被直接暴露。

应对办法是:为聚合设定最低阈值(某区域唯一用户数少于N时不显示热力数据),排除敏感地理区域,并在发布前审查可视化结果,看看有没有意外的规律泄露。差分隐私技术(对聚合查询加入经过校准的噪声)也有帮助,只是要正确实现并不简单。

审计你的数据共享

每一个提供位置数据的API端点、每一个数据导出功能、每一个第三方集成,都可能成为敏感数据泄露的渠道。梳理你的数据流,弄清楚用户位置数据去了哪里、谁能访问、在什么条件下访问。如果你要与合作伙伴或广告商共享数据,请向用户明确说明共享了什么、分享给了谁。

更大的图景:数据最小化

根本问题在于,你的应用是否真的需要它所收集的数据。跑步App需要每秒一次的GPS坐标吗?如果要做路线可视化,确实需要。计算距离和配速,较低的精度就够了。估算卡路里,你只需要总距离和海拔变化。

数据最小化,即只收集特定功能所需的数据,是防止数据泄露的最有力保护。你不收集的数据,就不会被泄露、被传唤、被出售,也不会被聚合成监控模式。这与“先收集一切,以后再想用途”的增长思维相冲突,但它是唯一真正稳健的做法。

保护用户数据的最好方式,不是更好的加密,也不是更严格的访问控制,而是从一开始就不持有这些数据。

健身App行业是吃过苦头才学到这一课的,但仍有一些公司没有学会。军人依然在航母上使用Strava,情报人员依然在涉密设施附近记录跑步。数据仍在流向服务器、API和数据经纪商,他们能拼凑出任何用户都无意暴露的规律。作为开发者,我们既可以构建默认保护用户免受这些风险的系统,也可以利用用户的疏忽来构建系统。航母上的船员打开跑步App时,并没有做出任何安全决策;几年前,做出决策的是应用的开发者,他们选择了默认设置。