C#实战:如何保护代码免受SQL注入和XSS攻击

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

前言:为什么安全不是可选项,而是基本素养

\n\n

想象一下:你正在用C#编写一个很棒的Web服务。一切运行完美——用户可以注册、发表评论、搜索商品。然后来了个“黑客瓦西里”(其实他只是从网上复制了一段脚本)——就把整个数据库拖走了。或者更糟的是,他在你的页面中插入了一段脚本,窃取了所有访问者的Cookie。

\n\n

听起来像恐怖电影的情节?然而这种事情每天都在发生。根据OWASP的统计,注入攻击(SQL、XSS、LDAP)位列Web应用程序最危险的三大漏洞之中。而C#,尽管非常可靠,但默认情况下并不会给你提供免疫护盾。

\n\n

在本文中,我们将深入分析两种最热门的攻击方式——SQL注入和XSS(跨站脚本攻击)。你得到的将不仅仅是理论,而是带有真实代码示例的C#实战防御技巧。我们开始吧!

\n\n

SQL注入:当用户变成黑客

\n\n

实际场景是怎样的

\n\n

假设你有一个简单的登录系统。用户输入用户名和密码,然后你这样构建查询:

\n\n
string login = txtLogin.Text;\nstring password = txtPassword.Text;\nstring query = "SELECT * FROM Users WHERE Login = '" + login + "' AND Password = '" + password + "'";\nSqlCommand cmd = new SqlCommand(query, connection);
\n\n

看起来合理?大错特错!如果攻击者在用户名字段中输入:' OR 1=1 --,那么查询将变成:

\n\n
SELECT * FROM Users WHERE Login = '' OR 1=1 --' AND Password = '...'
\n\n

--之后的所有内容都是注释。1=1条件永远为真。查询将返回所有用户,从而通过身份验证。如果攻击者用DROP TABLE Users替换注释呢?数据库就没了。

\n\n

防御措施#1:参数化查询(你的主要盾牌)

\n\n

防御SQL注入的最佳方法——永远不要手动拼接字符串。使用参数。SQL Server会自动转义危险字符,你的数据库将数据作为值接收,而不是作为代码。

\n\n
string login = txtLogin.Text;\nstring password = txtPassword.Text;\n\nstring query = "SELECT * FROM Users WHERE Login = @Login AND Password = @Password";\n\nusing (SqlConnection conn = new SqlConnection(connectionString))\n{\n    SqlCommand cmd = new SqlCommand(query, conn);\n    cmd.Parameters.AddWithValue("@Login", login);\n    cmd.Parameters.AddWithValue("@Password", password);\n    \n    conn.Open();\n    SqlDataReader reader = cmd.ExecuteReader();\n    // 处理结果\n}
\n\n

请注意:@Login和@Password是参数。即使用户输入'; DROP TABLE Users; --,数据库管理系统也会将其视为普通字符串,而不是代码。既安全又优雅。

\n\n

防御措施#2:存储过程

\n\n

另一个强大的工具是存储过程。它们不仅能防御注入,还能提高性能(查询计划会被缓存)。

\n\n
-- SQL Server\nCREATE PROCEDURE GetUserByLogin\n    @Login NVARCHAR(50)\nAS\nBEGIN\n    SELECT * FROM Users WHERE Login = @Login\nEND
\n\n
// C#代码\nusing (SqlConnection conn = new SqlConnection(connectionString))\n{\n    SqlCommand cmd = new SqlCommand("GetUserByLogin", conn);\n    cmd.CommandType = CommandType.StoredProcedure;\n    cmd.Parameters.AddWithValue("@Login", inputLogin);\n    \n    conn.Open();\n    // ...\n}
\n\n

防御措施#3:Entity Framework和ORM

\n\n

如果你使用Entity Framework(或任何其他ORM),你已经得到了部分保护。EF会自动生成参数化查询。但有一个注意事项:通过EF执行原始SQL查询(FromSqlRaw方法)——本质上还是字符串拼接。请保持警惕!

\n\n
// 糟糕的做法:\nvar users = context.Users.FromSqlRaw("SELECT * F                

博客

书籍推荐