当前位置:   article > 正文

Security+ 学习笔记12 安全编码实践_白名单是输入验证的最有力的方法

白名单是输入验证的最有力的方法

一、输入验证(Input validation)

用户向一个应用程序提供输入的任何情况都会使该应用程序被利用。用户提供的输入可能包含旨在与数据库交互的代码,操纵网站后续访问者的浏览器,或执行其他一些攻击。在上一个笔记中,我们提到了包括SQL注入和跨站脚本都是基于输入的攻击。防止基于输入的攻击的最重要方法之一是使用输入验证。 这种技术对用户输入进行过滤,确保终端用户提供的输入不包含恶意的或其他意外的值。
在这里插入图片描述
我们可以采取两种不同的方法进行输入验证,即白名单(Whitelisting)和黑名单(Blacklisting)。

  1. 白名单是输入验证的最有力的方法。在这种方法中,开发者指定允许最终用户输入的确切类型,任何不符合该规范的输入都会被拒绝。例如,如果应用程序要求用户输入他们的出生年份,输入验证程序可以检查以确保输入的是一个四位数的数字。它还可以进一步确保这个四位数的数字对于现在还活着的人来说是一个合理的出生年份。我们不能总是精确地指定应该允许的输入类型,所以白名单并不总是实用。例如,如果我们有一个网络应用程序,允许某人在一个就业网站上输入招聘信息,我们可能无法精确定义该招聘信息的性质。它可能包含字母、数字、特殊符号、超链接,而且可能极短或极长。在这种情况下,我们转而使用黑名单作为输入验证技术。
  2. 黑名单不是描述允许输入的内容,而是描述不允许输入的内容。例如,我们可以禁止在用户输入中使用HTML标签,以防止跨站脚本攻击。我们还可以防止使用SQL关键字,以防止注入攻击。黑名单是一种比白名单更灵活的技术,但它很难描述所有可能的恶意输入类型,所以大多数安全专家认为它不如白名单方法有效。

需要注意的是,当我们执行任何类型的输入验证时,确保该验证发生在服务器本身,而不是在客户的浏览器中,这是非常重要的。

二、参数化查询(Parameterized queries)

参数化查询提供了另一种方法,可以保护应用程序免受注入攻击。在参数化查询中,客户端不直接向数据库服务器发送SQL代码。相反,客户端向服务器发送参数,然后服务器将这些参数插入到预先编译的查询模板中。这种方法可以防止注入攻击,也可以提高数据库性能。

存储过程(Stored procedures)是一些数据库平台所使用的参数化查询的一个实现例子,存储过程十分灵活。当我们使用这种方法时,可以防止SQL注入攻击,因为存储过程是预先编译的。无论用户提供什么输入,它都不能改变底层的SQL语句。

三、认证和会话管理问题(Authentication and session management issues)

软件开发者依靠认证系统来验证用户的身份并做出授权决定。如下是两个软件开发者特别重要的两个问题:

  1. 首先,我们不应该以纯文本(plain)形式存储用户密码。储存密码会使它们面临被盗的风险。相反,我们应该以散列和加盐(hashed and salted)的形式存储密码。哈希密码使用一种加密算法,将密码转化为一个无法逆转的值。这允许通过比较哈希值来验证密码是否正确,但它不允许拥有哈希文件的人恢复密码,因为哈希函数是不可逆转的。在对密码进行散列之前,对密码进行加盐处理,为密码增加一个随机值。这是一个必要的控制,以防止一种特定类型的攻击,即彩虹表攻击(rainbow table attack) ,攻击者预先计算出常见密码的哈希值,然后在存储的密码文件中检查这些哈希值。
    在这里插入图片描述

  2. 除了保护存储的密码,开发人员和系统架构师必须确保密码在传输过程中被加密,这样,查看网络流量的窃听者就不会看到从客户端发送到服务器的用户密码。对于网络应用,在传输过程中保护密码的最简单方法是要求使用传输层安全协议(Transport Layer Security)或TLS。TLS使用HTTPS协议对整个网络会话进行加密,防止窃听者看到任何会话内容,包括用户密码。TLS还保护HTTP头的内容,其中包括会话cookies。我们已经讨论过保护这些cookie的重要性,以避免会话重放攻击。

四、输出编码(Output encoding)

输出编码是一种重要的技术,用于保护应用程序免受潜在的恶意输入,如用于SQL注入和跨站脚本攻击。输出编码的基本前提是把一个有潜在危险的字符,用一个等价的字符串代替,为终端用户产生相同的结果,但没有恶意操纵应用程序的风险。我们可以使用两种不同类型的编码,HTML编码和URL编码,常见的符号编码如下所示:
在这里插入图片描述
这只是一些常见的编码值的简短列表。我们不应该试图手动执行编码,因为还有许多其他的值也需要保护。相反,我们应该使用一个安全的、可信的编码库,自动验证和编码所有潜在的危险值。

五、错误和异常处理(Error and exception handing)

当软件以一种异常的方式响应无效的用户输入或其他错误情况时,就会出现许多安全问题。由于这个原因,适当地处理错误是软件安全的一个重要组成部分。软件被设计成在不同状态之间进行有序的转换。例如,如下是一个非常简单的软件程序:
在这里插入图片描述
它被设计用来计算零售购物的销售税。该软件一开始准备让用户输入一个购买金额。当它收到这个输入时,它计算交易税,然后进入显示模式,向用户显示税额。然后,用户可以按下一个新的交易按钮来输入另一个交易金额。因此,可以把这看作是软件的三种不同状态,即等待输入、计算税款和显示输出。
在这里插入图片描述
这个简单的状态转换模型很好地描述了软件的正常运行。但是,如果发生了错误,例如,用户在交易金额字段中输入了apple这个词。这时,我们的状态图并不包含任何计算机在收到一个字作为输入时应该遵循的指令,所以我们无法预测接下来会发生什么。这种情况被称为不可预测的状态(unpredictable state),它可能导致严重的安全漏洞,如缓冲区溢出和其他损害。

错误处理(Error handling),又称异常处理(exception handling),通过向计算机提供处理不可预测状态的明确指令来防止这种不可预测的状态问题。例如,我们可能想修改软件以显示一条信息,表明用户必须输入一个美元数额。新的状态图将包括这个错误处理,如下所示:
在这里插入图片描述
我们仍然有等待输入的状态,但是我们会有一个输入验证的状态,在这个状态下,软件会检查是否有可能产生错误的条件。如果没有错误,软件将继续计算税收并显示输出。然而,如果用户提供了错误的输入,软件就会进入一个显示错误信息的状态。不同的编程语言以不同的方式实现异常处理。如果我们能够考虑到自己的的代码可能导致的不同错误,并为处理这些错误提供明确的指示,代码将会更安全。

六、代码签名(Code signing)

代码签名为开发者提供了一种方法,向终端用户证明应用程序来自合法来源。通过密码学我们知道,如果数据应用数字签名(Digital signatures),以提供不可抵赖性。任何希望验证数字签名的人可以通过使用签名者的数字证书来验证。

同样的,数字签名也可用于代码签名。代码签名试图帮助用户使用数字签名来确定代码是否合法。 希望对其代码进行签名的开发者从一个受信任的证书机构获得数字证书。然后,他们使用与该数字证书相关的私钥,在向互联网发布他们的代码之前创建一个数字签名。当用户下载开发者的代码时,他们的操作系统会验证该数字签名。操作系统通过检查开发者数字证书中的公钥是否正确地解密了数字签名,以及数字签名中包含的哈希值是否与下载的代码相符。这与用于验证任何数字签名的过程相同。如果数字签名是合法的,操作系统接下来会检查它是否信任签署代码的开发者。
在这里插入图片描述

代码签名为开发者提供了向世界展示代码来自于他们并且没有被恶意的人篡改的方式。它还为终端用户提供了确定他们可以信任的软件的方法。

七、数据库安全(Database seccurity)

数据库包含各种各样的信息,其中有十分敏感和重要的信息。安全专业人员应与数据库管理员密切合作,保护存储在数据库中的信息免受保密性、完整性和可用性的威胁。
在这里插入图片描述

1.数据库规范:
数据库规范化是数据库设计者在建立和修改数据库时应遵循的一套设计原则。遵循这些原则的数据库被称为数据库范式(normal forms)的数据库。这些数据库范式的编号是按照所遵循的原则水平的递增顺序排列的。遵循这一些原则的一些好处包括:

  1. 规范化的设计可以防止数据的不一致性;
  2. 它们可以防止更新异常;
  3. 它们减少了将来重组现有数据库的需要。

前三种数据库范式:

  1. 1NF(First Normal Form):第一种范式要求为不同的相关数据集创建单独的表,为每个表提供一个主键(primary key),不创建具有多值字段的记录,并确保一个表中的所有记录具有相同数量的字段;
  2. 2NF(Second Normal Form):包括第一种范式的所有相同要求,并且其他数据元素与主关键字一一对应;
  3. 3NF(Third Normal Form):要求满足第一和第二种范式的要求,还包括限制非键字段之间关系的要求。

2.数据库加密:
加密是另一种数据库安全控制。与存储敏感数据的任何位置一样,数据库中静态的信息应使用强加密进行保护。这会阻止有权访问数据库表的人读取存储在数据库中的敏感信息,除非他们也有权访问相应的解密密钥。当数据库内容无意中泄露给未经授权的个人时,它还有助于防止意外数据泄露。

在数据库中存储敏感信息时,最好使用模糊(Obfuscation)伪装(Camouflage) 策略。另外,不命名我们的数据库服务器、信用卡数据库或诸如此类的东西是很好的常识。在命名约定中使用一些策略,不要将攻击者直接指向我们的敏感信息。

数据库用户拥有组织中一些特殊的访问权。如果可以直接连接到数据库,则可以绕过应用程序层施加的安全控制。数据库管理员可以读取、写入和修改存储在系统上的几乎任何数据。这种特权访问需要仔细监控,而这正是数据库活动监控或DAM解决方案发挥作用的地方。这些专用工具会监控对数据库的所有请求,特别是管理用户的请求,并监视可疑活动的迹象,将其标记为审查或直接干预。

最后,数据库管理员和应用程序开发人员应尽可能合作使用存储过程和应用程序。存储过程将查询文本存储在数据库服务器上,然后允许应用程序只提供参数而不是整个SQL命令。当正确实现时,存储过程可以有效地控制SQL注入攻击。

八、数据去识别化(Data deidentification)

许多组织试图保护自己免受个人信息意外披露的一种方式是,当识别信息对满足业务需求没有必要时,从数据集中删除所有识别信息。去除身份信息是指通过数据集,删除可能具有个人身份的数据的过程。例如,我们肯定会想删除姓名和其他明显的识别信息。然而,简单的数据去标识化往往不足以完全保护信息。其原因是,我们经常可以将看似无害的字段结合起来,以唯一地识别一个人。卡内基梅隆大学的一项研究分析了去识别数据集中通常保留的三个字段:邮政编码、出生日期和性别:
在这里插入图片描述

我们不会认为这些字段中的任何一个,当单独使用时,会让识别某人。毕竟,有很多人和我们住在同一个城市,而且地球上有很多人和我们出生在同一天。然而,但是当把他们全部结合起来时,危险就来了。研究发现,这三个要素加在一起可以独特地识别美国87%的人。因此,虽然我们所在的城市可能确实有很多人,世界上也有很多与我们同一天出生的人,但有87%的机会,我是我所在城市中唯一一个在我生日当天出生的男性。这对我们来说意味着,我们需要更谨慎地保护数据,而不是简单地删除明显的识别信息。我们需要对数据进行匿名化处理,而不仅仅是去掉数据的标识,使别人几乎不可能弄清某个人的身份。HIPAA标准包括一个严格的数据匿名化过程,在分析界被广泛接受。它提供了两种清除数据集的途径:

  1. 让统计学家分析你的数据集,并验证它非常不可能披露个人的身份。这个途径需要接触到专业的统计人员,而且它确实包括意外披露的可能性;
  2. 选择使用安全港(safe harbor)的方法,这需要从你的数据集中剔除18个可能相互结合而暴露个人身份的数据元素。

在这里插入图片描述

九、数据混淆(Data obfuscation)

从数据集中删除数据的另一种方法是将其转换为一种无法检索到原始信息的格式。这是一个被称为**数据混淆(data obfuscation)**的过程,我们有几个工具可以帮助我们完成这个过程:

  1. 我们可以使用哈希函数将我们数据集中的一个值转化为哈希值。虽然不可能直接从哈希值中检索出原始值,但这种方法有一个重大缺陷。如果有人拥有我们字段的可能值的列表,他们可以进行彩虹表攻击。在这种攻击中,攻击者计算出这些候选值的哈希值,然后检查这些哈希值是否存在于数据文件中。由于这个原因,散列法只应慎重使用;
  2. 盐(Salting) 是一种技术,它通过在散列之前将文本与随机选择的值相结合来增加散列的安全性。用随机值加盐使散列的预先计算成为可能,并防止使用彩虹表;
  3. 令牌化(Tokenization),敏感值被替换为使用查找表的唯一标识符。例如,我们可以用一个随机产生的10位数来替换一个广为人知的值,如学生证。然后我们维护一个查询表,如果我们需要确定某人的身份,就可以将这些值转换回学生证。当然,如果我们使用这种方法,需要保持查询表的安全;
  4. 在许多情况下,我们根本不需要重新识别数据。如果是这种情况,你可以使用一种被称为屏蔽(Masking) 的方法来编辑文件中的信息。这将敏感信息替换为空白值。例如,我们可以用 "X "掩盖社会安全号码的所有数字,以取代它们。

参考资料来源:
https://www.linkedin.com/learning/paths/become-a-comptia-security-plus-certified-security-professional-sy0-601

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/425584
推荐阅读
相关标签
  

闽ICP备14008679号