如何保护您的 C# 应用程序

作者:微信公众号:【架构师老卢】
9-20 12:46
97

1. 输入验证

输入验证可防止任何未经授权的用户或其脚本更深入地渗透到代码中以访问敏感信息。换句话说,输入验证层可以防止在代码中执行无效数据或脚本。

public bool IsValidEmail(string email)  
{  
    try  
    {  
        var addr = new System.Net.Mail.MailAddress(email);  
        return addr.Address == email;  
    }  
    catch  
    {  
        return false;  
    }  
}

2. 使用参数化查询

这些攻击可以通过使用参数化的 SQL 查询来简单地阻止,而不是使用带有“+”符号的字符串连接

using (SqlConnection connection = new SqlConnection(connectionString))  
{  
    string query = "SELECT * FROM Users WHERE UserName = @UserName";  
    SqlCommand command = new SqlCommand(query, connection);  
    command.Parameters.AddWithValue("@UserName", userName);  
      
    connection.Open();  
    SqlDataReader reader = command.ExecuteReader();  
    // Process results  
}

3. 避免使用硬编码密钥

对任何敏感信息(如连接字符串、API 密钥或密码)进行硬编码是一种非常糟糕的做法。尝试将它们保留在配置中或通过 AWS Secret Manager 或 Azure Key Vault 进行保留,以防止未经授权的访问。

// Use environment variables  
string apiKey = Environment.GetEnvironmentVariable("API_KEY");  
  
// Or use configuration files with appropriate protection

建议: 甚至不建议检查 Github 上包含连接字符串(带密码)的配置文件。

4. 加密敏感数据

在将任何敏感信息存储到文件或数据库中,甚至进行日志记录之前,请对其进行加密。例如,对文件或数据库字段使用 AES 加密。

public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv)  
{  
    using (Aes aes = Aes.Create())  
    {  
        aes.Key = key;  
        aes.IV = iv;  
        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);  
        using (MemoryStream ms = new MemoryStream())  
        {  
            using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))  
            {  
                using (StreamWriter sw = new StreamWriter(cs))  
                {  
                    sw.Write(plainText);  
                }  
            }  
            return ms.ToArray();  
        }  
    }  
}

5. 使用强身份验证和授权

拥有可信的身份验证方案以防止任何未经授权的用户进入应用程序至关重要。用户凭证的验证是关键,建议使用多因素身份验证,而不是涉及用户名/密码验证的基本身份验证。

public bool ValidateUserCredentials(string username, string password)  
{  
    // Example: Validate against a hashed password in the database  
    string storedHash = GetStoredPasswordHash(username); // Fetch stored hash from database  
    return VerifyPasswordHash(password, storedHash);  
}  
  
public bool VerifyPasswordHash(string password, string storedHash)  
{  
    // Implementation of hash verification  
}

6. 定期更新依赖项

使您的库和框架保持最新状态,以消除 Nuget 或任何其他包存储中提供的第三方组件中的漏洞。

\# Update NuGet packages via command line  
dotnet add package PackageName --version x.y.z

7. 实施适当的错误处理

建议向用户显示通用消息,并且永远不要透露任何敏感信息,如异常消息或堆栈跟踪。

记录异常详细信息以进行跟踪。

try  
{  
    // Code that might throw an exception  
}  
catch (Exception ex)  
{  
    // Log exception details securely  
    LogException(ex);  
    // Display a generic message to the user  
    ShowErrorMessage("An error occurred. Please try again later.");  
}

8. 使用安全传输 (HTTPS)

始终使用 HTTPS 来保护在客户端和服务器之间传输的数据。

// Configure your web server to use HTTPS  
// Example for ASP.NET Core:  
app.UseHttpsRedirection();

9. 限制用户输入长度

当应用程序中没有输入大小验证时,会发生这种情况。在输入中发送过长的数据可能会导致应用程序崩溃。因此,验证 input 大小至关重要。

public IActionResult SubmitForm(string input)  
{  
    if (input.Length > 100) // Example length check  
    {  
        return BadRequest("Input is too long.");  
    }  
// Process input  
}

10. 应用最小权限原则

永远不要提供对应用程序的完全数据库访问权限,即管理员级别的权限。应用程序应始终具有对数据库的最低特权访问权限,以防止运行时失败。

// Configure database user permissions in SQL Server  
-- Create a user with limited permissions  
CREATE USER LimitedUser FOR LOGIN LimitedLogin;  
GRANT SELECT ON dbo.SomeTable TO LimitedUser;

上述提示将增强应用程序安全性,但仍需要使用最佳安全实践对其进行更新,以保护应用程序免受未来的威胁。

相关留言评论
昵称:
邮箱:
阅读排行