• Unsafe SQL code Injection Inspector


    
    // /r:"C:\Program Files\Microsoft Visual Studio 10.0\VSTSDB\Deploy\Microsoft.Data.Schema.ScriptDom.dll";"C:\Program Files\Microsoft Visual Studio 10.0\VSTSDB\Deploy\Microsoft.Data.Schema.ScriptDom.Sql.dll"
    namespace Microsoft.Security.Application.SecurityRuntimeEngine.PlugIns
    {
        using System;
        using System.Collections.Generic;
        using System.IO;
        using Data.Schema.ScriptDom;
        using Data.Schema.ScriptDom.Sql;
        public class SqlInjectionInspector //: IRequestInspector, IConfigurablePlugIn
        {
            /// <summary>
            /// Returns a value indicating if the specified input could be a SQL injection attempt.
            /// </summary>
            /// <param name="input">The input to check.</param>
            /// <returns>True if the input is a possible SQL injection attempt, otherwise false</returns>
            private static bool IsSqlInjectible(string input)
            {
                return DetectCompleteSql(input) || DetectPartialSql(input) || DetectLogicInjection(input);
            }
            /// <summary>
            /// Detects logic short circuit attempts.
            /// </summary>
            /// <param name="input">The input to check.</param>
            /// <returns>True if a logic short circuit has been detected, otherwise false.</returns>
            private static bool DetectLogicInjection(string input)
            {
                // First determine whether there are two or more instances of single quotes.
                // This could potentially be SQL that attempts to change logic in a SQL query.
                int firstSingleQuoteIndex = input.IndexOf("'", StringComparison.Ordinal);
                // If there is no single quote in the input, then logic injection attack is unlikely.
                if (firstSingleQuoteIndex == -1)
                {
                    return false;
                }
                int lastSingleQuoteIndex = input.LastIndexOf("'", StringComparison.Ordinal);
                // If there is only one single quote in the input, then logic injection attack is unlikely.
                if (firstSingleQuoteIndex == lastSingleQuoteIndex)
                {
                    return false;
                }
                /* At this point, there is more than one single quote in the input.
                 * Strip out any quotes after the first instance and then pass it to the parser.
                 * For example, consider the query: select * from users where username=’ ” + param + “ ‘ “.
                 * 
                 * Input attack vectors:
                 * (a) someText' or username='alias
                 * (b) a' or 'a'='a
                 * 
                 * This function is designed to catch these types of attacks. */
                /* split the input into two sections. First variables contains everything from the
                 * start to the first occurrence (including) of the single quote.
                 * The second half contains everything after the first occurrence of the single quote. */
                string firstHalf = input.Substring(0, firstSingleQuoteIndex + 1);
                string secondHalf = input.Substring(firstSingleQuoteIndex + 1);
                /* Strip out any single quotes */
                secondHalf = secondHalf.Replace("'", string.Empty);
                string finalScrubbedInput = firstHalf + secondHalf;
                TSql100Parser parser = new TSql100Parser(false);
                IList<ParseError> errors;
                /* Try input with permutation. If input completes an invalid and partial SQL,
                 * then there is potential for an attack. This will capture cases where
                 * attackers attempt to escape out of valid SQL or modify logic. (i.e. OR 1=1)
                 */
                const string SqlCommandPrefix = "SELECT * FROM USERS WHERE ID='";
                string completeSql = SqlCommandPrefix + finalScrubbedInput;
                using (StringReader sr = new StringReader(completeSql))
                {
                    parser.Parse(sr, out errors);
                }
                return errors == null || errors.Count <= 0;
            }
            /// <summary>
            /// Detects partial SQL command injection.
            /// </summary>
            /// <param name="input">The input to check.</param>
            /// <returns>True if a partial command has been detected, otherwise false.</returns>
            private static bool DetectPartialSql(string input)
            {
                // Only processing input greater than 2 characters
                if (input.Length < 3)
                {
                    return false;
                }
                TSql100Parser parser = new TSql100Parser(false);
                IList<ParseError> errors;
                // Try input with permutation. If input completes an invalid and partial SQL,
                // then there is potential for an attack. This will capture cases where
                // attackers attempt to escape out of valid SQL or modify logic. (i.e. OR 1=1)
                const string StartSql = "SELECT * FROM USERS WHERE ID='";
                string completedSql = StartSql + input;
                using (StringReader sr = new StringReader(completedSql))
                {
                    parser.Parse(sr, out errors);
                }
                return errors == null || errors.Count <= 0;
            }
            /// <summary>
            /// Detects a complete SQL command in the specified input.
            /// </summary>
            /// <param name="input">The input to check.</param>
            /// <returns>True if a logic short circuit has been detected, otherwise false.</returns>
            private static bool DetectCompleteSql(string input)
            {
                // Parser treats strings of length 1 or 2 as stored procedure calls. These will be skipped as they do not form complete SQL.
                input = input.Trim();
                string[] numberOfTokens = input.Split(' ');
                if (numberOfTokens.Length < 3)
                {
                    return false;
                }
                // Try input in raw format. Detects complete SQL.
                using (StringReader sr = new StringReader(input))
                {
                    TSql100Parser parser = new TSql100Parser(false);
                    IList<ParseError> errors;
                    parser.Parse(sr, out errors);
                    return errors == null || errors.Count <= 0;
                }
            }
        }
    }
    
    
  • 相关阅读:
    20220528 08:00:01
    208. Implement Trie (Prefix Tree) (Rust version)
    【mq】从零开始实现 mq12消息的批量发送与回执
    【mq】从零开始实现 mq08配置优化 fluent
    【mq】从零开始实现 mq13注册鉴权 auth
    【mq】从零开始实现 mq10消费者拉取消息回执 pull message ack
    【mq】从零开始实现 mq09消费者拉取消息 pull message
    【mq】从零开始实现 mq11消费者消息回执添加分组信息 pull message ack groupName
    学习随笔
    算法随笔
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2057558.html
Copyright © 2020-2023  润新知