C# 使用Process.Start触发Fortify命令注入问题的解决求助
命令注入告警修复方案
告警触发原因
Fortify静态扫描识别到你传入Process.StartInfo.Arguments的参数为动态可控值,无法确认你的自定义正则/路径处理逻辑是否能完全防范命令注入风险,因此触发告警;硬编码参数时扫描器确认无可控输入风险,就不会触发告警。
修复方案
方案1:优先使用ArgumentList替代Arguments(推荐)
.NET Core 2.1、.NET 5及以上版本内置了ArgumentList属性,会自动对所有传入的参数做标准化转义,无需手动处理拼接和转义逻辑,是官方推荐的防参数注入方案,Fortify可识别该API的安全特性,不会误报告警。
修改后代码示例:
var cProcess = new Process { StartInfo = { FileName = sr, // 替换Arguments为逐个添加参数到ArgumentList ArgumentList = { "参数1", "参数2", "参数N" }, WindowStyle = ProcessWindowStyle.Minimized, UseShellExecute = false } }; cProcess.Start(); return cProcess;
如果你的参数是动态拼接的字符串,需要先拆分出每个独立的参数项,再逐个加入ArgumentList即可。
方案2:.NET Framework 兼容方案
如果你使用的是不支持ArgumentList的低版本.NET Framework,需要实现标准的命令行参数转义逻辑,同时配合白名单校验:
- 先对
FileName做强白名单校验:只允许启动预设的可执行文件,禁止传入用户可控的可执行文件路径 - 实现标准参数转义方法,示例如下:
// 标准命令行参数转义方法,符合Windows命令行解析规则 private string EscapeCommandLineArgument(string arg) { if (string.IsNullOrEmpty(arg)) return "\"\""; bool needsQuotes = arg.Contains(' ') || arg.Contains('\t') || arg.Contains('"'); if (!needsQuotes) return arg; StringBuilder sb = new StringBuilder(); sb.Append('"'); for (int i = 0; i < arg.Length; i++) { int backslashCount = 0; while (i < arg.Length && arg[i] == '\\') { backslashCount++; i++; } if (i == arg.Length) { sb.Append('\\', backslashCount * 2); break; } if (arg[i] == '"') { sb.Append('\\', backslashCount * 2 + 1); sb.Append('"'); } else { sb.Append('\\', backslashCount); sb.Append(arg[i]); } } sb.Append('"'); return sb.ToString(); } // 调用示例 var escapedArg1 = EscapeCommandLineArgument(参数1); var escapedArg2 = EscapeCommandLineArgument(参数2); string arguments = $"{escapedArg1} {escapedArg2}";
- 完成转义和白名单校验后,如果Fortify仍误报,可提供防护逻辑说明申请误报排除。
内容的提问来源于stack exchange,提问作者user1508503
相关产品推荐
相关产品推荐

