public void ConfigureRules()
        {
            List <string> rulePaths = new List <string>();

            if (!string.IsNullOrEmpty(_arg_customRulesPath))
            {
                rulePaths.Add(_arg_customRulesPath);
            }

            foreach (string rulePath in rulePaths)
            {
                if (Directory.Exists(rulePath))
                {
                    _rulesSet.AddDirectory(rulePath);
                }
                else if (File.Exists(rulePath))
                {
                    _rulesSet.AddFile(rulePath);
                }
                else
                {
                    throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, rulePath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rulesSet.Count() == 0)
            {
                throw new OpException(ErrMsg.GetString(ErrMsg.ID.CMD_NORULES_SPECIFIED));
            }
        }
        void ConfigRules()
        {
            if (!_arg_ignoreDefaultRules)
            {
                _rules = Utils.GetDefaultRuleSet(_arg_logger);
            }

            if (!string.IsNullOrEmpty(_arg_customRulesPath))
            {
                if (_rules == null)
                {
                    _rules = new RuleSet(_arg_logger);
                }

                if (Directory.Exists(_arg_customRulesPath))
                {
                    _rules.AddDirectory(_arg_customRulesPath);
                }
                else if (File.Exists(_arg_customRulesPath))
                {
                    _rules.AddFile(_arg_customRulesPath);
                }
                else
                {
                    throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, _arg_customRulesPath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules == null || _rules.Count() == 0)
            {
                throw new OpException(ErrMsg.GetString(ErrMsg.ID.CMD_NORULES_SPECIFIED));
            }
        }
예제 #3
0
        private void ConfigRules()
        {
            _logger.LogTrace("ExportTagsCommand::ConfigRules");
            _rules = new RuleSet(_loggerFactory);
            if (!_options.IgnoreDefaultRules)
            {
                _rules = RuleSetUtils.GetDefaultRuleSet(_loggerFactory);
            }

            if (!string.IsNullOrEmpty(_options?.CustomRulesPath))
            {
                if (Directory.Exists(_options.CustomRulesPath))
                {
                    _rules.AddDirectory(_options.CustomRulesPath);
                }
                else if (File.Exists(_options.CustomRulesPath))
                {
                    _rules.AddFile(_options.CustomRulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _options.CustomRulesPath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules == null || !_rules.Any())
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }
        }
예제 #4
0
        public RuleSet LoadRules(bool loadCustomRules)
        {
            RuleSet rules = RuleSet.FromDirectory(Path.Combine("rules", "valid"), null);

            if (loadCustomRules)
            {
                rules.AddDirectory(Path.Combine("rules", "custom"), "my rules");
            }

            return(rules);
        }
예제 #5
0
        /// <summary>
        ///     Reloads rules based on settings
        /// </summary>
        private void LoadRules()
        {
            Settings set = Settings.GetSettings();

            try
            {
                Assembly assembly = Assembly.GetAssembly(typeof(Boundary));
                string   filePath = "Microsoft.DevSkim.Resources.devskim-rules.json";
                Stream   resource = assembly.GetManifestResourceStream(filePath);

                if (set.UseDefaultRules)
                {
                    using (StreamReader file = new StreamReader(resource))
                    {
                        ruleset.AddString(file.ReadToEnd(), filePath);
                    }
                }
            }
            catch (Exception e) {
                Debug.WriteLine("Failed to load Default rules. {0}:{1}\n{2}", e.GetType(), e.Message, e.StackTrace);
            }

            try {
                if (set.UseCustomRules && Directory.Exists(set.CustomRulesPath))
                {
                    ruleset.AddDirectory(set.CustomRulesPath, "custom");
                }
            }
            catch (Exception e) {
                Debug.WriteLine("Failed to load custom rules. {0}:{1}\n{2}", e.GetType(), e.Message, e.StackTrace);
            }

            processor.Rules = ruleset;

            processor.SeverityLevel = Severity.Critical;

            if (set.EnableImportantRules)
            {
                processor.SeverityLevel |= Severity.Important;
            }
            if (set.EnableModerateRules)
            {
                processor.SeverityLevel |= Severity.Moderate;
            }
            if (set.EnableBestPracticeRules)
            {
                processor.SeverityLevel |= Severity.BestPractice;
            }
            if (set.EnableManualReviewRules)
            {
                processor.SeverityLevel |= Severity.ManualReview;
            }
        }
예제 #6
0
        public void UseCase_OnError_Test()
        {
            bool error = false;

            RuleSet rules = new RuleSet();

            rules.OnDeserializationError += delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
            {
                error = true;
                args.ErrorContext.Handled = true;
            };

            rules.AddDirectory(Path.Combine("rules", "invalid"), null);
            Assert.IsTrue(error, "Error should be raised");
        }
예제 #7
0
        /// <summary>
        /// Reloads rules based on settings
        /// </summary>
        private void LoadRules()
        {
            Settings set = Settings.GetSettings();

            ruleset = new RuleSet();

            Assembly assembly = Assembly.GetAssembly(typeof(Boundary));
            string   filePath = "Microsoft.DevSkim.Resources.devskim-rules.json";
            Stream   resource = assembly.GetManifestResourceStream(filePath);

            if (set.UseDefaultRules)
            {
                using (StreamReader file = new StreamReader(resource))
                {
                    ruleset.AddString(file.ReadToEnd(), filePath);
                }
            }

            if (set.UseCustomRules)
            {
                ruleset.AddDirectory(set.CustomRulesPath, "custom");
            }

            processor.Rules = ruleset;

            processor.SeverityLevel = Severity.Critical;

            if (set.EnableImportantRules)
            {
                processor.SeverityLevel |= Severity.Important;
            }
            if (set.EnableModerateRules)
            {
                processor.SeverityLevel |= Severity.Moderate;
            }
            if (set.EnableBestPracticeRules)
            {
                processor.SeverityLevel |= Severity.BestPractice;
            }
            if (set.EnableManualReviewRules)
            {
                processor.SeverityLevel |= Severity.ManualReview;
            }
        }
        void ConfigRules()
        {
            List <string> rulePaths = new List <string>();

            if (!_arg_ignoreDefaultRules)
            {
                Assembly assembly     = Assembly.GetExecutingAssembly();
                string[] resourceName = assembly.GetManifestResourceNames();
                string   filePath     = "Microsoft.ApplicationInspector.Commands.defaultRules.json";
                Stream   resource     = assembly.GetManifestResourceStream(filePath);
                using (StreamReader file = new StreamReader(resource))
                {
                    _rules.AddString(file.ReadToEnd(), filePath, null);
                }
            }

            if (!string.IsNullOrEmpty(_arg_customRulesPath))
            {
                rulePaths.Add(_arg_customRulesPath);
            }

            foreach (string rulePath in rulePaths)
            {
                if (Directory.Exists(rulePath))
                {
                    _rules.AddDirectory(rulePath);
                }
                else if (File.Exists(rulePath))
                {
                    _rules.AddFile(rulePath);
                }
                else
                {
                    throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, rulePath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules.Count() == 0)
            {
                throw new OpException(ErrMsg.GetString(ErrMsg.ID.CMD_NORULES_SPECIFIED));
            }
        }
예제 #9
0
        /// <summary>
        /// Reloads rules based on settings
        /// </summary>
        private void LoadRules()
        {
            Settings set = Settings.GetSettings();

            ruleset = new RuleSet();
            string rulesFile = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            rulesFile = Path.Combine(Path.Combine(rulesFile, "Content"), "devskim-rules.json");
            if (set.UseDefaultRules)
            {
                ruleset.AddFile(rulesFile, null);
            }

            if (set.UseCustomRules)
            {
                ruleset.AddDirectory(set.CustomRulesPath, "custom");
            }

            processor.Rules = ruleset;

            processor.SeverityLevel = Severity.Critical;

            if (set.EnableImportantRules)
            {
                processor.SeverityLevel |= Severity.Important;
            }
            if (set.EnableModerateRules)
            {
                processor.SeverityLevel |= Severity.Moderate;
            }
            if (set.EnableBestPracticeRules)
            {
                processor.SeverityLevel |= Severity.BestPractice;
            }
            if (set.EnableManualReviewRules)
            {
                processor.SeverityLevel |= Severity.ManualReview;
            }
        }
예제 #10
0
        private void ConfigRules()
        {
            WriteOnce.SafeLog("ExportTagsCommand::ConfigRules", LogLevel.Trace);

            if (!_options.IgnoreDefaultRules)
            {
                _rules = Utils.GetDefaultRuleSet(_options.Log);
            }

            if (!string.IsNullOrEmpty(_options.CustomRulesPath))
            {
                if (_rules == null)
                {
                    _rules = new RuleSet(_options.Log);
                }

                if (Directory.Exists(_options.CustomRulesPath))
                {
                    _rules.AddDirectory(_options.CustomRulesPath);
                }
                else if (File.Exists(_options.CustomRulesPath))
                {
                    _rules.AddFile(_options.CustomRulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _options.CustomRulesPath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules == null || _rules.Count() == 0)
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }
        }
예제 #11
0
        /// <summary>
        /// Add default and/or custom rules paths
        /// Iterate paths and add to ruleset
        /// </summary>
        void ConfigRules()
        {
            WriteOnce.SafeLog("AnalyzeCommand::ConfigRules", LogLevel.Trace);

            RuleSet       rulesSet  = new RuleSet(_arg_logger);
            List <string> rulePaths = new List <string>();

            if (!_arg_ignoreDefaultRules)
            {
                rulePaths.Add(Utils.GetPath(Utils.AppPath.defaultRules));
            }

            if (!string.IsNullOrEmpty(_arg_customRulesPath))
            {
                rulePaths.Add(_arg_customRulesPath);
            }

            foreach (string rulePath in rulePaths)
            {
                if (Directory.Exists(rulePath))
                {
                    rulesSet.AddDirectory(rulePath);
                }
                else if (File.Exists(rulePath))
                {
                    rulesSet.AddFile(rulePath);
                }
                else
                {
                    throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, rulePath));
                }
            }

            //error check based on ruleset not path enumeration
            if (rulesSet.Count() == 0)
            {
                throw new OpException(ErrMsg.GetString(ErrMsg.ID.CMD_NORULES_SPECIFIED));
            }

            //instantiate a RuleProcessor with the added rules and exception for dependency
            _rulesProcessor = new RuleProcessor(rulesSet, _arg_confidence, _arg_outputUniqueTagsOnly, _arg_simpleTagsOnly, _arg_logger);

            if (_arg_outputUniqueTagsOnly)
            {
                List <TagException> tagExceptions;
                if (File.Exists(Utils.GetPath(Utils.AppPath.tagCounterPref)))
                {
                    tagExceptions = JsonConvert.DeserializeObject <List <TagException> >(File.ReadAllText(Utils.GetPath(Utils.AppPath.tagCounterPref)));
                    string[] exceptions = new string[tagExceptions.Count];
                    for (int i = 0; i < tagExceptions.Count; i++)
                    {
                        exceptions[i] = tagExceptions[i].Tag;
                    }
                    _rulesProcessor.UniqueTagExceptions = exceptions;
                }
            }

            _appProfile      = new AppProfile(_arg_sourcePath, rulePaths, false, _arg_simpleTagsOnly, _arg_outputUniqueTagsOnly, _arg_autoBrowserOpen);
            _appProfile.Args = "analyze -f " + _arg_fileFormat + " -u " + _arg_outputUniqueTagsOnly.ToString().ToLower() + " -v " +
                               WriteOnce.Verbosity.ToString() + " -x " + _arg_confidence + " -i " + _arg_ignoreDefaultRules.ToString().ToLower();
        }
예제 #12
0
        /// <summary>
        ///     Analyzes a directory of files.
        /// </summary>
        /// <param name="directory"> directory to analyze. </param>
        /// <returns> List of tags identified </returns>
        public async Task <List <IssueRecord> > AnalyzeDirectory(string directory)
        {
            Logger.Trace("AnalyzeDirectory({0})", directory);

            var analysisResults = new List <IssueRecord>();

            RuleSet rules = new RuleSet();

            if (Options["disable-default-rules"] is bool disableDefaultRules && !disableDefaultRules)
            {
                var assembly = Assembly.GetExecutingAssembly();
                foreach (var resourceName in assembly.GetManifestResourceNames())
                {
                    if (resourceName.EndsWith(".json"))
                    {
                        try
                        {
                            var stream = assembly.GetManifestResourceStream(resourceName);
                            using var resourceStream = new StreamReader(stream ?? new MemoryStream());
                            rules.AddString(resourceStream.ReadToEnd(), resourceName);
                        }
                        catch (Exception ex)
                        {
                            Logger.Warn(ex, "Error loading {0}: {1}", resourceName, ex.Message);
                        }
                    }
                }
            }

            if (Options["custom-rule-directory"] is string customDirectory)
            {
                rules.AddDirectory(customDirectory);
            }

            if (!rules.Any())
            {
                Logger.Error("No rules were specified, unable to continue.");
                return(analysisResults); // empty
            }

            var processor = new RuleProcessor(rules)
            {
                EnableSuppressions = false,
                SeverityLevel      = (Severity)31
            };

            string[] fileList;

            if (Directory.Exists(directory))
            {
                fileList = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
            }
            else if (File.Exists(directory))
            {
                fileList = new string[] { directory };
            }
            else
            {
                Logger.Warn("{0} is neither a directory nor a file.", directory);
                return(analysisResults); // empty
            }

            foreach (var filename in fileList)
            {
                Logger.Trace($"Processing {filename}");

                // TODO: Make this more resilient
                if (IGNORE_FILES.Contains(Path.GetFileName(filename)))
                {
                    Logger.Trace($"Ignoring {filename}");
                    continue;
                }

                byte[] fileContents;
                try
                {
                    fileContents = File.ReadAllBytes(filename);
                }
                catch (Exception ex)
                {
                    Logger.Trace(ex, "File {0} cannot be read, ignoring.", filename);
                    continue;
                }

                var buffer = NormalizeFileContent(filename, fileContents);
                Logger.Debug("Normalization complete.");

                double MIN_CRYPTO_OP_DENSITY = 0.10;
                try
                {
                    // TODO don't do this if we disassembled native code
                    var cryptoOperationLikelihood = CalculateCryptoOpDensity(buffer);
                    Logger.Debug("Cryptographic operation density for {0} was {1}", filename, cryptoOperationLikelihood);

                    if (cryptoOperationLikelihood >= MIN_CRYPTO_OP_DENSITY)
                    {
                        analysisResults.Add(new IssueRecord(
                                                Filename: filename,
                                                Filesize: buffer.Length,
                                                TextSample: "n/a",
                                                Issue: new Issue(
                                                    Boundary: new Boundary(),
                                                    StartLocation: new Location(),
                                                    EndLocation: new Location(),
                                                    Rule: new Rule("Crypto Symbols")
                        {
                            Id          = "_CRYPTO_DENSITY",
                            Name        = "Cryptographic symbols",
                            Description = cryptoOperationLikelihood.ToString(),
                            Tags        = new string[]
                            {
                                "Cryptography.GenericImplementation.HighDensityOperators"
                            }
                        }
                                                    )
                                                ));
                    }
                    Logger.Debug($"Analyzing {filename}, length={buffer.Length}");

                    Issue[]? fileResults = null;
                    var task = Task.Run(() => processor.Analyze(buffer, Language.FromFileName(filename)));
                    if (task.Wait(TimeSpan.FromSeconds(2)))
                    {
                        fileResults = task.Result;
                    }
                    else
                    {
                        Logger.Debug("DevSkim operation timed out.");
                        return(analysisResults);
                    }

                    Logger.Debug("Operation Complete: {0}", fileResults?.Length);
                    foreach (var issue in fileResults ?? Array.Empty <Issue>())
                    {
                        var fileContentArray = buffer.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                        var excerpt          = new List <string>();
                        var startLoc         = Math.Max(issue.StartLocation.Line - 1, 0);
                        var endLoc           = Math.Min(issue.EndLocation.Line + 1, fileContentArray.Length - 1);
                        for (int i = startLoc; i <= endLoc; i++)
                        {
                            excerpt.Add(fileContentArray[i].Trim());
                        }

                        analysisResults.Add(new IssueRecord(
                                                Filename: filename,
                                                Filesize: buffer.Length,
                                                TextSample: issue.StartLocation.Line + " => " + string.Join(Environment.NewLine, excerpt),
                                                Issue: issue)
                                            );
                    }
                }
                catch (Exception ex)
                {
                    Logger.Warn(ex, "Error analyzing {0}: {1}", filename, ex.Message);
                    Logger.Warn(ex.StackTrace);
                }
            }

            return(analysisResults);
        }