protected CspDirectiveAttributeBase()
 {
     DirectiveConfig = new CspDirectiveOverride()
     {
         Enabled = true,
         InheritOtherSources = true
     };
     _headerConfigurationOverrideHelper = new CspConfigurationOverrideHelper();
     _headerOverrideHelper = new HeaderOverrideHelper();
 }
        public void GetOverridenCspDirectiveConfig_EnabledOverride_EnabledOverriden([Values(true, false)] bool expectedResult)
        {
            var directiveConfig = new CspDirectiveConfiguration { Enabled = !expectedResult };
            var directiveOverride = new CspDirectiveOverride { Enabled = expectedResult };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.AreEqual(expectedResult, newConfig.Enabled);
        }
        public ICspDirectiveConfiguration GetOverridenCspDirectiveConfig(CspDirectiveOverride directiveOverride, ICspDirectiveConfiguration directiveConfig)
        {
            if (directiveOverride.None.HasValue && (bool)directiveOverride.None)
            {
                //When 'none' is true we don't want any other sources
                return new CspDirectiveConfiguration { NoneSrc = true };
            }

            var result = directiveConfig ?? new CspDirectiveConfiguration();

            result.Enabled = directiveOverride.Enabled;

            if (directiveOverride.None.HasValue)
            {
                result.NoneSrc = (bool)directiveOverride.None;
            }

            //Keep track if other sources have been enabled, so none must be disabled.
            var disableNone = false;
            if (directiveOverride.Self.HasValue)
            {
                result.SelfSrc = (bool)directiveOverride.Self;
                disableNone = result.SelfSrc;
            }

            if (directiveOverride.UnsafeEval.HasValue)
            {
                result.UnsafeEvalSrc = (bool)directiveOverride.UnsafeEval;
                disableNone = disableNone || result.UnsafeEvalSrc;
            }

            if (directiveOverride.UnsafeInline.HasValue)
            {
                result.UnsafeInlineSrc = (bool)directiveOverride.UnsafeInline;
                disableNone = disableNone || result.UnsafeInlineSrc;
            }

            if (!directiveOverride.InheritOtherSources)
            {
                result.CustomSources = EmptySources;
            }

            if (directiveOverride.OtherSources != null && directiveOverride.OtherSources.Length > 0)
            {
                var newSources = new List<string>(result.CustomSources);
                newSources.AddRange(directiveOverride.OtherSources);
                result.CustomSources = newSources.Distinct();
                disableNone = true;
            }

            if (disableNone)
            {
                result.NoneSrc = false;
            }

            return result;
        }
        public void GetOverridenCspDirectiveConfig_NullConfig_ReturnsNewDefaultConfig()
        {
            var directiveConfig = new CspDirectiveConfiguration();
            var directiveOverride = new CspDirectiveOverride { Enabled = directiveConfig.Enabled };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, null);

            Assert.AreNotSame(directiveConfig, newConfig);
            Assert.That(newConfig, Is.EqualTo(directiveConfig).Using(new CspDirectiveConfigurationComparer()));
        }
        internal void SetCspDirectiveOverride(HttpContextBase context, CspDirectives directive, CspDirectiveOverride config, bool reportOnly)
        {
            var overrides = _contextConfigurationHelper.GetCspConfigurationOverride(context, reportOnly, false);

            var directiveToOverride = _configMapper.GetCspDirectiveConfig(overrides, directive);

            if (directiveToOverride == null)
            {
                var baseConfig = _contextConfigurationHelper.GetCspConfiguration(context, reportOnly);
                directiveToOverride = _configMapper.GetCspDirectiveConfigCloned(baseConfig, directive);
            }

            var newConfig = _cspDirectiveOverrideHelper.GetOverridenCspDirectiveConfig(config, directiveToOverride);

            _configMapper.SetCspDirectiveConfig(overrides, directive, newConfig);
        }
        public void GetOverridenCspDirectiveConfig_NoneDisabledOverride_OverridesNoneAndKeepsOtherSources()
        {
            var directiveConfig = new CspDirectiveConfiguration
            {
                NoneSrc = false,
                SelfSrc = true,
                Nonce = "hei",
                UnsafeEvalSrc = true,
                UnsafeInlineSrc = true,
                CustomSources = new[] { "nwebsec.com" }
            };
            var directiveOverride = new CspDirectiveOverride { None = false };


            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.That(newConfig, Is.EqualTo(directiveConfig).Using(new CspDirectiveConfigurationComparer()));
        }
        public void GetOverridenCspDirectiveConfig_NoneEnabledOverride_OverridesNoneAndDropsOtherSources()
        {
            //Overriding with 'none' should clear all other sources. 
            var directiveConfig = new CspDirectiveConfiguration
            {
                NoneSrc = false,
                SelfSrc = true,
                Nonce = "hei",
                UnsafeEvalSrc = true,
                UnsafeInlineSrc = true,
                CustomSources = new[] { "nwebsec.com" }
            };
            var directiveOverride = new CspDirectiveOverride { None = true };
            var expectedConfig = new CspDirectiveConfiguration { NoneSrc = true };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.That(newConfig, Is.EqualTo(expectedConfig).Using(new CspDirectiveConfigurationComparer()));
        }
        public void SetCspDirectiveOverride_HasOverride_OverridesExistingOverride([Values(false, true)]bool reportOnly,
            [ValueSource(typeof(CspCommonDirectives), "Directives")] CspDirectives directive)
        {

            var overrideConfig = new CspOverrideConfiguration();
            _contextHelper.Setup(h => h.GetCspConfigurationOverride(It.IsAny<HttpContextBase>(), reportOnly, false)).Returns(overrideConfig);
            //There's an override for directive
            var currentDirectiveOverride = new CspDirectiveConfiguration();
            _directiveConfigMapper.Setup(m => m.GetCspDirectiveConfig(overrideConfig, directive)).Returns(currentDirectiveOverride);
            //We need an override and a result.
            var directiveOverride = new CspDirectiveOverride();
            var directiveOverrideResult = new CspDirectiveConfiguration();
            _directiveOverrideHelper.Setup(h => h.GetOverridenCspDirectiveConfig(directiveOverride, currentDirectiveOverride)).Returns(directiveOverrideResult);
            //This should be called at the very end
            _directiveConfigMapper.Setup(m => m.SetCspDirectiveConfig(overrideConfig, directive, directiveOverrideResult));

            CspConfigurationOverrideHelper.SetCspDirectiveOverride(MockContext, directive, directiveOverride, reportOnly);

            //Verify that the override result was set on the override config.
            _directiveConfigMapper.Verify(m => m.SetCspDirectiveConfig(overrideConfig, directive, directiveOverrideResult), Times.Once);
        }
        public void SetCspDirectiveOverride_NoCurrentOverride_ClonesConfigFromContextAndOverrides([Values(false, true)]bool reportOnly,
            [ValueSource(typeof(CspCommonDirectives), "Directives")] CspDirectives directive)
        {

            var contextConfig = new CspConfiguration();
            var overrideConfig = new CspOverrideConfiguration();
            //Returns CSP config from context
            _contextHelper.Setup(h => h.GetCspConfiguration(It.IsAny<HttpContextBase>(), reportOnly)).Returns(contextConfig);
            _contextHelper.Setup(h => h.GetCspConfigurationOverride(It.IsAny<HttpContextBase>(), reportOnly, false)).Returns(overrideConfig);
            //There's no override for directive
            _directiveConfigMapper.Setup(m => m.GetCspDirectiveConfig(overrideConfig, directive)).Returns((ICspDirectiveConfiguration)null);
            //Returns cloned directive config from context config
            var clonedContextDirective = new CspDirectiveConfiguration();
            _directiveConfigMapper.Setup(m => m.GetCspDirectiveConfigCloned(contextConfig, directive)).Returns(clonedContextDirective);
            //We need an override and a result.
            var directiveOverride = new CspDirectiveOverride();
            var directiveOverrideResult = new CspDirectiveConfiguration();
            _directiveOverrideHelper.Setup(h => h.GetOverridenCspDirectiveConfig(directiveOverride, clonedContextDirective)).Returns(directiveOverrideResult);
            //This should be called at the very end
            _directiveConfigMapper.Setup(m => m.SetCspDirectiveConfig(overrideConfig, directive, directiveOverrideResult));

            CspConfigurationOverrideHelper.SetCspDirectiveOverride(MockContext, directive, directiveOverride, reportOnly);

            //Verify that the override result was set on the override config.
            _directiveConfigMapper.Verify(m => m.SetCspDirectiveConfig(overrideConfig, directive, directiveOverrideResult), Times.Once);
        }
        public void GetOverridenCspDirectiveConfig_CustomSourcesOverrideWithSourcesInherited_KeepsAllSources()
        {
            var directiveConfig = new CspDirectiveConfiguration { CustomSources = new[] { "transformtool.codeplex.com", "nwebsec.codeplex.com" } };
            var directiveOverride = new CspDirectiveOverride { OtherSources = new[] { "nwebsec.codeplex.com" }, InheritOtherSources = true };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.AreEqual(2, newConfig.CustomSources.Count());
            Assert.Contains("transformtool.codeplex.com", newConfig.CustomSources.ToList());
            Assert.Contains("nwebsec.codeplex.com", newConfig.CustomSources.ToList());
        }
        public void GetOverridenCspDirectiveConfig_CustomSourcesOverride_OverriddesCustomSources()
        {
            var directiveConfig = new CspDirectiveConfiguration { CustomSources = new[] { "www.nwebsec.com" } };
            var directiveOverride = new CspDirectiveOverride { OtherSources = new[] { "*.nwebsec.com" }, InheritOtherSources = false };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.IsFalse(newConfig.SelfSrc);
            Assert.IsTrue(newConfig.CustomSources.Count() == 1);
            Assert.IsTrue(newConfig.CustomSources.First().Equals("*.nwebsec.com"));
        }
        public void GetOverridenCspDirectiveConfig_NoCustomSourcesOverride_KeepsCustomSources()
        {
            var expectedSources = new[] { "www.nwebsec.com" };
            var directiveConfig = new CspDirectiveConfiguration { CustomSources = expectedSources };
            var directiveOverride = new CspDirectiveOverride { InheritOtherSources = true };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.IsTrue(expectedSources.SequenceEqual(newConfig.CustomSources), "CustomSources differed.");
        }
        public void GetOverridenCspDirectiveConfig_UnsafeInlineInherit_InheritsUnsafeInline([Values(true, false)] bool expectedResult)
        {
            var directiveConfig = new CspDirectiveConfiguration { UnsafeInlineSrc = expectedResult };
            var directiveOverride = new CspDirectiveOverride();

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.AreEqual(expectedResult, newConfig.UnsafeInlineSrc);
        }
        public void GetOverridenCspDirectiveConfig_UnsafeEvalOverride_OverridesUnsafeEval([Values(true, false)] bool expectedResult)
        {
            var directiveConfig = new CspDirectiveConfiguration { UnsafeEvalSrc = !expectedResult };
            var directiveOverride = new CspDirectiveOverride { UnsafeEval = expectedResult };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.AreEqual(expectedResult, newConfig.UnsafeEvalSrc);
        }
        public void GetOverridenCspDirectiveConfig_SelfOverride_OverridesSelf([Values(true, false)] bool expectedResult)
        {
            var directiveConfig = new CspDirectiveConfiguration { SelfSrc = !expectedResult };
            var directiveOverride = new CspDirectiveOverride { Self = expectedResult };

            var newConfig = _overrideHelper.GetOverridenCspDirectiveConfig(directiveOverride, directiveConfig);

            Assert.AreEqual(expectedResult, newConfig.SelfSrc);
        }