1
yhj
2024-07-24 5e5d945e91568b973faa27d8ab0bcef99fc4a6c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CSFrameworkV5.Core.Common
{
    /// <summary>
    /// 代码安全检查工具类-ver:20210820
    /// </summary>
    internal static class CodeSafeHelper
    {
        /// <summary>
        /// 防止命令注入,Process.Start()
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string GetSafeCmd(string content)
        {
            if (string.IsNullOrWhiteSpace(content))
            {
                return string.Empty;
            }
            else
            {
                //防止命令注入的方法如下:
                //过滤可能引起命令注入的危险字符,如:; ,[ ,] ,| ,< ,> ,\。
                var cs = new char[] { ';', '[', ']', '|', '<', '>' };
                foreach (var c in cs)
                    content = content.Replace(c.ToString(), "");
                return content.Trim();
            }
        }
 
        /// <summary>
        /// 防止路径遍历
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetSafePath(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                return string.Empty;
            }
            else
            {
                //防止路径遍历, 过滤..和/字符
                var fileName = path.Replace("..", "").Replace("/", "");
                return fileName;
            }
        }
 
        /// <summary>
        /// 获取安全的SQL脚本
        /// </summary>
        /// <param name="sql">SQL脚本</param>
        /// <param name="replaceInjectionChar">替换可能造成SQL注入攻击的字符</param>
        /// <returns></returns>
        public static string GetSafeSQL(string sql,
            bool replaceInjectionChar = true)
        {
            if (string.IsNullOrWhiteSpace(sql))
            {
                return string.Empty;
            }
            else
            {
                //检测单引号,防止注入攻击
                if (sql.IndexOf("'") > 0) sql = CheckSQM(sql);
 
                //防止SQL注入的方法如下:
                //过滤可能引起SQL注入的危险字符, 注意MySQL的注释:[-- ]后面有空格
                if (replaceInjectionChar)
                {
                    var cs = new string[] { "#", "--", "-- ", "/*", "*/" };
                    foreach (var c in cs)
                        sql = sql.Replace(c, "");
                }
 
                return sql.Trim();
            }
        }
 
        /// <summary>
        /// 检查SQL语法单引号,若不正常抛出异常。
        /// 单引号SQM:Single Quotation Mark        
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>若检测不通过抛出异常</returns>
        private static string CheckSQM(string sql)
        {
            if (string.IsNullOrWhiteSpace(sql)) return string.Empty;
 
            //SQL没有单引号不处理
            if (sql.IndexOf("'") < 0) return sql;
 
            //找出单引号数量
            var count = sql.Count(a => a == '\'');
 
            //奇数,单引号不配对!
            if (count % 2 == 1)
                throw new Exception($"SQL语法不正确!\r\nSQL:{sql}\r\n请检查单引号是否配对。");
 
            //检查where语句后面是否存在单引号
            var w = sql.ToLower().IndexOf("where");
            if (w > 0)
            {
                var where = sql.ToLower().Substring(w, sql.Length - w);
                if (where.IndexOf("'") >= 0)
                    throw new Exception(
                        $"SQL语句WHERE条件不允许任何单引号\"'\"拼接,请使用SQL参数传值!\r\n" + where);
            }
 
            return sql;
        }
    }
}