最近公司在进行网站的SEO优化,将所有主要页面的URL统一更改为新的格式,其中重要的一项改变是将所有URL的标识符统一为ID,例如过去我们的一个用户的公共页面URL是这样的

https://www.example.com/user/[:username]

而更新后的格式则变成

https://www.example.com/user/[:user_id]

在看到设计文档(Design Doc)的同时,我本能就对这个这样的URL形式产生了一丝疑虑,但又说不上为什么。

我们的用户信息是存在MySQL数据库的表单中,user_id是一个整数类型的主键(Primary Key),同时也是自增(Auto Increment)字段。

从安全角度来说,使用user_id来作为标识符的URL设计并没有什么问题,但是这样会有别的问题,什么样的问题呢?

暴露商业数据!

暴露的数据1:总体用户数量

有心人如果想要知道公司现在的总体用户数量,那么很简单,只需要注册一个新用户,然后查看自己的公共主页,这样新用户的user_id就会暴露出来,而这个user_id就约等于网站现在的总体用户数量(有一部分被删除的用户除外)

暴露的数据2:用户增速

如果说暴露总量还不是最危险的,用户增速则是更加重大的信息暴露。有心人知道URL中的user_id规律之后,可以通过做很简单的实验

1. 创建一个新用户,查看URL中的用户ID。 https://www.example.com/user/1000000

2. 隔一段时间之后(一周/月),再创建一个新用户,查看URL中的用户ID。https://www.example.com/user/1005000

二者相减(1005000-1000000)就可以轻易得到这段时间内的用户增长量。甚至可以在外部用很小的代价获得非常精确的用户增长曲线。

而这样的数据,对于大部分公司来说,都是非常核心的数据,尤其在公司未上市之前,应该尽量避免此类数据外流。

这样的情况十分普遍,因为在学习Web开发的初级教程中,几乎都会将数据库主键ID用来作为URL标识符,这样从URl解析主键到后台服务使用主键查询数据库,可以非常简洁直观。但是在实际的生产环境中,这样的做法往往并不可取。

那么有什么样的方法可以避免使用数据库ID呢?

1. 使用UUID —— UUID是乱序的字符串,所以无法用来预测数据,我们可以用多种方法来设计UUID。如果你使用了MongoDB等NoSQL的存储,那么恭喜你获得了天然的UUID,每一个ObjectID都是你可以使用的UUID。如果你的数据依然离不开关系数据库,那么可以考虑在数据库中扩增字段来生成UUID并存储,同时提供基于UUID的查询接口。

2. 加密自增ID —— 在系统已经到处使用自增ID作为内部查询的关键词的情况下,往往迁移到UUID会带来很大的工程开销,并且为了支持已有的URL访问,还需要维护两套不同的逻辑。在这种情况下一种相对简便的方法是在服务器端在生成URL的时候对于ID进行加密,这样在客户端看到的便是加密后的ID。当客户端进行请求的时候,服务器端再进行解密。这样的方法看似简单,其实其中也多需要注意的地方,比如加密的秘钥一旦泄露,便失去了意义。并且有在网页端动态生成URL的需求,也有不小的挑战。

(本文的部分观点源自 https://medium.com/lightrail/prevent-business-intelligence-leaks-by-using-uuids-instead-of-database-ids-on-urls-and-in-apis-17f15669fd2e

为什么数据库ID不能作为URL中的标识符的更多相关文章

  1. cas的url中去掉jsessionid

    Servlet3.0规范中的<tracking-mode>允许你定义JSESSIONID是存储在cookie中还是URL参数中.如果会话ID存储在URL中,那么它可能会被无意的存储 在多个 ...

  2. zencart分类页产品页去掉url中的id号

    最近公司新上的网站被seo指出要修改url,去掉url中产品id.由于我们用的是zencart框架,装了 Ultimate SEO URLs 插件,所以在网上应该有这方面的资料,本文主要参考资料: 原 ...

  3. php提取淘宝URL中ID的代码

    一段可以提取淘宝URL中ID的PHP代码. 例如: <?php $taobao = 'taobao.com'; $tmall = 'tmall.com'; $guojitmall = 'tmal ...

  4. orcal数据库得连接必须用localhost,url中不要用127.0.0.1,不然无法连接

    orcal数据库得连接必须用localhost,url中不要用127.0.0.1,不然无法连接,

  5. 你不从地址栏中增加曝光量所需的数据库ID方法

    <p><span style="font-size: 18px;"></span></p> 当你想隐藏数据库id时,你能够使用 Ha ...

  6. post可以直接把get请求代入到目标url中

    Feigong --非攻 非攻 取自<秦时明月>--非攻,针对不同情况自由变化的武器 Feigong,针对各种情况自由变化的mysql注入脚本 Feigong,In view of the ...

  7. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  8. 如何获取url中的参数并传递给iframe中的报表

    在使用报表软件时,用户系统左边一般有目录树,点击报表节点就会在右侧网页的iframe中显示出报表,同时点击的时候也会传递一些参数给网页,比如时间和用户信息等.如何使网页中的报表能够获取到传递过来的参数 ...

  9. 常用数据库的驱动程序和Url地址

    常用数据库的驱动程序及JDBC URL: Oracle数据库: 驱动程序包名:ojdbc6.jar 驱动类的名字:oracle.jdbc.driver.OracleDriver JDBC URL:jd ...

随机推荐

  1. AtCoder Grand Contest #026 C - String Coloring

    Time Limit: 3 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement You are given a st ...

  2. hdu3518 Boring Counting[后缀排序]

    裸的统计不同的重复出现子串(不重叠)种数的题.多次使用后缀排序要注意小细节.y数组在重复使用时一定要清空,看那个line25 +k就明白了 ,cnt也要清空,为什么就不说了 #include<b ...

  3. P1204 [USACO1.2]挤牛奶Milking Cows

    题目描述 三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶.第一个农民在300秒(从5点开始计时)给他的牛挤奶,一直到1000秒.第二个农民在700秒开始,在 1200秒结束.第三个农民在1500秒开 ...

  4. Django | 执行项目下指定的脚本

    1 描述 有时候会碰到这样的场景,对于一些业务升级,我需要把数据库数据做些处理,同时又想以 Django 项目的环境变量执行脚本,这个时候使用 python 脚本是再适合不过的手段了. 2 使用自带的 ...

  5. Linux中的nc测试端口是否开放

    nc测试端口是否开放 在Linux中有一个级强大的网络工具netcat,在默认情况下面都是没有安装的,现在介绍一下安装过程 其实安装很简单 一.安装使用 1.只需输入命令yum安装: [root@SZ ...

  6. ExecutorService和CompletionService区别

    ExecutorService和CompletionService区别: ExecutorService:一直习惯自己维护一个list保存submit的callable task所返回的Future对 ...

  7. 使用superobject 新建Json数据(数组)

    1. 要得到的Json数据:[{"name":"张三","age": 17},{"name":"李四" ...

  8. Polygon

    用当前的笔绘制一个由两个或多个点(顶点)连接的多边形. BOOL Polygon( LPPOINT lpPoints, int nCount ); lpPoints 指向一个指定多边形顶点的点.数组中 ...

  9. FASTQ格式

    FASQT格式是用于存储生物序列(通常是核苷酸序列)及其相应的碱基质量分数的一种文本格式.为简洁起见,序列字母和质量分数均使用单个ASCII字符进行编码.最初由Wellcome Trust Sange ...

  10. OpenCPN介绍及编译

    OpenCPN介绍及编译 OpenCPN是一个航海应用软件系统,采用wxWidgets界面框架,支持OpenGL,可以跨平台运行在Windows , Linux , Mac电脑上. OpenCPN是一 ...