V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hi20151215x
V2EX  ›  信息安全

请教各位下 将用户的 id 在 jwt 中 算是敏感信息么?

  •  
  •   hi20151215x · 2022-12-02 09:45:25 +08:00 · 6975 次点击
    这是一个创建于 757 天前的主题,其中的信息可能已经有所发展或是发生改变。

    程序是通过解析 jwt 中的用户 userId , 进行查询的

    
    select * from orders where ownerid = #userId
    
    

    但是看网上说 不建议将敏感信息 放入 jwt 中, 现在我有点迷惑 这个 userId 到底算不算敏感信息?

    说敏感吧,毕竟有 sha256+secret key 加密。 说不敏感吧,如果换成别的 userId ,就可以查询其他用户的信息。

    61 条回复    2022-12-03 13:08:07 +08:00
    leonme
        1
    leonme  
       2022-12-02 09:53:21 +08:00 via iPhone
    userId 很多网站直接露出,你说算敏感信息吗?
    geelaw
        2
    geelaw  
       2022-12-02 09:57:03 +08:00 via iPhone   ❤️ 9
    > 说敏感吧,毕竟有 sha256+secret key 加密。 说不敏感吧,如果换成别的 userId ,就可以查询其他用户的信息。

    我不知道从何吐槽起了。
    dddd1919
        3
    dddd1919  
       2022-12-02 09:59:10 +08:00
    如果 id 作为数据表主键或功能外键之类的内部功能字段,建议不要放入 jwt ,除非信息需要展示给用户,否则完全没必要放入
    gbw1992
        4
    gbw1992  
       2022-12-02 09:59:53 +08:00
    一般情况下都这么干
    我个人觉得 userid 也是拿用户名和和密码换的,不是用户信息不算是敏感。
    orangie
        5
    orangie  
       2022-12-02 10:02:43 +08:00   ❤️ 2
    如果不放心,专门设计一个 jwtId ,也做成全局唯一,限制其用途只用来通过 JWT 查找真正的 userId?
    sheeta
        6
    sheeta  
       2022-12-02 10:04:14 +08:00
    如#5 所说,redis 映射一个 jwtId => userId 的关系
    tool2d
        7
    tool2d  
       2022-12-02 10:10:53 +08:00
    肯定不能用 userId 啊,你看看大厂的用户 oauth API ,全部都是转换成 access token 令牌访问的。
    swulling
        8
    swulling  
       2022-12-02 10:13:10 +08:00 via iPhone   ❤️ 4
    userid 不敏感,但是你们有接口可以允许通过 userid 查询其他人的信息,这个是错误的。没权限控制么?
    hoopan
        9
    hoopan  
       2022-12-02 10:28:36 +08:00
    不是敏感,userid 没啥特殊含义
    Jooooooooo
        10
    Jooooooooo  
       2022-12-02 10:33:39 +08:00
    "如果换成别的 userId ,就可以查询其他用户的信息"

    这是典型的越权. 你再多搜搜
    vopin
        11
    vopin  
       2022-12-02 10:35:00 +08:00
    > 如果换成别的 userId ,就可以查询其他用户的信息
    不是有签名吗?内容更换了校验是不成功的呀。
    mayday526
        12
    mayday526  
       2022-12-02 10:37:12 +08:00
    @Jooooooooo 越什么权,用户手动修改 jwt 中的 userid ,这个 jwt 就不会认证通过,除非用户知道该系统 jwt 的加密方式
    radiocontroller
        13
    radiocontroller  
       2022-12-02 10:37:45 +08:00
    如果换成别的 userId ,就可以查询其他用户的信息。

    前提是加密加签要正确,才能生成正确的 jwt token ,那谁又能拿到你的私钥去做这个事呢
    fuchish112
        14
    fuchish112  
       2022-12-02 10:38:23 +08:00
    看业务咯,大多数业务是不敏感的
    mayday526
        15
    mayday526  
       2022-12-02 10:39:29 +08:00
    userid 都要隐藏起来?那你们还要用 jwt 干嘛,为什么不用普通的 redis+自定义 token 的方式,jwt 用来认证一堆鬼问题:自动续期 jwt 如何解决,强制剔除或者使某个 jwt 失效又该如何解决
    Jooooooooo
        16
    Jooooooooo  
       2022-12-02 10:41:46 +08:00
    @mayday526 如你所说, 那就并非 "换成别的 userId ,就可以查询其他用户的信息".

    我只是按照 op 所说描述.
    diegozhu
        17
    diegozhu  
       2022-12-02 10:45:27 +08:00
    @geelaw 请教下,有哪些槽点?
    aitaii
        18
    aitaii  
       2022-12-02 11:04:19 +08:00
    jwt 不加密的?
    momocraft
        19
    momocraft  
       2022-12-02 11:05:26 +08:00
    JWE
    lawler
        20
    lawler  
       2022-12-02 11:29:03 +08:00
    @diegozhu #17 这句话和“他知道我的电话号码,就可以接听我的来电”一样卧槽。

    更值得发掘的槽点是,11 楼之前的狗屁不通。。(哭笑
    tool2d
        21
    tool2d  
       2022-12-02 11:47:55 +08:00
    @mayday526 jwt 认证的加密方式和公钥,都是直接写到 json 头部里的。

    密钥是留在客户端 JS 文件里的,但一般 Electron 这种 JS 文件不加密,随便看,随便改。
    mayday526
        22
    mayday526  
       2022-12-02 11:49:43 +08:00
    @tool2d 谁告诉你 jwt 加密方式是由前端完成的?
    tool2d
        23
    tool2d  
       2022-12-02 11:53:35 +08:00
    @mayday526 楼主的 SQL 语句执行是在后端吧?

    那么后端来解密 JWT ,那么发送加密 JWT 的部分,肯定是在前端 /客户端了。
    zjp
        24
    zjp  
       2022-12-02 12:09:06 +08:00 via Android
    补充下#3 的吐槽
    如果是根据 userld 就可以查到敏感数据,这是个横向越权的问题
    wheeler
        25
    wheeler  
       2022-12-02 12:13:23 +08:00 via iPhone
    > 如果换成别的 userId ,就可以查询其他用户的信息。

    那就是敏感。
    vagusss
        26
    vagusss  
       2022-12-02 12:14:05 +08:00 via iPhone
    @tool2d 建议看看 jwt 的实现,本身就是后端生成的,前端只是携带。
    vagusss
        27
    vagusss  
       2022-12-02 12:15:51 +08:00 via iPhone
    “如果换成别的 userId ,就可以查询其他用户的信息。”

    除非能拿到密钥,不然怎么换?
    mayday526
        28
    mayday526  
       2022-12-02 12:16:21 +08:00
    @tool2d 。。。。。前端加密,后端解密?你牛
    tool2d
        29
    tool2d  
       2022-12-02 12:17:48 +08:00
    我再多啰嗦几句,

    正常来说 JWT 有两种使用情况,第一种就是替代以前的 cookie user session, 后端加密后端解密,这样对于前端就是透明的存在,的确无法修改其保存内容。

    另一种情况,是用于匿名身份验证,比如最近很流行的 Apple Passkeys ,就是用公钥来验证用户 ID 。

    换成 JWT 流程也是一样。

    第一步在前端 /客户端生成公钥和密钥。
    第二步把附带公钥的 JWT 发给服务器,服务器就能自动认证用户的 ID ,因为基本上用户本地生成的公钥,是不太可能有重复的。但是因为私钥留在客户端,还是有一定被篡改的风险。
    tool2d
        30
    tool2d  
       2022-12-02 12:20:22 +08:00
    @mayday526 去了解一下 acme 的 jwt 使用场景,就是典型的前端加密,后端解密。JWT 是一个完整规范,有多个使用场景,并不仅仅是 session 的替代品。
    okakuyang
        31
    okakuyang  
       2022-12-02 12:25:44 +08:00
    @tool2d 我麻了
    tool2d
        32
    tool2d  
       2022-12-02 12:30:36 +08:00
    @okakuyang 我就觉得既然用了 JWT ,就应该用起来他的身份认证的功能,不要仅仅当黑盒字符串。

    否则后端发点别的什么不好,干嘛非要给前端塞一长串的 JSON 保存起来。还不如换成 access token 用户认证,还能附带权限控制。
    oott123
        33
    oott123  
       2022-12-02 13:08:24 +08:00
    jwt 标准中没有加密,只有编码+签名,这意味着:

    1. 任何人都能获知 jwt 内编码的信息
    2. 除非有 secret 或者 private key ,否则没有人能轻易修改其中编码的信息,这保证了消息的完整性
    coolzjy
        34
    coolzjy  
       2022-12-02 13:39:46 +08:00
    简单来说,你可以把任何当前用户有访问权限的数据塞到 jwt 中,jwt 能够保证这些数据不被篡改。
    mayday526
        35
    mayday526  
       2022-12-02 13:43:00 +08:00
    @tool2d 使用场景都不一样,还在东扯西扯。op 的 userid 哪里来的,数据库生成的,后端特意返回个 userid 给前端自己生成 jwt ?
    你说的 jwt 黑盒字符串?黑盒? jwt 不是透明的吗?
    你说换成 token 就附带权限控制?认证和授权是两个步骤,jwt 和 token 第一步都是用来认证的,你非要携带权限控制信息,jwt 就不能携带吗?
    前端生成 jwt 跟裸奔有什么区别?你公司敢这么用吗?请把你公司使用这种方式的网站地址发出来
    Rache1
        36
    Rache1  
       2022-12-02 13:50:45 +08:00
    @sheeta 那还不如换成传统的 Token 呢,这样子一搞,JWT 的无状态又变成有状态了。

    不过可以考虑 hashids 的形式。
    dqzcwxb
        37
    dqzcwxb  
       2022-12-02 13:55:58 +08:00
    "如果不放心,专门设计一个 jwtId ,也做成全局唯一,限制其用途只用来通过 JWT 查找真正的 userId?"
    "如#5 所说,redis 映射一个 jwtId => userId 的关系"
    恭喜你,又重新回到了 token 体系的怀抱
    wangxiaoaer
        38
    wangxiaoaer  
       2022-12-02 13:58:20 +08:00
    1 UserId 算不算敏感要看 id 的生成方式,假如你直接用身份证,那就敏感,如果是 uuid 就不敏感。

    2 用户直接更换 jwt 的 userid ,请告诉我用户咋不知道私钥的情况下如何替换?难道后端不做 jwt 校验的吗?

    关于楼上有提到越权的,严格讲这个不算越权,因为 jwt 就代表当前用户身份,就好比有人拦截 cookie 或者碰撞,就可以模拟别人身份操作,这个不属于越权。只不过 cookie 一般人不好拦截或碰撞,而 jwt 是公开的,假如你私钥比较简单,是会被滥用。
    wangxiaoaer
        39
    wangxiaoaer  
       2022-12-02 14:04:22 +08:00
    @tool2d #29

    1 JWT 有很多场景,但题主这种很显然就是用来替代身份认证的。

    2 Apple Passkeys 我了解不多,但凭常识猜测这个是用在 iPhone 、Mac 等客户端上的吧,这种所谓的客户端是有硬件用来存放私钥等信息的,跟题目这种浏览器客户端压根是两个概念。
    dzdh
        40
    dzdh  
       2022-12-02 14:09:19 +08:00
    优酷的视频 ID 不是说是 base64 的么

    https://chenjiehua.me/python/youku-userid-and-videoid-decrypt.html
    watzds
        41
    watzds  
       2022-12-02 14:12:10 +08:00
    你是不懂 jwt 的,也不懂加密和认证
    lanlanye
        42
    lanlanye  
       2022-12-02 14:13:46 +08:00
    不得不翻出我好多年前读的文章了 [你会做 WEB 上的用户登录功能吗?]( https://coolshell.cn/articles/5353.html)
    lanlanye
        43
    lanlanye  
       2022-12-02 14:19:18 +08:00
    @lanlanye
    发完意识到这篇文章没提 JWT ,补充一下:
    1. JWT 的意义是保证数据完整性,只能存放公开的信息,user_id 这种东西看场景,大部分时候应该是可以公开的
    2. JWT 是无状态的,需要设置较短的有效期,签发后无法在有效期内收回
    3. 尽量不要通过在服务端保存签出的 JWT 这种方式来控制其有效性,因为这会使 JWT 失去它无状态的特点,不如直接用回 cookie-session 那一套
    tool2d
        44
    tool2d  
       2022-12-02 14:42:36 +08:00
    @mayday526 你既然说了使用场景不一样,说明还是能看懂我说的。

    https://en.wikipedia.org/wiki/JSON_Web_Token ,里面有一段 use 案例描述,写了有传统后端验证外,还有客户端直接发起 JWT 身份验证两种方式。

    作为后者,很适合匿名账户纯客户端直接认证。私钥又不需要在网络传输,只有用户自己能看见,本机不泄漏,就很安全。
    superliy
        45
    superliy  
       2022-12-02 14:49:49 +08:00
    sha256+secret key 这里加密 不是因为敏感而是用于数据校验,不被串改。。你理解方向歪了。。。
    JamChiu
        46
    JamChiu  
       2022-12-02 15:22:14 +08:00
    jwt 存放的内容本来就敏感,但是加密了,你解密不了也没用,所以有需要就放,没需要就不放~
    leonshaw
        47
    leonshaw  
       2022-12-02 16:15:08 +08:00
    敏感不敏感是保密性,能不能篡改是完整性,注意区分。
    通常所说的 JWT 只保证完整性,关于加密了解下 JWE.
    JasperYanky
        48
    JasperYanky  
       2022-12-02 18:00:57 +08:00
    说个不太显眼的用途,如果 userid 是显性连续的,投资机构会用这个估算产品真实的用户规模
    gzf6
        49
    gzf6  
       2022-12-02 18:38:48 +08:00 via Android
    后端用唯一用户名查询 ID?
    GeruzoniAnsasu
        50
    GeruzoniAnsasu  
       2022-12-02 20:18:54 +08:00
    看了这么多楼回复我感觉我也不知道怎么吐槽了


    - jwt 本身就是鉴权的令牌,换句话说它本身就是用来防止「知道 userID 查到别的用户信息」的关键设施
    - jwt 的关键信息是已登录用户的签名,签名是不可伪造的。至于怎么个不可伪造以及签名如何使用,你们所说的「具体场景有不同用法」,但根本逻辑不会变:通过不可伪造的唯一签名来标识当前请求者是谁
    - jwt 不防 csrf

    我觉得抓住这三点就够了
    rekulas
        51
    rekulas  
       2022-12-02 20:47:00 +08:00
    jwt 的存在不就是为了让分布式节点脱离数据库也能认证么(安全传递令牌或身份验证信息),当然可以存放私有信息比如 uid (除非你有特殊要求比如普通节点禁止获取用户信息,不在此话题讨论内),如果啥用户信息都不想存放而是放一个映射 id 那用 jwt 的意义是什么,不如直接 token 一把梭
    darknoll
        52
    darknoll  
       2022-12-02 21:14:00 +08:00
    @tool2d 我醉了
    zhaogaz
        53
    zhaogaz  
       2022-12-02 21:22:02 +08:00
    。。。楼主说的 jwt 内容有事实性错误。。。,建议在学习一下,有标准 rfc 的。。。

    如果你想把 user ID 藏起来可以用 JWE

    id 这种一般算是一般信息,不算敏感,也没必要加密。如果 id 是身份证号那种,那是有必要加密的,让然用它做 id 也不太对。

    如果你随便换个 id 能查到其他人信息,这个问题是权限问题。。。

    这几句话问题太多了。
    eason1874
        54
    eason1874  
       2022-12-02 21:38:59 +08:00
    1 、用户 ID 不算隐私信息,前提是用户 ID 是系统自动生成的,而非邮箱、手机号、身份证号这些用户隐私信息

    2 、“换成别的 userId 就可以查询其他用户的信息” 要是这样,就说明你们的 jwt 鉴权逻辑有问题,正常的 jwt 换了一个字节都会导致签名不一样,从而无法通过鉴权
    ixixi
        55
    ixixi  
       2022-12-02 23:01:41 +08:00
    觉得有点裸露可以把 userId 用 aes 加密一下 用的时候解密 不影响整体
    urnoob
        56
    urnoob  
       2022-12-02 23:12:57 +08:00 via Android
    jwt 延生带用户信息的叫 openid ,一般就是 uniqueid 通常是 uuid 或者加上用户的姓名等非敏感信息。这个 openid 的 token 在获取时通常需要用户授权,权限列表中如果包含查询用户信息,那么这个 token 才可以拿来查询更多用户信息入 email 电话等等
    mmdsun
        57
    mmdsun  
       2022-12-02 23:47:00 +08:00   ❤️ 1
    如果换成别的 userId ,就可以查询其他用户的信息??
    难道不做验签吗?纂改了还能通过 jwt 校验?

    还有那些放信息去 redis 的 那为啥不直接用 session 呢。 本来 jwt 就是节约服务期资源的
    1423
        58
    1423  
       2022-12-03 00:28:17 +08:00
    需要加密的话,稍微想一下,这跟 ss 的协议设计可能有一样的问题
    最终解法可能是 AEAD 。
    不考虑 jwt 原本的 Signature 。而是将 AEAD 后的结果给到客户端。
    edis0n0
        59
    edis0n0  
       2022-12-03 01:11:35 +08:00
    @JasperYanky #48 我前两周做的外包就要求 userid 增量每次随机 1~50
    JaguarJack
        60
    JaguarJack  
       2022-12-03 11:54:00 +08:00 via iPhone
    串改也没用啊。jwt 需要校验。token 是通过 userid=1 生成。改了数据,校验就过不去啊
    iseki
        61
    iseki  
       2022-12-03 13:08:07 +08:00 via Android
    不要把 user id 当隐私信息,id 这种东西保不齐什么地方就露出去了,不要依赖它保证安全性
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2819 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 517ms · UTC 03:31 · PVG 11:31 · LAX 19:31 · JFK 22:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.