默认系统文本 JSON 序列化中的潜在风险
System.Text.Json 库已成为大多数现代 .NET 应用程序的默认库。它高效、轻量级,并且与 ASP.NET Core 深度集成。但正是这些使其易于使用的默认设置,也带来了不易察觉的安全风险。 默认情况下,System.Text.Json 序列化会自动序列化所有公共属性,即使是包含敏感数据(例如令牌或内部标识符)的属性也不例外。开发人员通常为了提高速度而依赖这些默认设置,却忽略了这可能会在 API 响应中暴露机密信息(jsonserializer)。
⚠️此示例不安全,仅供学习交流之用。请勿用于生产环境。
public class UserProfile
{
public string UserName { get; set; }
public string Email { get; set; }
public string SessionToken { get; set; } // Sensitive field
}
var json = JsonSerializer.Serialize(userProfile);
Console.WriteLine(json);
// Output: {"UserName":"alex","Email":"alex@example.com","SessionToken":"eyJhbGciOi..."}
这种 jsonserializer 行为暴露了 会话令牌 因为所有公共属性都会自动序列化。
安全版本:
public class UserProfile
{
public string UserName { get; set; }
public string Email { get; set; }
[JsonIgnore] // Prevent serialization of sensitive fields
public string SessionToken { get; set; }
}
教育说明: 一律使用 [JsonIgnore] 对于敏感属性,或者设计单独的 DTO,其中只包含用于序列化的字段。
JsonSerializer 如何在无警告的情况下扩大风险敞口
System.Text.Json 中的 JsonSerializer 并不会止步于表面层。它会递归地遍历嵌套的对象、集合和枚举值,序列化它能够访问的所有内容。 如果没有明确排除,这很容易导致嵌套数据泄露,尤其是在内部对象包含令牌、标识符或会话密钥时。
⚠️此示例不安全,仅供学习交流之用。请勿用于生产环境。
public class AuthData
{
public string AccessToken { get; set; } // Sensitive
}
public class ApiResponse
{
public string Message { get; set; }
public AuthData AuthInfo { get; set; } // Nested object
}
var json = JsonSerializer.Serialize(new ApiResponse
{
Message = "OK",
AuthInfo = new AuthData { AccessToken = "abc123" }
});
Console.WriteLine(json);
// Output: {"Message":"OK","AuthInfo":{"AccessToken":"abc123"}}
嵌套对象使得系统文本 JSON 序列化包含敏感信息。 访问令牌 自动。
安全版本:
public class AuthData
{
[JsonIgnore] // Prevent exposure of sensitive tokens
public string AccessToken { get; set; }
}
public class ApiResponse
{
public string Message { get; set; }
public AuthData AuthInfo { get; set; }
}
var options = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = false
};
var json = JsonSerializer.Serialize(apiResponse, options);
教育说明: 始终定义 JsonSerializerOptions 明确检查嵌套类型是否存在意外数据泄露。
API 和微服务在现实世界中的影响
在实际的 .NET 应用程序中,这些序列化风险通常在部署后才会显现。自动化、DTO 重用以及默认的 jsonserializer 行为的结合,加剧了这些风险。 不安全序列化导致数据泄露的常见模式:
- 在 API 响应中直接重用 EF Core 实体。
记录包含身份验证数据的序列化对象。 - 内部服务和公共服务之间的共享模式 CI/CD pipelines.
⚠️此示例不安全,仅供学习交流之用。请勿用于生产环境。
// Logs the full object, including sensitive fields
_logger.LogInformation("Response: {data}", JsonSerializer.Serialize(result));
如果 导致 包含 密码哈希 or 会话令牌这些现在都存储在 CI/CD 日志,违反 最小特权原则。 切勿在以下位置暴露真实令牌、凭据或内部 URL: pipelines.
安全版本:
var options = new JsonSerializerOptions
{
IgnoreReadOnlyProperties = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
// Sanitize before serialization
result.SessionToken = null;
_logger.LogInformation("Response: {data}", JsonSerializer.Serialize(result, options));
教育说明: 在记录日志之前,请对敏感字段进行脱敏或置空处理,并始终使用安全模式。 JsonSerializerOptions 审计输出的默认值。
面向开发人员的安全序列化实践
开发者应将 system.text.json 的默认值视为一种便利层,而非安全策略。安全的系统文本 JSON 序列化意味着掌控哪些内容会离开你的应用程序。
实用防御
- 明确约定: 为 API 响应创建专用 DTO,切勿直接序列化 EF 或领域实体。
- 配置全局选项: 绝大部分储备使用 JsonSerializerOptions.DefaultIgnoreCondition 以及 物业命名政策.
- 在断裂前, [JsonIgnore] 或转换器: 隐藏或转换敏感数据。
- 验证输出结果: 检查测试中实际的序列化响应。
- 自动检查: 在序列化验证中加入 CI/CD.
迷你预防检查清单
- 检查所有使用 System.Text.Json 序列化的类
- 标记密钥或凭证 [JsonIgnore]
- 在以下位置定义全局安全默认值 程序.cs or 启动文件
- 避免在日志中直接序列化
- 将序列化暴露测试纳入您的计划中 CI/CD pipeline
教育说明: 安全序列化旨在限制风险暴露,而非增加复杂性。应明确序列化过程并使其可测试。
使用自动扫描检测不安全的序列化——System.Text.Json
自动扫描 CI/CD 有助于检测对 System.Text.Json 和 JsonSerializer 的风险使用。静态分析工具可以识别:
- 模型缺失 [JsonIgnore].
- DTO中暴露的敏感场。
- 不安全的全局默认值(例如,缺少忽略条件)。
例如: Pipeline 确保
# Never expose real tokens, credentials, or internal URLs in pipelines
- name: Run serialization security checks
run: dotnet xygeni validate --rules serialization --fail-on-risk
教育说明: 整合 静态检查 进入你的 CI/CD 确保对所有构建版本进行一致的系统文本 JSON 序列化控制。
创新中心 Xygeni Code Security 增强 .NET 序列化安全性
西吉尼 Code Security 提供对 .NET 中 System.Text.Json 的不安全默认值和 JsonSerializer 的滥用进行深度检测。
它可以识别以下模式:
- 敏感字段默认进行序列化。
- JSON 数据日志记录不安全。
- 失踪 [JsonIgnore] 属性。
- 系统文本 JSON 序列化选项配置错误。
通过整合 西吉尼 成 pre-commit hooks, CI/CD pipelines,或者说 PR 门,可以在易受攻击的序列化模式合并之前阻止它们。 它通过将序列化错误配置转化为可强制执行的安全策略,来完善您现有的 DevSecOps 流程。
教育性提示:像 Xygeni 这样的安全工具会自动强制执行序列化规范。 让开发人员能够专注于代码编写,而不是审计。
结论——关于 System.Text.Json
System.Text.Json 虽然序列化速度很快,但这种便利往往会带来安全隐患。默认情况下,system.text.json 序列化会包含所有公共属性,这可能会导致内部数据、令牌或标识符泄露。
开发者应该:
- 审核他们的模型。
- 绝大部分储备使用 [JsonIgnore] 而且安全 JsonSerializerOptions.
- 避免序列化内部对象。
- 使用诸如此类的工具自动扫描 Xygeni Code Security.
默认序列化并非开发者的捷径,它还可能导致数据泄露。务必明确指定序列化方式,验证输出,并自动执行检查,因为看似安全的默认设置并不总是安全的。





