CodeQL 文档

不安全的随机性

ID: cs/insecure-randomness
Kind: path-problem
Security severity: 7.8
Severity: warning
Precision: high
Tags:
   - security
   - external/cwe/cwe-338
Query suites:
   - csharp-code-scanning.qls
   - csharp-security-extended.qls
   - csharp-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

使用加密强度较弱的伪随机数生成器来生成安全敏感值(例如密码)会使攻击者更容易预测该值。

伪随机数生成器生成的数字序列仅近似于随机数的属性。该序列并非真正随机,因为它完全由一组相对较小的初始值(种子)决定。如果随机数生成器的加密强度较弱,则可以通过外部观察轻松预测该序列。

建议

如果要在安全敏感的上下文中使用输出,请使用加密安全的伪随机数生成器。根据经验,如果预测某个值将允许攻击者执行他们原本无法执行的操作,则该值应被视为“安全敏感的”。例如,如果攻击者可以预测为新用户生成的随机密码,则他们将能够以该新用户的身份登录。

对于 C#,RNGCryptoServiceProvider 提供了加密安全的伪随机数生成器。Random 不是加密安全的,在安全上下文中应避免使用。对于非安全敏感的上下文,Random 可能更可取,因为它具有更方便的接口,并且可能更快。

示例

以下示例展示了生成密码的不同方法。

在第一种情况下,我们通过将随机整数附加到静态字符串的末尾来生成新密码。使用的随机数生成器(Random)不是加密安全的,因此攻击者有可能预测生成的密码。

在第二个示例中,出于相同目的使用了加密安全的随机数生成器。在这种情况下,预测生成的整数要困难得多。

在最后一个示例中,使用 Membership.GeneratePassword 库方法生成密码,该方法生成的密码存在偏差,因此应避免使用。

using System.Security.Cryptography;
using System.Web.Security;

string GeneratePassword()
{
    // BAD: Password is generated using a cryptographically insecure RNG
    Random gen = new Random();
    string password = "mypassword" + gen.Next();

    // GOOD: Password is generated using a cryptographically secure RNG
    using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
    {
        byte[] randomBytes = new byte[sizeof(int)];
        crypto.GetBytes(randomBytes);
        password = "mypassword" + BitConverter.ToInt32(randomBytes);
    }

    // BAD: Membership.GeneratePassword generates a password with a bias
    password = Membership.GeneratePassword(12, 3);

    return password;
}

参考资料

  • ©GitHub 公司
  • 条款
  • 隐私