美文网首页Amazing Arch极客思维运维驿站
在日志记录中保护用户隐私数据的七个最佳实践

在日志记录中保护用户隐私数据的七个最佳实践

作者: 极客人 | 来源:发表于2019-03-20 12:50 被阅读4次

    2019年度“315”晚会人工智能拨打骚扰电话的情节,让大众了解到在信息时代,保护个人隐私的重要性。本篇文章分享了在日志记录中保护用户隐私数据的七个最佳实践。

    与“中国人愿意用隐私交换便利性”的心态完全不同,欧美国家在个人隐私保护方面明显走得更早也更远一些。在2018年5月GDPR发布前后的一段时间里,保护个人隐私相关的需求被迅速提高了优先级,而像我这样一个开发国际化产品的普通程序员,日常工作也因此受到影响,我们放下手中的业务需求卡(Story),转而去做GDPR相关的安全需求。

    从公司最高层面,自上而下,我们采取了一系列相关动作,比如梳理我们基础设施架构图、数据流图、数据格式……,而其中很大一部分就是保护日志中的个人信息。

    一般在医疗保健或金融行业中,限制访问客户的敏感数据有着非常严格的规定,尤其欧洲GDPR颁布之后,公司泄露个人数据的后果也非常严重。如果没有适当的流程、工具或者意识,为了开发调试的方便,常常会无意地将隐私数据写入日志文件。

    并没有一种一劳永逸的方式来避免个人信息出现在日志中,但我们可以通过下面的措施,并内建在自己平时的开发工作中,来尽量规避出现个人隐私安全问题。

    一、确定什么是隐私数据

    在我们深入讨论怎样避免个人隐私数据出现在日志之前,我们来界定什么是隐私数据

    • 个人可标识数据(PII):如社会安全号码,数据组合(如名字+出生日期或姓氏+邮政编码)或用户生成的数据(如电子邮件或用户名,如BillGates@hotmail.com),手机号。
    • 健康信息
    • 财务数据(如信用卡号)
    • 密码
    • IP地址:IP地址也有可能是个人隐私数据,尤其是与个人可标识数据与其有某种绑定关系。(而2019年的3.15晚会介绍一种将MAC也变成了PII的方式)

    个人隐私信息不一而足,重要的是要根据实际情况彻查应用内的数据,来确定什么是敏感的.

    二、分离隐私数据

    处理隐私数据时,应尽量减少系统使用这些数据。例如,在数据库表设计时,使用SSN或电子邮件地址作为人的主键的确很顺手,但是,如果这样做,系统在许多不同部分(数据库表,API端点等)都要处理和存储这些敏感字段,更好的方法是分离隐私数据,只在在必要时才使用它。

    一种常见的解决方案是使用查找表用随机ID替换隐私字段。例如:

    SSN | 外键
    ------------------------- 
    999-99-9999 |5a2_cXKrt32DcWOJpJlyhr7FhTcLPfvlEAb1eA2H
    

    即使SSN是主键,主Person表外的表和服务也只使用外键。

    三、避免在URL中出现个人隐私信息

    如果您正在构建RESTful API并且您的用户数据是在电子邮件地址上键入的,则可能很容易拥有一个端点,如:/user/<email>。请求URL通常由代理和Web服务器记录,因此如果您这样做,电子邮件必然会以日志结束。要将敏感数据保留在您的网址之外,您可以选择几个选项。

    选项1.根据建议#1,不要将敏感字段用作唯一标识符。对于端点URL,请改用这些外部ID。

    选项2.违反REST原则并将敏感值作为POST正文的一部分传递,即使它是只读请求。Web服务器通常不会记录POST请求的正文,因此您的敏感字段不会记录日志。

    问题

    在设计早期,您应确定系统中哪些数据被视为敏感数据。如果你还没有这样做,那么可能需要付出艰苦的努力才能在游戏后期进行类似的API设计更改。

    四、对象打印重写toString方法

    因此,您已经划分了代码(#1)并将数据保留在URL(#2)之外。但是,您的用户端点包含一些日志记录语句,以帮助调试服务。它可能看起来像:

    logger.info("为用户$ {user}更新电子邮件);
    

    代码库中的某个位置是将a序列化为user字符串的方法。也许它在课堂定义中。在该定义中,请确保使用敏感数据编辑字段:

    class UserAccount { 
      id:string 
      username:string 
      passwordHash:string 
      firstName:string 
      lastName:string 
    
      ... 
    
      public toString(){ 
        return "UserAccount (${this.id})"; 
    }
    

    记录所有字段可能很诱人toString,但事实证明你真的只需要id。如果在调试过程中需要跟踪有关用户的更多详细信息,则可以在完成后查找它们id

    问题

    这不会阻止开发人员直接记录字段,例如: logger.info("The user's details are: ${user.firstName} ${user.lastName}");

    五、结构化对象打印时屏蔽隐私字段

    通过基于字符串的API记录,console.log()或者printf两者都需要将数据转换为字符串,现在通常被认为是一种反模式。将数据吐出来进行调试可能很容易,但解析这些数据很痛苦,而且可能缺少有用的上下文。使用结构化日志记录而不是字符串,可以记录键/值或嵌套对象。有关当前上下文的某些详细信息(例如,请求ID或服务器主机名)可以自动注入请求中。

    如果你不熟悉结构化日志,那么honeycomb.io博客就有一个很好的介绍:你可以发明结构化日志

    结构化日志记录后,您现在可以将某些属性列入黑名单,以便在运行时对其进行过滤。例如:

    Blacklist = ["firstName", "lastName", "SSN"]
    SSNRegex = r"^\d{3}-?\d{2}-?\d{4}$"
    EmailRegex = r".+@.+";
    class Logger {
      log(details: Map<string,string>) {
        const cleanedDetails = details.map( (key, value) => {
          if (Blacklist.contains(key) || 
              SSNRegex.match(value) || 
              EmailRegex.match(value)) {
            return (key, "<redacted>");
          }
          return (key, value);
        }
        console.log(JSON.stringify(cleanedDetails));
      }
    }
    

    在上面的记录器中,我们有一个基于黑名单和两个正则表达式的简单启发式,以跳过看起来像SSN或电子邮件的值。

    问题

    这并不能阻止某人做类似的事情:

    logger.log({'pleaseLogThis': user.firstName});
    

    要么

    logger.log('{firstName:Joe}');
    

    也可能有一个误报,其中一个日志记录语句过滤掉它不应该的东西 - 但根据我的经验,这是非常罕见的,很容易在开发早期捕获。

    五、通过代码审查尽量避免

    作为代码审查的一部分,审阅者应查找包含敏感数据的日志记录。如果您使用的是Pull Request Template,则可能需要在模板中设置一个复选框,以便审阅者确认他们已在更改中验证了日志记录语句。

    什么可能出错

    根据我的经验,审稿人倾向于掩盖日志记录。它需要文化的转变来注意并密切关注它们。

    六、通过QA和自动化测试

    虽然您的QA团队应该测试系统中的许多流程是否正常工作,但他们的测试并不止于此。如果测试是自动化的并且使用可预测的数据,则测试可以自动检查该数据是否未在日志中结束。例如,如果Web表单包含名字,姓氏和SSN字段,则在运行Selenium套件之后,测试还应在应用服务器日志中查找该名字,姓氏和SSN。

    问题

    QA团队通常没有正确的访问权限,甚至不知道要检查哪些系统。如果他们一直在进行黑盒测试,那么需要一些工作才能让他们加快速度。

    七、在日志系统中配置告警

    与#4和#6类似,您可以在日志记录系统中编写测试以查找某些数据模式。例如,查找SSN或搜索常见测试数据的正则表达式。此测试应该在您的staging或dev环境中就位,以便将代码提升为生产之前捕获它。

    虽然这看起来有点矫枉过正,但我​​已经看到这种技术在它投入生产之前会发现许多可能的PII漏洞。如果您有一个复杂的系统,系统某个部分的微小变化可能会产生意想不到的后果,这些后果很难以其他方式捕获。

    问题

    您的登台环境的应用程序配置(例如日志级别)是否与生产相匹配?您是否将登录的日志记录到与生产相同的日志记录系统中?

    有时,警报可能过于嘈杂,因为将为DEBUG级别的日志记录配置分段,这会导致更多消息。有时,团队会忽略分段提醒。根据我的经验,以与生产中相同的活力处理分段中的警报或中断非常重要。否则,你可能不会提前抓住这些东西。

    总结

    这些最佳实践可以帮助您将敏感数据保留在日志之外。它肯定不是一个完整的设置,可以让你为HIPAA或SOC2审计做好准备,但它们可以使你的创业公司在这方面有一个良好的立足点。即使您不在高度合规行业,您也应该认真对待保持客户数据的机密性。

    但在一天结束时,清单不会使您的系统安全。您的公司和软件团队需要投资建立安全系统的文化。

    如果您想了解有关日志记录和安全性的更多信息,OWASP拥有许多优秀的资源,包括Logging Cheat Sheet

    我看到数据潜入日志的其他方式包括:

    • 数据库日志 - 如果配置错误,他们最终可能会写出查询和查询参数
    • 其他错误配置 - 我发现部署错误无意中将日志更改为生产中的DEBUG数十次。虽然您的日志记录可能没问题,但ORM或其他第三方库可能会丢弃大量信息。
    • 客户端数据泄露 - 您需要注意如何在客户端存储数据,就像Healthcare.gov在2015年出名一样

    参考资料:https://medium.com/@joecrobak/seven-best-practices-for-keeping-sensitive-data-out-of-logs-3d7bbd12904

    相关文章

      网友评论

        本文标题:在日志记录中保护用户隐私数据的七个最佳实践

        本文链接:https://www.haomeiwen.com/subject/hlvbmqtx.html