/// <summary>
        /// Adds support for the <a href="https://developers.facebook.com/docs/plugins/page-plugin">Facebook Page Plugin</a> to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        /// <remarks>Facebook only needs style-src 'sha256-W2kUcrmSyYrtLKKok5R0tuGKVjGmCtnA6wr7AIdSwgU=' rather than unsafe-inline, but if a hash or nonce is used then unsafe-inline is ignored for others that need it (ie Twitter)</remarks>
        public static CspOptions AddFacebook(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ScriptSrc == null)
            {
                updated.ScriptSrc = ScriptCspDirective.Empty;
            }
            updated.ScriptSrc = updated.ScriptSrc.AddSource("https://connect.facebook.net");

            if (updated.ImgSrc == null)
            {
                updated.ImgSrc = CspDirective.Empty;
            }
            updated.ImgSrc = updated.ImgSrc.AddSource("https://www.facebook.com");

            if (updated.FrameSrc == null)
            {
                updated.FrameSrc = CspDirective.Empty;
            }
            updated.FrameSrc = updated.FrameSrc.AddSource("https://*.facebook.com");

            if (updated.StyleSrc == null)
            {
                updated.StyleSrc = StyleCspDirective.Empty;
            }
            updated.StyleSrc = updated.StyleSrc.AddUnsafeInline();

            return(updated);
        }
Exemplo n.º 2
0
    /// <summary>
    /// Construct a new CspHeader
    /// </summary>
    /// <param name="options">The CspOptions to configure the header with</param>
    public CspHeader(CspOptions options)
    {
        options.EnsureNotNull(nameof(options));

        Key   = $"Content-Security-Policy{(options.IsReportOnly ? "-Report-Only" : string.Empty)}";
        Value = string.Concat(options.Directives);
    }
        /// <summary>
        /// Adds support for Google Maps to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddGoogleMaps(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ScriptSrc == null)
            {
                updated.ScriptSrc = ScriptCspDirective.Empty;
            }
            updated.ScriptSrc = updated.ScriptSrc.AddSource("https://*.googleapis.com").AddSource("https://maps.gstatic.com").AddUnsafeEval();

            if (updated.ImgSrc == null)
            {
                updated.ImgSrc = CspDirective.Empty;
            }
            updated.ImgSrc = updated.ImgSrc.AddSource("https://*.gstatic.com").AddSource("https://*.googleapis.com").AddSource("https://*.ggpht.com");

            if (updated.StyleSrc == null)
            {
                updated.StyleSrc = StyleCspDirective.Empty;
            }
            updated.StyleSrc = updated.StyleSrc.AddUnsafeInline();

            if (updated.FrameSrc == null)
            {
                updated.FrameSrc = CspDirective.Empty;
            }
            updated.FrameSrc = updated.FrameSrc.AddSource("https://maps.google.co.uk").AddSource("https://www.google.com");

            return(updated);
        }
Exemplo n.º 4
0
        public static void AddScriptCspHeaders(this HttpResponse response, CspOptions options, string hash)
        {
            var csp1part  = options.Level == CspLevel.One ? "'unsafe-inline' " : string.Empty;
            var cspHeader = $"default-src 'none'; script-src {csp1part}'{hash}'";

            AddCspHeaders(response.Headers, options, cspHeader);
        }
        /// <summary>
        /// Adds support for client-side Ordnance Survey maps to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddOrdnanceSurveyMaps(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ScriptSrc == null)
            {
                updated.ScriptSrc = ScriptCspDirective.Empty;
            }
            updated.ScriptSrc = updated.ScriptSrc.AddSource("https://maps1.eastsussex.gov.uk")
                                .AddSource("https://maps2.eastsussex.gov.uk")
                                .AddSource("https://cdnjs.cloudflare.com")
                                .AddSource("https://serverapi.arcgisonline.com")
                                .AddUnsafeEval();

            if (updated.StyleSrc == null)
            {
                updated.StyleSrc = StyleCspDirective.Empty;
            }
            updated.StyleSrc = updated.StyleSrc.AddSource("https://serverapi.arcgisonline.com").AddUnsafeInline();

            if (updated.ImgSrc == null)
            {
                updated.ImgSrc = CspDirective.Empty;
            }
            updated.ImgSrc = updated.ImgSrc.AddSource("https://maps1.eastsussex.gov.uk").AddSource("https://maps2.eastsussex.gov.uk").AddSource("https://serverapi.arcgisonline.com");

            return(updated);
        }
Exemplo n.º 6
0
        public void ManyOptions_ResultIsCorrect()
        {
            var options = new CspOptions
            {
                Default = new CspDefaultSrcOptions
                {
                    AllowSelf = true
                },
                Img = new CspImgSrcOptions
                {
                    AllowAny = true
                },
                Media = new CspMediaSrcOptions
                {
                    AllowedSources = new List <string>
                    {
                        "media1.com",
                        "media2.com"
                    }
                },
                Script = new CspScriptSrcOptions
                {
                    AllowedSources = new List <string>
                    {
                        "userscripts.example.com"
                    }
                }
            };

            var(headerName, headerValue) = options.ToString(null);

            Assert.Equal("Content-Security-Policy", headerName);
            Assert.Equal("default-src 'self';script-src userscripts.example.com;img-src *;media-src media1.com media2.com", headerValue);
        }
        /// <summary>
        /// Adds middleware for using CSP, which adds the Content-Security-Policy header.
        /// </summary>
        /// <param name="app">The <see cref="IApplicationBuilder"/> instance this method extends.</param>
        /// <param name="csp">Value to be set for Content-Security-Policy header.</param>
        /// <returns></returns>
        public static IApplicationBuilder UseCsp(this IApplicationBuilder app, string csp)
        {
            CspOptions options = new CspOptions {
                Content = csp
            };

            return(app.UseMiddleware <CspMiddleware>(options));
        }
        public void EnableSandbox_EnablesTheSandbox()
        {
            var builder = new CspBuilder();

            builder.EnableSandbox();
            CspOptions options = builder.BuildCspOptions();

            Assert.True(options.EnableSandbox);
        }
        public void SetReportOnly_SetsReportOnlyToTrue()
        {
            var builder = new CspBuilder();

            builder.SetReportOnly();
            CspOptions options = builder.BuildCspOptions();

            Assert.True(options.ReportOnly);
        }
        public void SetUpgradeInsecureRequests_SetsUpgradeInsecureRequestsToTrue()
        {
            var builder = new CspBuilder();

            builder.SetUpgradeInsecureRequests();
            CspOptions options = builder.BuildCspOptions();

            Assert.True(options.UpgradeInsecureRequests);
        }
        /// <summary>
        /// Adds middleware for using CSP, which adds the Content-Security-Policy header.
        /// </summary>
        /// <param name="app">The <see cref="IApplicationBuilder"/> instance this method extends.</param>
        /// <param name="builderAction">A delegate used for setting up the <see cref="CspOptionsBuilder"/>.</param>
        /// <returns></returns>
        public static IApplicationBuilder UseCsp(this IApplicationBuilder app, Action <CspOptionsBuilder> builderAction)
        {
            CspOptionsBuilder builder = new CspOptionsBuilder();

            builderAction(builder);
            CspOptions options = builder.Build();

            return(app.UseMiddleware <CspMiddleware>(options));
        }
        public void SetBlockAllMixedContent_SetsBlockAllMixedContentToTrue()
        {
            var builder = new CspBuilder();

            builder.SetBlockAllMixedContent();
            CspOptions options = builder.BuildCspOptions();

            Assert.True(options.BlockAllMixedContent);
        }
        public void ReportViolationsTo_SetsTheReportUri()
        {
            var builder = new CspBuilder();

            builder.ReportViolationsTo("/somewhere");
            CspOptions options = builder.BuildCspOptions();

            Assert.Equal("/somewhere", options.ReportUri);
        }
Exemplo n.º 14
0
        public void IncludeXHeader_SetsIncludeXHeaderToTrue()
        {
            var builder = new CspBuilder();

            builder.IncludeXHeader();
            CspOptions options = builder.BuildCspOptions();

            Assert.True(options.IncludeXHeader);
        }
Exemplo n.º 15
0
        public void UpgradeInsecureRequests_ValueIsCorrect()
        {
            var options = new CspOptions
            {
                UpgradeInsecureRequests = true
            };

            string policy = options.ToString(null).headerValue;

            Assert.Equal("upgrade-insecure-requests", policy);
        }
Exemplo n.º 16
0
        public void BlockAllMixedContent_ValueIsCorrect()
        {
            var options = new CspOptions
            {
                BlockAllMixedContent = true
            };

            string policy = options.ToString(null).headerValue;

            Assert.Equal("block-all-mixed-content", policy);
        }
Exemplo n.º 17
0
 public static void AddCspHeaders(this IHeaderDictionary headers, CspOptions options, string cspHeader)
 {
     if (!headers.ContainsKey("Content-Security-Policy"))
     {
         headers.Add("Content-Security-Policy", cspHeader);
     }
     if (options.AddDeprecatedHeader && !headers.ContainsKey("X-Content-Security-Policy"))
     {
         headers.Add("X-Content-Security-Policy", cspHeader);
     }
 }
        /// <summary>
        /// Adds support for Google Content Experiments to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddGoogleContentExperiments(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ScriptSrc == null)
            {
                updated.ScriptSrc = ScriptCspDirective.Empty;
            }
            updated.ScriptSrc = updated.ScriptSrc.AddUnsafeInline();

            return(updated);
        }
        /// <summary>
        /// Adds support for server-side Ordnance Survey maps to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddOldOrdnanceSurveyMaps(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ImgSrc == null)
            {
                updated.ImgSrc = CspDirective.Empty;
            }
            updated.ImgSrc = updated.ImgSrc.AddSource("https://maps2.eastsussex.gov.uk");

            return(updated);
        }
Exemplo n.º 20
0
        public static void AddStyleCspHeaders(this HttpResponse response, CspOptions options, string hash, string frameSources)
        {
            var csp1part  = options.Level == CspLevel.One ? "'unsafe-inline' " : string.Empty;
            var cspHeader = $"default-src 'none'; style-src {csp1part}'{hash}'";

            if (!string.IsNullOrEmpty(frameSources))
            {
                cspHeader += $"; frame-src {frameSources}";
            }

            AddCspHeaders(response.Headers, options, cspHeader);
        }
        public void ContentSecurityPolicyMiddleware_adds_policy_from_startup()
        {
            var context = new DefaultHttpContext();

            context.Response.ContentType = "text/html";
            var environment       = new Mock <IHostingEnvironment>();
            var policyFromStartup = new CspOptions().AddYouTube();

            ContentSecurityPolicyMiddleware.AddHeader(context, environment.Object, policyFromStartup, new List <ContentSecurityPolicyDependency>());

            Assert.Contains("https://www.youtube-nocookie.com", context.Response.Headers["Content-Security-Policy"].ToString());
        }
        /// <summary>
        /// Adds support for an ESCIS search widget to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddEscis(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.FrameSrc == null)
            {
                updated.FrameSrc = CspDirective.Empty;
            }
            updated.FrameSrc = updated.FrameSrc.AddSource("https://www.escis.org.uk");

            return(updated);
        }
        /// <summary>
        /// Adds support for an East Sussex 1Space search widget to an existing Content Security Policy
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static CspOptions AddEastSussex1Space(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ImgSrc == null)
            {
                updated.ImgSrc = CspDirective.Empty;
            }
            updated.ImgSrc = updated.ImgSrc.AddSource("https://1space.eastsussex.gov.uk");

            return(updated);
        }
Exemplo n.º 24
0
        public void Invoked_StringAdded()
        {
            //Arrange
            CspOptionsBuilder builder = new CspOptionsBuilder();

            //Act
            builder.BlockAllMixedContent();

            //Assert
            CspOptions options = builder.Build();

            Assert.Equal("block-all-mixed-content", options.Content);
        }
Exemplo n.º 25
0
        public void Invoked_StringAdded()
        {
            //Arrange
            CspOptionsBuilder builder = new CspOptionsBuilder();

            //Act
            builder.UpgradeInsecureRequests();

            //Assert
            CspOptions options = builder.Build();

            Assert.Equal("upgrade-insecure-requests", options.Content);
        }
Exemplo n.º 26
0
        public void BaseUriSelf_ValueIsCorrect()
        {
            var options = new CspOptions
            {
                BaseUri = new CspBaseUriOptions
                {
                    AllowSelf = true
                }
            };

            string policy = options.ToString(null).headerValue;

            Assert.Equal("base-uri 'self'", policy);
        }
        /// <summary>
        /// Adds support for localhost URLs to any directive of an existing Content Security Policy that already supports another source
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        /// <remarks>For use in development</remarks>
        public static CspOptions AddLocalhost(this CspOptions options)
        {
            var updated = options.Clone();

            if (updated.ChildSrc != null)
            {
                updated.ChildSrc = updated.ChildSrc.AddSource("https://localhost:*");
            }
            if (updated.ConnectSrc != null)
            {
                updated.ConnectSrc = updated.ConnectSrc.AddSource("https://localhost:*");
            }
            if (updated.FontSrc != null)
            {
                updated.FontSrc = updated.FontSrc.AddSource("https://localhost:*");
            }
            if (updated.FrameSrc != null)
            {
                updated.FrameSrc = updated.FrameSrc.AddSource("https://localhost:*");
            }
            if (updated.ImgSrc != null)
            {
                updated.ImgSrc = updated.ImgSrc.AddSource("https://localhost:*");
            }
            if (updated.ManifestSrc != null)
            {
                updated.ManifestSrc = updated.ManifestSrc.AddSource("https://localhost:*");
            }
            if (updated.MediaSrc != null)
            {
                updated.MediaSrc = updated.MediaSrc.AddSource("https://localhost:*");
            }
            if (updated.ObjectSrc != null)
            {
                updated.ObjectSrc = updated.ObjectSrc.AddSource("https://localhost:*");
            }
            if (updated.ScriptSrc != null)
            {
                updated.ScriptSrc = updated.ScriptSrc.AddSource("https://localhost:*");
            }
            if (updated.StyleSrc != null)
            {
                updated.StyleSrc = updated.StyleSrc.AddSource("https://localhost:*");
            }
            if (updated.WorkerSrc != null)
            {
                updated.WorkerSrc = updated.WorkerSrc.AddSource("https://localhost:*");
            }
            return(updated);
        }
Exemplo n.º 28
0
        public void WithoutReportOnly_HeaderNameIsCorrect()
        {
            var options = new CspOptions
            {
                Default = new CspDefaultSrcOptions
                {
                    AllowAny = true
                }
            };

            var(headerName, _) = options.ToString(null);

            Assert.Equal("Content-Security-Policy", headerName);
        }
        public void SomeBuildersReturnedDirectives_AllDirectivesIncluded()
        {
            //Arrange
            CspOptionsBuilder builder = new CspOptionsBuilder();

            //Act
            builder.ConnectSources.AllowSelf();
            builder.ScriptSources.AllowHosts("https://example.com");
            builder.Sandbox.AllowModals();

            //Assert
            CspOptions result = builder.Build();

            Assert.Equal("connect-src 'self'; script-src https://example.com; sandbox allow-modals", result.Content);
        }
Exemplo n.º 30
0
        public void UpgradeInsecureRequestsAndDefaultHttps_ValueIsCorrect()
        {
            var options = new CspOptions
            {
                UpgradeInsecureRequests = true,
                Default = new CspDefaultSrcOptions
                {
                    AllowOnlyHttps = true
                }
            };

            string policy = options.ToString(null).headerValue;

            Assert.Equal("upgrade-insecure-requests;default-src https:", policy);
        }
Exemplo n.º 31
0
 public void Setup()
 {
     _options = new CspOptions();
 }