最近公司在进行网站的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. swift的arc 是不是有问题?

    class Arctest { let name: String = "Arctest" @lazy var ret:() -> String? = { [weak self ...

  2. leetcode 104 Maximum Depth of Binary Tree(DFS)

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  3. P3515 [POI2011]Lightning Conductor[决策单调性优化]

    给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$\forall j \neq i $有$ p_i>=a_j-a_i+ \sqrt{|i-j|}$. 绝对值很烦 ,先分左右情况单 ...

  4. Btree算法的C语言实现

    btree.h //实现对order序(阶)的B-TREE结构基本操作的封装. //查找:search,插入:insert,删除:remove. //创建:create,销毁:destory,打印:p ...

  5. poj3585树最大流——换根法

    题目:http://poj.org/problem?id=3585 二次扫描与换根法,一次dfs求出以某个节点为根的相关值,再dfs遍历一遍树,根据之前的值换根取最大值为答案. 代码如下: #incl ...

  6. 解决Response输出时乱码

    Response ServletResponse – 通用的response提供了一个响应应该具有的最基本的属性和方法 | |- HttpServletResponse – 在ServletRespo ...

  7. android和iOS平台的崩溃捕获和收集

    转自:http://www.cnblogs.com/lancidie/archive/2013/04/13/3019349.html 通过崩溃捕获和收集,可以收集到已发布应用(游戏)的异常,以便开发人 ...

  8. mysql Split函数

    mysql没有split函数,这里手动写一个: ),)) BEGIN CREATE TEMPORARY TABLE IF NOT EXISTS temp_split ( col ) ); DELETE ...

  9. 如何選擇最佳的 Wi-Fi 無線網路頻道,獲得最佳的傳輸速度(转载)

    转自:https://blog.gtwang.org/useful-tools/how-to-find-the-best-wi-fi-channel-for-your-router/

  10. vim配置----YouCompleteMe配置

    YouCompleteMe是一个功能极强的自动补全插件,安装这个插件折磨了我好久,找了很多博客查看都无果,最后还是感谢stack overflow.和其它的一些插件相比,YCM能够基于语法来给出相应的 ...