Skip to content

Commit dcd3701

Browse files
committed
Merge remote-tracking branch 'origin/dev' into task/system-text-json-migration
2 parents 94b3582 + bce6104 commit dcd3701

File tree

7 files changed

+73
-19
lines changed

7 files changed

+73
-19
lines changed

Lombiq.HelpfulLibraries.AspNetCore/Docs/Security.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- `EmbeddedMediaContentSecurityPolicyProvider`: An optional policy provider that permits additional host names used by usual media embedding sources (like YouTube) for the `frame-scr` directive.
99
- `IContentSecurityPolicyProvider`: Interface for services that update the dictionary that will be turned into the `Content-Security-Policy` header value.
1010
- `ServiceCollectionExtensions`: Extensions methods for `IServiceCollection`, e.g. `AddContentSecurityPolicyProvider()` is a shortcut to register `IContentSecurityPolicyProvider` in dependency injection.
11+
- `XWidgetsContentSecurityPolicyProvider`: An optional content security policy provider that provides configuration to allow the usage of X (Twitter) social widgets.
1112

1213
There is a similar section for security extensions related to Orchard Core [here](../../Lombiq.HelpfulLibraries.OrchardCore/Docs/Security.md).
1314

Lombiq.HelpfulLibraries.AspNetCore/Security/CdnContentSecurityPolicyProvider.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,43 +17,53 @@ public class CdnContentSecurityPolicyProvider : IContentSecurityPolicyProvider
1717
/// <summary>
1818
/// Gets the sources that will be added to the <see cref="StyleSrc"/> directive.
1919
/// </summary>
20-
public static ConcurrentBag<string> PermittedStyleSources { get; } = new(
20+
public static ConcurrentBag<string> PermittedStyleSources { get; } =
2121
[
22-
"fonts.googleapis.com",
23-
"fonts.gstatic.com", // #spell-check-ignore-line
2422
"cdn.jsdelivr.net", // #spell-check-ignore-line
25-
"fastly.jsdelivr.net", // #spell-check-ignore-line
2623
"cdnjs.cloudflare.com", // #spell-check-ignore-line
24+
"fastly.jsdelivr.net", // #spell-check-ignore-line
25+
"fonts.cdnfonts.com", // #spell-check-ignore-line
26+
"fonts.googleapis.com",
27+
"fonts.gstatic.com", // #spell-check-ignore-line
2728
"maxcdn.bootstrapcdn.com", // #spell-check-ignore-line
28-
]);
29+
"unpkg.com", // #spell-check-ignore-line
30+
];
2931

3032
/// <summary>
3133
/// Gets the sources that will be added to the <see cref="ScriptSrc"/> directive.
3234
/// </summary>
33-
public static ConcurrentBag<string> PermittedScriptSources { get; } = new(
35+
public static ConcurrentBag<string> PermittedScriptSources { get; } =
3436
[
3537
"cdn.jsdelivr.net", // #spell-check-ignore-line
3638
"cdnjs.cloudflare.com", // #spell-check-ignore-line
3739
"code.jquery.com",
3840
"fastly.jsdelivr.net", // #spell-check-ignore-line
3941
"maxcdn.bootstrapcdn.com", // #spell-check-ignore-line
40-
]);
42+
"unpkg.com", // #spell-check-ignore-line
43+
];
4144

4245
/// <summary>
4346
/// Gets the sources that will be added to the <see cref="FontSrc"/> directive.
4447
/// </summary>
45-
public static ConcurrentBag<string> PermittedFontSources { get; } = new(
48+
public static ConcurrentBag<string> PermittedFontSources { get; } =
4649
[
4750
"cdn.jsdelivr.net", // #spell-check-ignore-line
51+
"cdnjs.cloudflare.com", // #spell-check-ignore-line
52+
"fonts.cdnfonts.com", // #spell-check-ignore-line
4853
"fonts.googleapis.com",
4954
"fonts.gstatic.com", // #spell-check-ignore-line
50-
]);
55+
];
5156

5257
/// <summary>
5358
/// Gets the sources that will be added to the <see cref="FrameSrc"/> directive.
5459
/// </summary>
5560
public static ConcurrentBag<string> PermittedFrameSources { get; } = [];
5661

62+
/// <summary>
63+
/// Gets the sources that will be added to the <see cref="ImgSrc"/> directive.
64+
/// </summary>
65+
public static ConcurrentBag<string> PermittedImgSources { get; } = [];
66+
5767
public ValueTask UpdateAsync(IDictionary<string, string> securityPolicies, HttpContext context)
5868
{
5969
var any = false;
@@ -82,6 +92,12 @@ public ValueTask UpdateAsync(IDictionary<string, string> securityPolicies, HttpC
8292
CspHelper.MergeValues(securityPolicies, FrameSrc, PermittedFrameSources);
8393
}
8494

95+
if (!PermittedImgSources.IsEmpty)
96+
{
97+
any = true;
98+
CspHelper.MergeValues(securityPolicies, ImgSrc, PermittedImgSources);
99+
}
100+
85101
if (any)
86102
{
87103
var allPermittedSources = PermittedStyleSources.Concat(PermittedScriptSources).Concat(PermittedFontSources);

Lombiq.HelpfulLibraries.AspNetCore/Security/ContentSecurityPolicyDirectives.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
namespace Lombiq.HelpfulLibraries.AspNetCore.Security;
1+
namespace Lombiq.HelpfulLibraries.AspNetCore.Security;
22

33
/// <summary>
4-
/// The <c>Content-Security-Policy</c> directives defined in the <a href="https://www.w3.org/TR/CSP2/#directives">W3C
5-
/// Recommendation</a>.
4+
/// The <c>Content-Security-Policy</c> directives defined in the <see href="https://www.w3.org/TR/CSP2/#directives">W3C
5+
/// Recommendation</see> (also see the <see
6+
/// href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives">MDN page</see>).
67
/// </summary>
78
public static class ContentSecurityPolicyDirectives
89
{
@@ -15,13 +16,20 @@ public static class ContentSecurityPolicyDirectives
1516
public const string FrameAncestors = "frame-ancestors";
1617
public const string FrameSrc = "frame-src";
1718
public const string ImgSrc = "img-src";
19+
public const string ManifestSrc = "manifest-src";
1820
public const string MediaSrc = "media-src";
1921
public const string ObjectSrc = "object-src";
2022
public const string PluginTypes = "plugin-types";
23+
public const string ReportTo = "report-to";
2124
public const string ReportUri = "report-uri";
2225
public const string Sandbox = "sandbox";
2326
public const string ScriptSrc = "script-src";
27+
public const string ScriptSrcAttr = "script-src-attr";
28+
public const string ScriptSrcElem = "script-src-elem";
2429
public const string StyleSrc = "style-src";
30+
public const string StyleSrcAttr = "style-src-attr";
31+
public const string UpgradeInsecureRequests = "upgrade-insecure-requests";
32+
public const string StyleSrcElem = "style-src-elem";
2533
public const string WorkerSrc = "worker-src";
2634

2735
public static class CommonValues
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Microsoft.AspNetCore.Http;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using static Lombiq.HelpfulLibraries.AspNetCore.Security.ContentSecurityPolicyDirectives;
5+
6+
namespace Lombiq.HelpfulLibraries.AspNetCore.Security;
7+
8+
/// <summary>
9+
/// An optional content security policy provider that provides configuration to allow the usage of X (Twitter) social
10+
/// widgets.
11+
/// </summary>
12+
public class XWidgetsContentSecurityPolicyProvider : IContentSecurityPolicyProvider
13+
{
14+
private const string PlatformDotTwitter = "platform.twitter.com";
15+
16+
public ValueTask UpdateAsync(IDictionary<string, string> securityPolicies, HttpContext context)
17+
{
18+
CspHelper.MergeValues(securityPolicies, FrameSrc, PlatformDotTwitter);
19+
CspHelper.MergeValues(securityPolicies, ImgSrc, PlatformDotTwitter, "syndication.twitter.com");
20+
CspHelper.MergeValues(securityPolicies, StyleSrc, PlatformDotTwitter);
21+
CspHelper.MergeValues(securityPolicies, ScriptSrc, PlatformDotTwitter);
22+
23+
return ValueTask.CompletedTask;
24+
}
25+
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Lombiq Helpful Libraries - Orchard Core Libraries - Security
22

3-
## Extensions
4-
5-
- `SecurityOrchardCoreBuilderExtensions`: Adds `BuilderExtensions` extensions. For example, the `ConfigureSecurityDefaultsWithStaticFiles()` that provides some default security configuration for Orchard Core.
6-
73
There is a similar section for security extensions related to ASP.NET Core [here](../../Lombiq.HelpfulLibraries.AspNetCore/Docs/Security.md). All of the services mentioned in both documents are included in the `ConfigureSecurityDefaults()` and `ConfigureSecurityDefaultsWithStaticFiles()` extensions.
84

95
These extensions provide additional security and can resolve issues reported by the [ZAP security scanner](https://github.com/Lombiq/UI-Testing-Toolbox/blob/dev/Lombiq.Tests.UI/Docs/SecurityScanning.md).
106

7+
## Extensions
8+
9+
- `SecurityOrchardCoreBuilderExtensions`: Adds `BuilderExtensions` extensions. For example, the `ConfigureSecurityDefaultsWithStaticFiles()` that provides some default security configuration for Orchard Core.
10+
1111
## Attributes
1212

1313
- `ContentSecurityPolicyAttribute`: You can add the `[ContentSecurityPolicy(value, name)]` attribute to any MVC action's method. This way you can grant per-action content security policy permissions, right there in the controller. These attributes are handled by the `ContentSecurityPolicyAttributeContentSecurityPolicyProvider`.
@@ -19,3 +19,5 @@ These extensions provide additional security and can resolve issues reported by
1919
- `ReCaptchaContentSecurityPolicyProvider`: Provides various directives for the `Content-Security-Policy` header, allowing using ReCaptcha captchas. Is automatically enabled when the `OrchardCore.ReCaptcha` feature is enabled.
2020
- `ResourceManagerContentSecurityPolicyProvider`: An abstract base class for implementing content security policy providers that trigger when the specified resource is included.
2121
- `VueContentSecurityPolicyProvider`: An implementation of `ResourceManagerContentSecurityPolicyProvider` that adds `script-src: unsafe-eval` permission to the page if it uses the `vuejs` resource. This includes any Vue.js app in stock Orchard Core, apps you create in your view files, and SFCs created with the Lombiq.VueJs module. This is necessary, because without `unsafe-eval` Vue.js only supports templates that are pre-compiled into JS code.
22+
23+
You can configure optional or custom content security policy providers by implementing the `IContentSecurityPolicyProvider` interface and registering them in the DI container with `AddContentSecurityPolicyProvider<TProvider>()`, e.g. `services.AddContentSecurityPolicyProvider<XWidgetsContentSecurityPolicyProvider>();` in a `Startup` class. You can also register providers for the whole app (i.e. all tenants) from the root `Program` class via `OrchardCoreBuilder.ApplicationServices`.

Lombiq.HelpfulLibraries.OrchardCore/Security/GoogleAnalyticsContentSecurityPolicyProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ public class GoogleAnalyticsContentSecurityPolicyProvider : IContentSecurityPoli
1313
{
1414
private const string HttpContextItemKey = nameof(GoogleAnalyticsContentSecurityPolicyProvider);
1515

16+
public static bool AlwaysEnabled { get; set; }
17+
1618
public async ValueTask UpdateAsync(IDictionary<string, string> securityPolicies, HttpContext context)
1719
{
18-
var googleAnalyticsIsEnabled = context.Items.ContainsKey(HttpContextItemKey);
20+
var googleAnalyticsIsEnabled = AlwaysEnabled || context.Items.ContainsKey(HttpContextItemKey);
1921

2022
if (!googleAnalyticsIsEnabled)
2123
{

Lombiq.HelpfulLibraries.Tests/Lombiq.HelpfulLibraries.Tests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
<ItemGroup>
1919
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
20-
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
20+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
2121
<PrivateAssets>all</PrivateAssets>
2222
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2323
</PackageReference>
@@ -31,7 +31,7 @@
3131
</ItemGroup>
3232

3333
<ItemGroup>
34-
<AdditionalFiles Include="package.json"/>
34+
<AdditionalFiles Include="package.json" />
3535
</ItemGroup>
3636

3737
</Project>

0 commit comments

Comments
 (0)