Example #1
0
 /// <summary>
 /// Add Strict-Transport-Security max-age=0 to all requests.
 /// Tells the user-agent to remove, or not cache the host in the STS cache
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddStrictTransportSecurityNoCache(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new StrictTransportSecurityHeader($"max-age=0")));
 }
Example #2
0
 /// <summary>
 /// Add a Cross-Origin-Opener-Policy Header Report-Only to all requests
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="configure">Configure the COOP</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddCrossOriginOpenerPolicyReportOnly(this HeaderPolicyCollection policies, Action <CrossOriginOpenerPolicyBuilder> configure)
 {
     return(policies.ApplyPolicy(CrossOriginOpenerPolicyHeader.Build(configure, asReportOnly: true)));
 }
Example #3
0
 /// <summary>
 /// Add a Content-Security-Header-Report-Only to all requests
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="configure">Configure the CSP</param>
 public static HeaderPolicyCollection AddContentSecurityPolicyReportOnly(this HeaderPolicyCollection policies, Action <CspBuilder> configure)
 {
     return(policies.ApplyPolicy(ContentSecurityPolicyHeader.Build(configure, asReportOnly: true)));
 }
 /// <summary>
 /// Add X-XSS-Protection 0 to all requests.
 /// Disables the XSS Protections offered by the user-agent.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddXssProtectionDisabled(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(XssProtectionHeader.Disabled()));
 }
 /// <summary>
 /// Add X-XSS-Protection 1; report=http://site.com/report to all requests.
 /// A partially supported directive that tells the user-agent to report potential XSS attacks to a single URL. Data will be POST'd to the report URL in JSON format.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="reportUrl">The url to report potential XSS attacks to</param>
 public static HeaderPolicyCollection AddXssProtectionReport(this HeaderPolicyCollection policies, string reportUrl)
 {
     return(policies.ApplyPolicy(XssProtectionHeader.Block()));
 }
Example #6
0
 /// <summary>
 /// Add a Cross-Origin-Resource-Policy Header to all requests
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="configure">Configure the CORP</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddCrossOriginResourcePolicy(this HeaderPolicyCollection policies, Action <CrossOriginResourcePolicyBuilder> configure)
 {
     return(policies.ApplyPolicy(CrossOriginResourcePolicyHeader.Build(configure)));
 }
 /// <summary>
 /// Remove a custom header from all requests
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="header">The header value to remove</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection RemoveCustomHeader(this HeaderPolicyCollection policies, string header)
 {
     return(policies.ApplyPolicy(new RemoveCustomHeader(header)));
 }
Example #8
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                // 追蹤阻塞調用
                app.UseBlockingDetection();
                app.UseDeveloperExceptionPage();
            }

            if (Configuration.GetValue <bool>("MiniProfiler:Enable"))
            {
                app.UseMiniProfiler();
            }

            // 轉發標頭
            app.UseForwardedHeaders(new ForwardedHeadersOptions {
                ForwardedHeaders = ForwardedHeaders.All
            });

            #region Firewall

            /*
             * app.UseFirewall(
             *  FirewallRulesEngine
             *      .DenyAllAccess()
             *      .ExceptFromIPAddressRanges(allowedCIDRs)
             *      .ExceptFromIPAddresses(allowedIPs));
             */
            #endregion

            // 回應緩衝
            app.UseResponseBuffering();

            app.UseRouting();

            #region Security Headers
            var policyCollection = new HeaderPolicyCollection()
                                   .AddFrameOptionsDeny()
                                   .AddXssProtectionBlock()
                                   .AddContentTypeOptionsNoSniff()
                                   .AddReferrerPolicyStrictOriginWhenCrossOrigin()
                                   .RemoveServerHeader();
            //.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365)
            //.AddContentSecurityPolicy(builder => {
            //    builder.AddObjectSrc().None();
            //    builder.AddFormAction().Self();
            //    builder.AddFrameAncestors().None();
            //});

            app.UseSecurityHeaders(policyCollection);
            #endregion

            // Hangfire UI
            if (Configuration.GetValue <bool>("Hangfire:Enable"))
            {
                // 加入Hangfire伺服器
                app.UseHangfireServer();

                // 加入Hangfire控制面板
                app.UseHangfireDashboard(
                    pathMatch: Configuration.GetValue <string>("Hangfire:PathMatch"),
                    options: new DashboardOptions()   // 使用自訂的認證過濾器
                {
                    Authorization = new[] { new HangfireAuthorizeFilter() }
                }
                    );
            }

            // Swagger UI
            if (Configuration.GetValue <bool>("Swagger:Enable"))
            {
                app.UseOpenApiAndSwaggerUi3();
            }

            // 使用認證
            app.UseAuthentication();

            // 使用MVC
            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
            });


            // 使用靜態檔案
            app.UseStaticFiles();

            // 使用SPA
            app.UseSpa();
        }
Example #9
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app">The application to configure.</param>
        /// <param name="env">The environment information to use in configuration phase.</param>
        /// <param name="applicationLifetime"></param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime)
        {
            app.UseProblemDetails();
            if (!env.IsProduction())
            {
                //This test middleware needs to be before developer exception pages.
                app.Use(TestMiddleware);
                app.UseDeveloperExceptionPage();
            }

            //app.UseHealthChecks("/healthz");
            //app.UseMiddleware<StartupTasksMiddleware>();

            applicationLifetime.ApplicationStopping.Register(() => { });

            //This ensures (or improves chances) to flush log buffers before (a graceful) shutdown.
            //It appears there isn't other way (e.g. in Program) than taking a reference to the global
            //static Serilog instance.
            applicationLifetime.ApplicationStopped.Register(Log.CloseAndFlush);

            //Security headers will always be added and by default the disallow everything.
            //The trimming is a robustness measure to make sure the URL has one trailing slash.
            //The listening address is needed for security headers. This is the public
            //API address.
            var appsettingsSection = Configuration.GetSection("AppSettings");
            var listeningAddress   = appsettingsSection["OneBoxDeploymentApiUrl"];

            listeningAddress = (listeningAddress ?? app.ServerFeatures.Get <IServerAddressesFeature>().Addresses.FirstOrDefault()).EnsureTrailing('/');

            //Note: the constructor checks ConfigurationKeys forbidden in production are not found.
            if (!env.IsProduction())
            {
                //Creates a route to specifically throw and unhandled exception. This route is most likely injected only in testing.
                //This kind of testing middleware can be made to one code block guarded appropriately if there is more of it.
                var alwaysFaultyRoute = Configuration.GetValue <string>(ConfigurationKeys.AlwaysFaultyRoute, null);
                if (alwaysFaultyRoute != null)
                {
                    app.Use((context, next) =>
                    {
                        if (context.Request.Path.StartsWithSegments($"/{alwaysFaultyRoute}", out _, out _))
                        {
                            throw new Exception($"Fault injected route for testing ({context.Request.PathBase}/{alwaysFaultyRoute}).");
                        }

                        return(next());
                    });
                }
            }

            Logger.LogInformation(Events.SwaggerDocumentation.Id, Events.SwaggerDocumentation.FormatString, listeningAddress + SwaggerRoot + "/");
            var defaultSecurityPolicies = new HeaderPolicyCollection()
                                          .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365)
                                          .RemoveServerHeader()
                                          .AddFrameOptionsDeny();

            app.UseSecurityHeaders(defaultSecurityPolicies);
            app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/" + SwaggerRoot), swaggerBranch =>
            {
                //See configuration at https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders.
                const string GoogleStyles   = "https://fonts.googleapis.com";
                const string GoogleFontsUrl = "https://fonts.gstatic.com";
                var clientUrl = Path.Combine(listeningAddress, SwaggerRoot).EnsureTrailing('/');
                //Additional information for the many Feature-Policy none definitions:
                //https://github.com/w3c/webappsec-feature-policy/issues/189#issuecomment-452401661.
                swaggerBranch.UseSecurityHeaders(new HeaderPolicyCollection().AddFeaturePolicy(builder =>
                {
                    builder.AddAccelerometer().None();
                    builder.AddAmbientLightSensor().None();
                    builder.AddAutoplay().None();
                    builder.AddCamera().None();
                    builder.AddEncryptedMedia().None();
                    builder.AddFullscreen().None();
                    builder.AddGeolocation().None();
                    builder.AddGyroscope().None();
                    builder.AddMagnetometer().None();
                    builder.AddMicrophone().None();
                    builder.AddMidi().None();
                    builder.AddPayment().None();
                    builder.AddPictureInPicture().None();
                    builder.AddSpeaker().None();
                    builder.AddSyncXHR().None();
                    builder.AddUsb().None();
                    builder.AddVR().None();
                })
                                                 .AddXssProtectionBlock()
                                                 .AddContentTypeOptionsNoSniff()
                                                 .AddReferrerPolicyStrictOriginWhenCrossOrigin()
                                                 .AddContentSecurityPolicy(builder =>
                {
                    builder.AddReportUri().To("/cspreport");
                    builder.AddBlockAllMixedContent();
                    builder.AddConnectSrc().Self();
                    builder.AddStyleSrc().Self().UnsafeInline().Sources.Add(GoogleStyles);
                    builder.AddFontSrc().Self().Sources.Add(GoogleFontsUrl);
                    builder.AddImgSrc().Self().Sources.Add("data:");
                    builder.AddScriptSrc().Self().UnsafeInline();
                    builder.AddObjectSrc().None();
                    builder.AddFormAction().Self();
                    builder.AddFrameAncestors().None().Sources.Add(clientUrl);
                }, asReportOnly: false));
            });

            //For further Swagger related information, see at
            //https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger.
            app.UseSwagger();
            app.UseSwagger(swagger => swagger.RouteTemplate = $"{SwaggerRoot}/{{documentName}}/swagger.json");

            if (Configuration["HideSwaggerUi"]?.Equals("true") != true)
            {
                app.UseSwaggerUI(swaggerSetup =>
                {
                    swaggerSetup.SwaggerEndpoint($"/{SwaggerRoot}/{SwaggerDocumentationBasePath}/swagger.json", SwaggerDocumentationBasePath);
                    swaggerSetup.RoutePrefix = SwaggerRoot;

                    swaggerSetup.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream($"{Assembly.GetAssembly(typeof(Startup)).GetName().Name}.wwwroot.swagger.index.html");
                });
            }

            app.UseCors("CorsPolicy");
            app.UseStaticFiles();
            app.UseRouting();
            //app.UseAuthorization();
            app.UseEndpoints(endpoints => endpoints.MapControllers());
        }
Example #10
0
 /// <summary>
 /// The browser will send the full URL to requests to the same origin but
 /// only send the origin when requests are cross-origin, as long as a scheme
 /// downgrade has not happened (i.e. you are not moving from HTTPS to HTTP)
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddReferrerPolicyStrictOriginWhenCrossOrigin(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new ReferrerPolicyHeader("strict-origin-when-cross-origin")));
 }
Example #11
0
 /// <summary>
 /// The browser will always send the full URL with any request to any origin.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddReferrerPolicyUnsafeUrl(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new ReferrerPolicyHeader("unsafe-url")));
 }
Example #12
0
 /// <summary>
 /// The browser will always set the referrer header to the origin from which the request was made.
 /// This will strip any path information from the referrer information.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddReferrerPolicyOrigin(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new ReferrerPolicyHeader("origin")));
 }
Example #13
0
 /// <summary>
 /// The browser will not send the referrer header when navigating from HTTPS to HTTP,
 /// but will always send the full URL in the referrer header when navigating
 /// from HTTP to any origin.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddReferrerPolicyNoReferrerWhenDowngrade(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new ReferrerPolicyHeader("no-referrer-when-downgrade")));
 }
Example #14
0
 /// <summary>
 /// Instructs the browser to never send the referrer header with requests
 /// that are made from your site. This also include links to pages on your own site.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddReferrerPolicyNoReferrer(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new ReferrerPolicyHeader("no-referrer")));
 }
        public void AddCustomHeader_WhenNullValue_DoesntThrow()
        {
            var collection = new HeaderPolicyCollection();

            collection.AddCustomHeader("header", "value");
        }
Example #16
0
    public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev, string idpHost)
    {
        var policy = new HeaderPolicyCollection()
                     .AddFrameOptionsDeny()
                     .AddXssProtectionBlock()
                     .AddContentTypeOptionsNoSniff()
                     .AddReferrerPolicyStrictOriginWhenCrossOrigin()
                     .AddCrossOriginOpenerPolicy(builder =>
        {
            builder.SameOrigin();
        })
                     .AddCrossOriginResourcePolicy(builder =>
        {
            builder.SameOrigin();
        })
                     .AddCrossOriginEmbedderPolicy(builder => // remove for dev if using hot reload
        {
            builder.RequireCorp();
        })
                     .AddContentSecurityPolicy(builder =>
        {
            builder.AddObjectSrc().None();
            builder.AddBlockAllMixedContent();
            builder.AddImgSrc().Self().From("data:");
            builder.AddFormAction().Self().From(idpHost);
            builder.AddFontSrc().Self();
            builder.AddStyleSrc().Self();
            builder.AddBaseUri().Self();
            builder.AddFrameAncestors().None();

            // due to Blazor
            builder.AddScriptSrc()
            .Self()
            .WithHash256("v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=")
            .UnsafeEval();

            // disable script and style CSP protection if using Blazor hot reload
            // if using hot reload, DO NOT deploy with an insecure CSP
        })
                     .RemoveServerHeader()
                     .AddPermissionsPolicy(builder =>
        {
            builder.AddAccelerometer().None();
            builder.AddAutoplay().None();
            builder.AddCamera().None();
            builder.AddEncryptedMedia().None();
            builder.AddFullscreen().All();
            builder.AddGeolocation().None();
            builder.AddGyroscope().None();
            builder.AddMagnetometer().None();
            builder.AddMicrophone().None();
            builder.AddMidi().None();
            builder.AddPayment().None();
            builder.AddPictureInPicture().None();
            builder.AddSyncXHR().None();
            builder.AddUsb().None();
        });

        if (!isDev)
        {
            // maxage = one year in seconds
            policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365);
        }

        return(policy);
    }
 /// <summary>
 /// Removes the Server header from all responses
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection RemoveServerHeader(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(ServerHeader.Remove()));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SecurityHeadersMiddleware"/> class.
 /// </summary>
 /// <param name="next">The next middleware in the pipeline.</param>
 /// <param name="service">An instance of <see cref="ICustomHeaderService"/>.</param>
 /// <param name="policies">A <see cref="HeaderPolicyCollection"/> containing the policies to be applied.</param>
 public SecurityHeadersMiddleware(RequestDelegate next, ICustomHeaderService service, HeaderPolicyCollection policies)
     : this(next, service, policies, new NonceGenerator())
 {
     _mustGenerateNonce = MustGenerateNonce(_policy);
 }
Example #19
0
 /// <summary>
 /// Add a Permissions-Policy header to all requests
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="configure">Configure the Permissions-Policy</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddPermissionsPolicy(this HeaderPolicyCollection policies, Action <PermissionsPolicyBuilder> configure)
 {
     return(policies.ApplyPolicy(PermissionsPolicyHeader.Build(configure)));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SecurityHeadersMiddleware"/> class.
 /// </summary>
 /// <param name="next">The next middleware in the pipeline.</param>
 /// <param name="service">An instance of <see cref="ICustomHeaderService"/>.</param>
 /// <param name="policies">A <see cref="HeaderPolicyCollection"/> containing the policies to be applied.</param>
 /// <param name="nonceGenerator">Used to generate nonce (number used once) values for headers</param>
 internal SecurityHeadersMiddleware(RequestDelegate next, ICustomHeaderService service, HeaderPolicyCollection policies, NonceGenerator nonceGenerator)
 {
     _next = next ?? throw new ArgumentNullException(nameof(next));
     CustomHeaderService = service ?? throw new ArgumentNullException(nameof(service));
     _policy             = policies ?? throw new ArgumentNullException(nameof(policies));
     _nonceGenerator     = nonceGenerator ?? throw new ArgumentException(nameof(nonceGenerator));
 }
Example #21
0
        public static IApplicationBuilder UseStatCanSecurityHeaders(this IApplicationBuilder app)
        {
            var env = app.ApplicationServices.GetRequiredService <IHostEnvironment>();
            var policyCollection = new HeaderPolicyCollection()
                                   .AddFrameOptionsSameOrigin()
                                   .AddXssProtectionEnabled()
                                   .AddContentTypeOptionsNoSniff()
                                   .AddReferrerPolicyStrictOriginWhenCrossOrigin()
                                   .RemoveServerHeader()
                                   .AddContentSecurityPolicy(builder =>
            {
                builder.AddObjectSrc().Self();
                // Domains here for OAuth redirects
                builder.AddFormAction().Self().From("github.com").From("account.gccollab.ca").From("login.microsoftonline.com");
                builder.AddFrameAncestors().Self();
                builder.AddDefaultSrc().Self();
                builder.AddImgSrc().Self().Data().From("*.statcan.ca").From("*.statcan.gc.ca")
                .From("*.omtrdc.net").From("*.demdex.net").From("cm.everesttech.net");     // adobe analytics
                builder.AddFontSrc().Self().Data().From("cdn.jsdelivr.net").From("fonts.googleapis.com").From("fonts.gstatic.com").From("cdn.materialdesignicons.com");
                builder.AddStyleSrc().UnsafeInline().Self()
                .From("cdn.materialdesignicons.com")
                .From("cdn.jsdelivr.net")
                .From("fonts.googleapis.com")
                .From("code.jquery.com")
                .From("unpkg.com")
                .From("cdnjs.cloudflare.com")
                .From("stackpath.bootstrapcdn.com");
                builder.AddConnectSrc().Self().From("*.statcan.ca").From("*.statcan.gc.ca").From("cdn.jsdelivr.net").From("dpm.demdex.net").From("canada.sc.omtrdc.net"); // adobe analytics

                builder.AddScriptSrc()
                .UnsafeEval()                                                                         // for vue-js in oc admin
                .UnsafeInline()                                                                       // for oc admin
                .Self()
                .From("https://www.google.com/recaptcha/").From("https://www.gstatic.com/recaptcha/") //recaptcha
                .From("cdn.jsdelivr.net")
                .From("code.jquery.com")
                .From("ajax.googleapis.com")
                .From("cdnjs.cloudflare.com")
                .From("vuejs.org")
                .From("unpkg.com")
                .From("stackpath.bootstrapcdn.com")
                .From("*.statcan.ca")
                .From("*.statcan.gc.ca")
                .From("*.2o7.net")           // adobe analytics
                .From("*.omtrdc.net")        // adobe analytics
                .From("*.tt.omtrdc.net")     // adobe analytics
                .From("assets.adobedtm.com") // adobe analytics
                .From("*.demdex.net")        // adobe analytics
                .From("cm.everesttech.net")  // adobe analytics
                .From("*.adobe.com");        // adobe analytics
                builder.AddFrameSrc().Self()
                .From("canada.demdex.net")   // adobe analytics
                .From("https://www.google.com/recaptcha/");
            });

            if (!env.IsDevelopment())
            {
                policyCollection.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365); // maxage = one year in seconds
            }

            return(app.UseSecurityHeaders(policyCollection));
        }
Example #22
0
        public static IApplicationBuilder UseCustomHeadersMiddleware(this IApplicationBuilder app, HeaderPolicyCollection policies)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (policies == null)
            {
                throw new ArgumentNullException(nameof(policies));
            }

            return(app.UseMiddleware <CustomHeadersMiddleware>(policies));
        }
 /// <summary>
 /// Add X-XSS-Protection 1; mode=block to all requests.
 /// Enables XSS protections and instructs the user-agent to block the response in the event that script has been inserted from user input, instead of sanitizing.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 public static HeaderPolicyCollection AddXssProtectionBlock(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(XssProtectionHeader.Block()));
 }
Example #24
0
 /// <summary>
 /// Add X-XSS-Protection 1 to all requests.
 /// Enables the XSS Protections
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddXssProtectionEnabled(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new XssProtectionHeader("1")));
 }
Example #25
0
 /// <summary>
 /// Add X-Content-Type-Options nosniff to all requests.
 /// Disables content sniffing
 /// Can be set to protect against MIME type confusion attacks.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddContentTypeOptionsNoSniff(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new XContentTypeOptionsHeader("nosniff")));
 }
Example #26
0
 /// <summary>
 /// Add X-XSS-Protection 1; mode=block to all requests.
 /// Enables XSS protections and instructs the user-agent to block the response in the event that script has been inserted from user input, instead of sanitizing.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddXssProtectionBlock(this HeaderPolicyCollection policies)
 {
     return(policies.ApplyPolicy(new XssProtectionHeader("1; mode=block")));
 }
Example #27
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app">The application.</param>
        /// <param name="env">The env.</param>
        /// <param name="antiforgery">The antiforgery.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="seeder">The database seeder.</param>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAntiforgery antiforgery,
                              ILoggerFactory loggerFactory, IServiceProvider serviceProvider, DataSeeder seeder)
        {
            HttpContextAccessor = app.ApplicationServices.GetRequiredService <IHttpContextAccessor>();

            _userService = serviceProvider.GetService <IUserAccountService>();
            _authService = serviceProvider.GetService <IAuthService>();
            _crypto      = serviceProvider.GetService <ICrypto>();

            app.UseCors("CorsPolicy");

            app.UseTokenProvider(_tokenOptions, _signingKey);

            var localizationOptions = app.ApplicationServices.GetService <IOptions <RequestLocalizationOptions> >();

            localizationOptions.Value.RequestCultureProviders.Insert(0, new UrlRequestCultureProvider());
            app.UseRequestLocalization(localizationOptions.Value);

            // Show Index.html as default page
            app.UseDefaultFiles();

            app.UseStaticFiles();

            //app.UseHangfireDashboard();
            //app.UseHangfireServer();

            //const int maxAge = 60*60*24*365;
            var policyCollection = new HeaderPolicyCollection()
                                   .AddFrameOptionsDeny()
                                   .AddXssProtectionBlock()
                                   .AddContentTypeOptionsNoSniff()
                                   .AddStrictTransportSecurityMaxAge() // maxage = one year in seconds
                                   .RemoveServerHeader();

            //.AddCustomHeader("X-TOTAL-RECORDS", "Header value");

            app.UseCustomHeadersMiddleware(policyCollection);

            //RecurringJob.AddOrUpdate(() => Console.WriteLine("Minutely Job"), Cron.Minutely);

            app.UseWebSockets();

            app.UseSignalR <RawConnection>("/signalr");

            app.UseMiddleware(typeof(ErrorHandlingMiddleware));

            // Add MVC to the request pipeline.
            app.UseMvc(routes =>
            {
                var cultureConstraint = new
                {
                    Culture = new RegexRouteConstraint("^[a-z]{{2}}-[A-Z]{{2}}$")
                };

                routes.MapRoute(
                    "apiVersionCulture",
                    "api/{version}/{culture}/{controller}/{action=Index}/{id?}",
                    cultureConstraint
                    );

                routes.MapRoute(
                    "apiVersion",
                    "api/{version}/{controller}/{action=Index}/{id?}"
                    );

                routes.MapRoute(
                    "apiCulture",
                    "api/{culture}/{controller}/{action=Index}/{id?}",
                    cultureConstraint
                    );

                routes.MapRoute(
                    "default",
                    "{controller=Home}/{action=Index}/{id?}"
                    );
            });

            // https://github.com/domaindrivendev/Swashbuckle.AspNetCore
            // Middleware to expose the generated Swagger as JSON endpoint(s)
            app.UseSwagger();

            // Middleware to expose interactive documentation
            app.UseSwaggerUI(c =>
            {
                c.ShowJsonEditor();
                c.SwaggerEndpoint("/swagger/v1/swagger.json", AppSettings.Information.Name);
                c.DocExpansion("full");
                c.ShowRequestHeaders();
                c.SupportedSubmitMethods(new[] { "get", "post", "delete", "put", "patch" });
                c.InjectOnCompleteJavaScript("/swagger-ui/on-complete.js");
                c.InjectOnFailureJavaScript("/swagger-ui/on-failure.js");
            });

            app.Use(next => context =>
            {
                if (!string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase) &&
                    !string.Equals(context.Request.Path.Value, "/index.html", StringComparison.OrdinalIgnoreCase))
                {
                    return(next(context));
                }

                var tokens = antiforgery.GetAndStoreTokens(context);
                context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions {
                    HttpOnly = false
                });
                return(next(context));
            });

            seeder.SeedAsync().Wait();
        }
Example #28
0
 /// <summary>
 /// Add X-XSS-Protection 1; report=http://site.com/report to all requests.
 /// A partially supported directive that tells the user-agent to report potential XSS attacks to a single URL. Data will be POST'd to the report URL in JSON format.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="reportUrl">The url to report potential XSS attacks to</param>
 /// <returns>The <see cref="HeaderPolicyCollection"/> for method chaining</returns>
 public static HeaderPolicyCollection AddXssProtectionReport(this HeaderPolicyCollection policies, string reportUrl)
 {
     return(policies.ApplyPolicy(new XssProtectionHeader($"1; report={reportUrl}")));
 }
Example #29
0
        // https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders
        public static IApplicationBuilder AddCustomSecurityHeaders(this IApplicationBuilder app)
        {
            var env = app.ApplicationServices.GetRequiredService <IWebHostEnvironment>();

            var policyCollection = new HeaderPolicyCollection()
                                   .AddFrameOptionsDeny()
                                   .AddXssProtectionBlock()
                                   .AddContentTypeOptionsNoSniff()
                                   .AddStrictTransportSecurityMaxAge(maxAgeInSeconds: 60 * 60 * 24 * 365) // maxage = one year in seconds
                                   .AddReferrerPolicyOriginWhenCrossOrigin()
                                   .RemoveServerHeader()
                                   .AddContentSecurityPolicy(builder =>
            {
                if (env.IsProduction())
                {
                    builder.AddUpgradeInsecureRequests();         // upgrade-insecure-requests
                }

                // builder.AddReportUri() // report-uri: https://report-uri.com
                //     .To("https://report-uri.com");

                builder.AddDefaultSrc()
                .Self();

                // Allow AJAX, WebSocket and EventSource connections to:
                var socketUrl = Startup.Configuration["HostUrl"].ToString().Replace("http://", "ws://", StringComparison.OrdinalIgnoreCase).Replace("https://", "wss://", StringComparison.OrdinalIgnoreCase);
                var stsUrl    = Startup.Configuration["StsAuthority"];


                builder.AddConnectSrc()
                .Self()
                .From(stsUrl)
                .From(socketUrl);

                builder.AddFontSrc()         // font-src 'self'
                .Self()
                .Data();

                builder.AddObjectSrc()         // object-src 'none'
                .None();

                builder.AddFormAction()         // form-action 'self'
                .Self();

                builder.AddImgSrc()         // img-src https:
                .Self()
                .Data();

                // builder.AddScriptSrc() // script-src 'self'
                //     .Self();

                // builder.AddStyleSrc() // style-src 'self'
                //     .Self();

                builder.AddUpgradeInsecureRequests();         // upgrade-insecure-requests
                builder.AddCustomDirective("script-src", "'self' 'unsafe-inline' 'unsafe-eval'");
                builder.AddCustomDirective("style-src", "'self' 'unsafe-inline' 'unsafe-eval'");

                builder.AddMediaSrc()
                .Self();

                // frame-ancestors 'none'
                builder.AddFrameAncestors()
                .None();

                builder.AddFrameSource()
                .From(stsUrl);

                // You can also add arbitrary extra directives: plugin-types application/x-shockwave-flash"
                // builder.AddCustomDirective("plugin-types", "application/x-shockwave-flash");
            });

            app.UseSecurityHeaders(policyCollection);
            return(app);
        }
Example #30
0
 /// <summary>
 /// Add Strict-Transport-Security max-age=<see paramref="maxAge"/>; includeSubDomains to all requests.
 /// Tells the user-agent to cache the domain in the STS list for the number of seconds provided and include any sub-domains.
 /// </summary>
 /// <param name="policies">The collection of policies</param>
 /// <param name="maxAgeInSeconds">The maximum number of seconds to cache the domain</param>
 public static HeaderPolicyCollection AddStrictTransportSecurityMaxAgeIncludeSubDomains(this HeaderPolicyCollection policies, int maxAgeInSeconds = StrictTransportSecurityHeader.OneYearInSeconds)
 {
     return(policies.ApplyPolicy(new StrictTransportSecurityHeader($"max-age={maxAgeInSeconds}; includeSubDomains")));
 }