Esempio n. 1
0
 public static void SetEncryptParam(String ParamName, String ParamValue)
 {
     if (ParamName == "EncryptKey")
     {
         // do not use "~", seems to be a read-only accessor. Have to use the ApplicationPath to get a read-write copy.
         // Also requires that the user for the worker process (NETWORK USER, ASPNET etc..) be granted read/write to the web.config file
         System.Configuration.Configuration config =
             WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
         AppSettingsSection appsettings = (AppSettingsSection)config.GetSection("appSettings");
         appsettings.Settings[ParamName].Value    = ParamValue;
         appsettings.SectionInformation.ForceSave = true;
         config.Save(ConfigurationSaveMode.Full);
     }
     else
     {
         try
         {
             AppConfigManager.SetAppConfigValue(ParamName, ParamValue);
         }
         catch
         {
             throw new ArgumentException("You do not have a required Security AppConfig [" + ParamName + "] parameter in your database. Please run the latest database upgrade script, and restart your website!!");
         }
     }
 }
Esempio n. 2
0
        private void EnsureAppConfigsExist()
        {
            foreach (AppConfigAtomInfo acai in this.AtomAppConfigs)
            {
                if (!acai.HasCreateInfo || AppLogic.AppConfigExists(acai.Config.Name, 0))
                {
                    break;
                }

                AppConfigManager.CreateDBAndCacheAppConfig(acai.Config);
            }
        }
Esempio n. 3
0
        public SearchConfigurationAtom(String searchTerm, String htmlHeader, String title)
        {
            List <AppConfigAtomInfo> acinfo = new List <AppConfigAtomInfo>();
            IEnumerable <AppConfig>  acs    = AppConfigManager.SearchAppConfigs(searchTerm, 0);

            foreach (AppConfig ac in acs)
            {
                acinfo.Add(new AppConfigAtomInfo(ac));
            }

            AtomAppConfigs = acinfo;
            HTMLHeader     = htmlHeader;
            Title          = title;
        }
Esempio n. 4
0
        public SearchConfigurationAtom(string searchTerm, string htmlHeader, string title)
        {
            var acinfo = new List <AppConfigAtomInfo>();
            IEnumerable <AppConfig> acs = AppConfigManager.GetAppConfigs(0).Where(appConfig => appConfig.Name.ContainsIgnoreCase(searchTerm));

            foreach (AppConfig ac in acs)
            {
                acinfo.Add(new AppConfigAtomInfo(ac));
            }

            this.AtomAppConfigs = acinfo;
            this.HTMLHeader     = htmlHeader;
            this.Title          = title;
        }
Esempio n. 5
0
        private void EnsureAppConfigsExist()
        {
            foreach (AppConfigAtomInfo acai in this.AtomAppConfigs)
            {
                if (!acai.HasCreateInfo || AppConfigManager.AppConfigExists(acai.Config.Name))
                {
                    break;
                }

                AppConfigManager.AddAppConfig(
                    name: acai.Config.Name,
                    description: acai.Config.Description,
                    groupName: acai.Config.GroupName,
                    configValue: acai.Config.ConfigValue,
                    valueType: acai.Config.ValueType,
                    allowableValues: acai.Config.AllowableValues.ToDelimitedString(),
                    storeId: acai.Config.StoreId,
                    superOnly: acai.Config.SuperOnly);
            }
        }
Esempio n. 6
0
        private void InitFromXML(XmlDocument xmlDoc)
        {
            XmlNode headerNode = xmlDoc.SelectSingleNode("/ConfigurationAtom/HtmlHeader");
            String  header     = string.Empty;

            if (headerNode != null && !String.IsNullOrEmpty(headerNode.InnerText))
            {
                header = headerNode.InnerText;
            }

            XmlNode titleNode = xmlDoc.SelectSingleNode("/ConfigurationAtom/Title");
            string  title     = string.Empty;

            if (titleNode != null && !string.IsNullOrEmpty(titleNode.InnerText))
            {
                title = titleNode.InnerText;
            }

            List <AppConfigAtomInfo> configs = new List <AppConfigAtomInfo>();

            foreach (XmlNode acNode in xmlDoc.SelectNodes("/ConfigurationAtom/AppConfig"))
            {
                String name = null;

                XmlNode nameNode = acNode.SelectSingleNode("Name");
                if (nameNode == null || string.IsNullOrEmpty(nameNode.InnerText))
                {
                    throw new ArgumentException("Name node invalid.");
                }

                name = nameNode.InnerText;

                AppConfig ac            = AppConfigManager.GetAppConfig(0, nameNode.InnerText);
                Boolean   hasCreateInfo = false;
                if (ac == null)
                {
                    XmlNode createNode = acNode.SelectSingleNode("CreateValues");
                    if (createNode != null)
                    {
                        String        description     = string.Empty;
                        String        defaultValue    = string.Empty;
                        String        groupName       = "CUSTOM";
                        Boolean       superOnly       = false;
                        String        valueType       = "string";
                        List <String> allowableValues = new List <string>();

                        XmlNode descriptionNode = createNode.SelectSingleNode("Description");
                        if (descriptionNode != null && !String.IsNullOrEmpty(descriptionNode.InnerText))
                        {
                            description = descriptionNode.InnerText;
                        }

                        XmlNode defaultVauleNode = createNode.SelectSingleNode("DefaultValue");
                        if (defaultVauleNode != null && !String.IsNullOrEmpty(defaultVauleNode.InnerText))
                        {
                            defaultValue = defaultVauleNode.InnerText;
                        }

                        XmlNode groupNameNode = createNode.SelectSingleNode("GroupName");
                        if (groupNameNode != null && !String.IsNullOrEmpty(groupNameNode.InnerText))
                        {
                            groupName = groupNameNode.InnerText.ToUpper();
                        }

                        XmlNode superOnlyNode = createNode.SelectSingleNode("SuperOnly");
                        if (superOnlyNode != null && !String.IsNullOrEmpty(superOnlyNode.InnerText))
                        {
                            superOnly = superOnlyNode.InnerText.ToBool();
                        }

                        XmlNode valueTypeNode = createNode.SelectSingleNode("ValueType");
                        if (valueTypeNode != null && !String.IsNullOrEmpty(valueTypeNode.InnerText))
                        {
                            valueType = valueTypeNode.InnerText;
                        }

                        XmlNode allowableValuesNode = createNode.SelectSingleNode("AllowableValues");
                        if (allowableValuesNode != null && !String.IsNullOrEmpty(allowableValuesNode.InnerText))
                        {
                            allowableValues = allowableValuesNode.InnerText.Split(',').ToList();
                        }


                        ac            = new AppConfig(0, Guid.NewGuid(), name, description, defaultValue, groupName, superOnly, DateTime.Now, valueType, allowableValues);
                        ac.StoreId    = 0;
                        hasCreateInfo = true;
                    }
                }

                AppConfigAtomInfo acai = new AppConfigAtomInfo(ac);
                acai.HasCreateInfo = hasCreateInfo;

                if (acNode.Attributes["Required"] != null)
                {
                    acai.IsRequired = acNode.Attributes["Required"].InnerText.ToBool();
                }

                if (acNode.Attributes["Advanced"] != null)
                {
                    acai.IsAdvanced = acNode.Attributes["Advanced"].InnerText.ToBool();
                }

                if (acNode.Attributes["FriendlyName"] != null)
                {
                    acai.FriendlyName = acNode.Attributes["FriendlyName"].InnerText;
                }

                XmlNode contextualDescriptionNode = acNode.SelectSingleNode("ContextualDescription");
                if (contextualDescriptionNode != null && !String.IsNullOrEmpty(contextualDescriptionNode.InnerText))
                {
                    acai.ContextualDescription = contextualDescriptionNode.InnerText;
                }

                configs.Add(acai);
            }

            this.Init(configs, header, title);
        }
Esempio n. 7
0
        /// <summary>
        /// Performs an audit and returns a list of audit issues
        /// </summary>
        public static IEnumerable <SecurityAuditItem> GetAuditIssues(HttpRequestBase request = null)
        {
            // 1. Ensure that SSL is working on the admin site.  An issue with LiveServer can cause SSL not to function.
            if (!CommonLogic.IsSecureConnection())
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "Your Admin site is not currently using SSL.  This can allow data being sent to and from the admin site to be read in transit.  <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=ssl' target='_blank'>Click Here</a> to learn how to enable SSL.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 2. Check for path element containing /admin/. We do not allow Admin sites to be located at the default /admin/ path. Too easy to guess.
            if (request != null && request.Path.IndexOf("/admin/", StringComparison.InvariantCultureIgnoreCase) != -1)
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "The URL to your Admin site contains '/admin/'. This does not follow our <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=securitybestpractices' target='_blank'>security best practices</a>. Please immediately rename the Admin folder, and restart the website.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 3. Remove or change [email protected]. Cannot use the default credentials long-term.
            if (new Customer("*****@*****.**").EMail == "*****@*****.**")
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "The default user '*****@*****.**' is a registered user on this website. <a href='customers.aspx?filter.0.0=admin%40aspdotnetstorefront.com'>Click Here</a> to edit this user.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 4. Check MailMe_Server AppConfig Setting. Cannot Allow blank MailMe_Server AppConfig.
            var mailServerConfig = AppLogic.AppConfig("MailMe_Server");

            if (string.IsNullOrWhiteSpace(mailServerConfig) ||
                mailServerConfig.Equals(AppLogic.ro_TBD, StringComparison.InvariantCultureIgnoreCase) ||
                mailServerConfig.Equals("MAIL.YOURDOMAIN.COM", StringComparison.InvariantCultureIgnoreCase))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "The 'MailMe_Server' Setting is not properly configured. Click <a href=\"mailingtest.aspx\">here</a> to configure mail settings.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 5. Check for admin\assetmanager folder. Should be deleted.
            if (Directory.Exists(CommonLogic.SafeMapPath("assetmanager")))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "The obsolete folder 'assetmanager' exists in your site's Admin folder, and can present a security risk. Please delete this folder and its contents.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 6. Check for match between path and AdminDir. Verify that AdminDir is set correctly.
            if (request != null && request.Path.IndexOf(string.Format("/{0}/", AppLogic.AppConfig("AdminDir")), StringComparison.InvariantCultureIgnoreCase) == -1)
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "The URL to your Admin site does not match the 'AdminDir' Setting, which can lead to disclosure of your Admin URL. Please update the 'AdminDir' Setting, using the 'Configuration -> Settings' menu.",
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            if (AppLogic.TrustLevel == AspNetHostingPermissionLevel.Unrestricted || AppLogic.TrustLevel == AspNetHostingPermissionLevel.High)
            {
                var webConfig = WebConfigurationManager.OpenWebConfiguration("~");

                // 7. Check for debug=true in web.config. Should be false on a live site.
                var compilation = (CompilationSection)webConfig.GetSection("system.web/compilation");
                if (compilation.Debug == true)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "The 'compilation' element in web.config is set to 'debug=true'. Please set it to 'debug=false' to improve site performance.",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 8. Check encryption on web.config. Must be encrypted as the last step before going Live.
                var appSettings = webConfig.GetSection("appSettings");
                if (!appSettings.SectionInformation.IsProtected)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "The web.config file is not encrypted. This does not follow our <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=securitybestpractices' target='_blank'>security best practices</a>. Please use the <a href='wizard.aspx'>Site Setup Wizard</a> to encrypt the web.config file before going Live.",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 9. Check write permissions on web.config. Must have write-permission to encrypt, then have read-only permission after encryption.
                if (FileIsWriteable(CommonLogic.SafeMapPath("~/web.config")))
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "The file permission on web.config allows for write-access. This does not follow our <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=securitybestpractices' target=\"_blank\">security best practices</a>. Please set the web.config file as read-only before going Live.",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 10. Check non-write permissions on root. Cannot allow root folder to have write permission.
                if (FolderIsWriteable(CommonLogic.SafeMapPath("~/")))
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "The root directory of your website allows write-access. Please remove write-access before going Live. <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=golive' target='_blank'>Read more</a>",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 11. Check for customErrors Mode=Off in web.config. Should be RemoteOnly or On on a Live site.
                var customErrors = (CustomErrorsSection)webConfig.GetSection("system.web/customErrors");
                if (customErrors.Mode == CustomErrorsMode.Off)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "The 'customErrors' element in web.config is set to 'off'. Please set it to 'on' before going Live. <a href='http://www.aspdotnetstorefront.com/linkmanager.aspx?topic=10000manual&type=golive' target=\"_blank\">Read more</a>",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;
            }

            // 12. DotFeed is installed but not enabled.
            if (AppConfigManager.AppConfigExists("DotFeed.AccessKey") && string.IsNullOrEmpty(AppLogic.AppConfig("DotFeed.AccessKey")))
            {
                yield return new SecurityAuditItem()
                       {
                           Message = "DotFeed is installed but not enabled, <a href=\"https://manage.dotfeed.com\" target=\"_blank\">click here</a> to configure DotFeed",

                           ItemType = SecurityAuditItemType.Configuration
                       }
            }
            ;

            // 13. Site is using the default Search Engine Meta Title, Description, and Keywords tags.
            if (AppLogic.AppConfig("SE_MetaTitle").ContainsIgnoreCase("Enter your site title here") ||
                AppLogic.AppConfig("SE_MetaDescription").ContainsIgnoreCase("enter your site description here") ||
                AppLogic.AppConfig("SE_MetaKeywords").ContainsIgnoreCase("enter your site keywords here"))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = "Your site is using the default Search Engine Meta Title & Description tags, <a href=\"wizard.aspx#trSEO\">click here</a> to update.",
                           ItemType = SecurityAuditItemType.Configuration
                       }
            }
            ;

            // 14. Time to change the encrypt key
            var nextKeyChangeDate = DateTime.MinValue;

            if (AppLogic.AppConfigBool("StoreCCInDB") &&
                DateTime.TryParse(AppLogic.AppConfig("NextKeyChange"), out nextKeyChangeDate))
            {
                if (nextKeyChangeDate < DateTime.Now)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = "Time To Change Your Encrypt Key!",
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;
            }
        }
Esempio n. 8
0
        private void InitFromXML(XmlDocument xmlDoc)
        {
            var headerNode = xmlDoc.SelectSingleNode("/ConfigurationAtom/HtmlHeader");
            var header     = string.Empty;

            if (headerNode != null && !string.IsNullOrEmpty(headerNode.InnerText))
            {
                header = headerNode.InnerText;
            }

            var titleNode = xmlDoc.SelectSingleNode("/ConfigurationAtom/Title");
            var title     = string.Empty;

            if (titleNode != null && !string.IsNullOrEmpty(titleNode.InnerText))
            {
                title = titleNode.InnerText;
            }

            var configs = new List <AppConfigAtomInfo>();

            foreach (XmlNode acNode in xmlDoc.SelectNodes("/ConfigurationAtom/AppConfig"))
            {
                string name = null;

                var nameNode = acNode.SelectSingleNode("Name");
                if (nameNode == null || string.IsNullOrEmpty(nameNode.InnerText))
                {
                    throw new ArgumentException("Name node invalid.");
                }

                name = nameNode.InnerText;

                var  appConfig     = AppConfigManager.GetAppConfig(nameNode.InnerText);
                bool hasCreateInfo = false;
                if (appConfig == null)
                {
                    var createNode = acNode.SelectSingleNode("CreateValues");
                    if (createNode != null)
                    {
                        var  description     = string.Empty;
                        var  defaultValue    = string.Empty;
                        var  groupName       = "CUSTOM";
                        bool superOnly       = false;
                        var  valueType       = "string";
                        var  allowableValues = new List <string>();

                        var descriptionNode = createNode.SelectSingleNode("Description");
                        if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText))
                        {
                            description = descriptionNode.InnerText;
                        }

                        var defaultVauleNode = createNode.SelectSingleNode("DefaultValue");
                        if (defaultVauleNode != null && !string.IsNullOrEmpty(defaultVauleNode.InnerText))
                        {
                            defaultValue = defaultVauleNode.InnerText;
                        }

                        var groupNameNode = createNode.SelectSingleNode("GroupName");
                        if (groupNameNode != null && !string.IsNullOrEmpty(groupNameNode.InnerText))
                        {
                            groupName = groupNameNode.InnerText.ToUpper();
                        }

                        var superOnlyNode = createNode.SelectSingleNode("SuperOnly");
                        if (superOnlyNode != null && !string.IsNullOrEmpty(superOnlyNode.InnerText))
                        {
                            superOnly = superOnlyNode.InnerText.ToBool();
                        }

                        var valueTypeNode = createNode.SelectSingleNode("ValueType");
                        if (valueTypeNode != null && !string.IsNullOrEmpty(valueTypeNode.InnerText))
                        {
                            valueType = valueTypeNode.InnerText;
                        }

                        var allowableValuesNode = createNode.SelectSingleNode("AllowableValues");
                        if (allowableValuesNode != null && !string.IsNullOrEmpty(allowableValuesNode.InnerText))
                        {
                            allowableValues = allowableValuesNode.InnerText.Split(',').ToList();
                        }

                        appConfig = new AppConfig(
                            appConfigId: 0,
                            appConfigGuid: Guid.NewGuid(),
                            storeId: 0,
                            name: name,
                            description: description,
                            configValue: defaultValue,
                            groupName: groupName,
                            superOnly: superOnly,
                            createdOn: DateTime.Now,
                            updatedOn: DateTime.Now,
                            valueType: valueType,
                            allowableValues: allowableValues,
                            hidden: false);
                        hasCreateInfo = true;
                    }
                }

                var appConfigAtomInfo = new AppConfigAtomInfo(appConfig);
                appConfigAtomInfo.HasCreateInfo = hasCreateInfo;

                if (acNode.Attributes["Required"] != null)
                {
                    appConfigAtomInfo.IsRequired = acNode.Attributes["Required"].InnerText.ToBool();
                }

                if (acNode.Attributes["Advanced"] != null)
                {
                    appConfigAtomInfo.IsAdvanced = acNode.Attributes["Advanced"].InnerText.ToBool();
                }

                if (acNode.Attributes["FriendlyName"] != null)
                {
                    appConfigAtomInfo.FriendlyName = acNode.Attributes["FriendlyName"].InnerText;
                }

                var contextualDescriptionNode = acNode.SelectSingleNode("ContextualDescription");
                if (contextualDescriptionNode != null && !string.IsNullOrEmpty(contextualDescriptionNode.InnerText))
                {
                    appConfigAtomInfo.ContextualDescription = contextualDescriptionNode.InnerText;
                }

                configs.Add(appConfigAtomInfo);
            }

            this.Init(configs, header, title);
        }
Esempio n. 9
0
        /// <summary>
        /// Performs an audit and returns a list of audit issues
        /// </summary>
        public static IEnumerable <SecurityAuditItem> GetAuditIssues(HttpRequestBase request = null)
        {
            // 1. Ensure that SSL is working on the admin site.  An issue with LiveServer can cause SSL not to function.
            if (!CommonLogic.IsSecureConnection())
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.SSL"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 2. Check for path element containing /admin/. We do not allow Admin sites to be located at the default /admin/ path. Too easy to guess.
            if (request != null && request.Path.IndexOf("/admin/", StringComparison.InvariantCultureIgnoreCase) != -1)
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.PathElement"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 3. Remove or change [email protected]. Cannot use the default credentials long-term.
            if (new Customer("*****@*****.**").EMail == "*****@*****.**")
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.DefaultAdmin"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 4. Check MailMe_Server AppConfig Setting. Cannot Allow blank MailMe_Server AppConfig.
            var mailServerConfig = AppLogic.AppConfig("MailMe_Server");

            if (string.IsNullOrWhiteSpace(mailServerConfig) ||
                mailServerConfig.Equals(AppLogic.ro_TBD, StringComparison.InvariantCultureIgnoreCase) ||
                mailServerConfig.Equals("MAIL.YOURDOMAIN.COM", StringComparison.InvariantCultureIgnoreCase))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.MailServer"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 5. Check for admin\assetmanager folder. Should be deleted.
            if (Directory.Exists(CommonLogic.SafeMapPath("assetmanager")))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.AssetManager"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            // 6. Check for match between path and AdminDir. Verify that AdminDir is set correctly.
            if (request != null && request.Path.IndexOf(string.Format("/{0}/", AppLogic.AppConfig("AdminDir")), StringComparison.InvariantCultureIgnoreCase) == -1)
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.AdminDir"),
                           ItemType = SecurityAuditItemType.Security
                       }
            }
            ;

            if (AppLogic.TrustLevel == AspNetHostingPermissionLevel.Unrestricted || AppLogic.TrustLevel == AspNetHostingPermissionLevel.High)
            {
                var webConfig = WebConfigurationManager.OpenWebConfiguration("~");

                // 7. Check for debug=true in web.config. Should be false on a live site.
                var compilation = (CompilationSection)webConfig.GetSection("system.web/compilation");
                if (compilation.Debug == true)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.splash.aspx.security.Debug"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 8. Check encryption on web.config. Must be encrypted as the last step before going Live.
                var appSettings = webConfig.GetSection("appSettings");
                if (!appSettings.SectionInformation.IsProtected)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.splash.aspx.security.Encryption"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 9. Check write permissions on web.config. Must have write-permission to encrypt, then have read-only permission after encryption.
                if (FileIsWriteable(CommonLogic.SafeMapPath("~/web.config")))
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.splash.aspx.security.WebConfigWritable"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 10. Check non-write permissions on root. Cannot allow root folder to have write permission.
                if (FolderIsWriteable(CommonLogic.SafeMapPath("~/")))
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.splash.aspx.security.RootWritable"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;

                // 11. Check for customErrors Mode=Off in web.config. Should be RemoteOnly or On on a Live site.
                var customErrors = (CustomErrorsSection)webConfig.GetSection("system.web/customErrors");
                if (customErrors.Mode == CustomErrorsMode.Off)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.splash.aspx.security.CustomErrors"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;
            }

            // 12. DotFeed is installed but not enabled.
            if (AppConfigManager.AppConfigExists("DotFeed.AccessKey") && string.IsNullOrEmpty(AppLogic.AppConfig("DotFeed.AccessKey")))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.DotFeedNotEnabled"),
                           ItemType = SecurityAuditItemType.Configuration
                       }
            }
            ;

            // 13. Site is using the default Search Engine Meta Title, Description, and Keywords tags.
            if (AppLogic.AppConfig("SE_MetaTitle").ContainsIgnoreCase("Enter your site title here") ||
                AppLogic.AppConfig("SE_MetaDescription").ContainsIgnoreCase("enter your site description here") ||
                AppLogic.AppConfig("SE_MetaKeywords").ContainsIgnoreCase("enter your site keywords here"))
            {
                yield return new SecurityAuditItem()
                       {
                           Message  = AppLogic.GetString("admin.splash.aspx.security.MetaTagsNotSet"),
                           ItemType = SecurityAuditItemType.Configuration
                       }
            }
            ;

            // 14. Time to change the encrypt key
            var nextKeyChangeDate = DateTime.MinValue;

            if (AppLogic.AppConfigBool("StoreCCInDB") &&
                DateTime.TryParse(AppLogic.AppConfig("NextKeyChange"), out nextKeyChangeDate))
            {
                if (nextKeyChangeDate < DateTime.Now)
                {
                    yield return new SecurityAuditItem()
                           {
                               Message  = AppLogic.GetString("admin.default.ChangeEncryptKey"),
                               ItemType = SecurityAuditItemType.Security
                           }
                }
                ;
            }
        }