Skip to content

Add SRI Hash support to Static Web Assets in Blazor #61180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
Tornhoof opened this issue Mar 27, 2025 · 6 comments
Open
1 task done

Add SRI Hash support to Static Web Assets in Blazor #61180

Tornhoof opened this issue Mar 27, 2025 · 6 comments
Labels
area-blazor Includes: Blazor, Razor Components
Milestone

Comments

@Tornhoof
Copy link
Contributor

Tornhoof commented Mar 27, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

I'm trying to calculate SRI hashes for the static web assets in my Blazor Web App.
At the moment, the suggested way for static data is simply to calculate it elsewhere and paste the SRI hash into my App..razor.
See https://learn.microsoft.com/en-us/aspnet/core/blazor/security/content-security-policy?view=aspnetcore-9.0#adopt-subresource-integrity-sri

I'd like an built-in way to do that

Describe the solution you'd like

Something like a new method in ComponentBase, similar to Assets, called AssetIntegrity

<link rel="stylesheet" integrity="@AssetIntegrity["MyApp.styles.css"]" crossorigin="anonymous" href="@Assets["MyApp.styles.css"]" />

Additional context

I looked at the build-time staticwebassets.build.json, there is already a property called Integrity, which is used for ETag and (I think) for ImportMap. https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/static-files?view=aspnetcore-9.0#import-maps

I looked at runtime into the data structures behind Assets, ResourceAssetCollection, but I couldn't find the Integrity property anywhere.

There is some prior discussins about CSP in #6001, but that includes a fully features CSP builder.

@ghost ghost added the area-blazor Includes: Blazor, Razor Components label Mar 27, 2025
@javiercn
Copy link
Member

javiercn commented Mar 27, 2025

@Tornhoof thanks for contacting us.

We don't populate this, but this information is already available on the resource collection.

https://github.com/dotnet/aspnetcore/blob/main/src/Components/Endpoints/src/Assets/ImportMapDefinition.cs#L85-L108

The integrity property contains the sha256 hash of the asset

We would definitely not add a public property on component base for this.

@javiercn javiercn added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Mar 27, 2025
@Tornhoof
Copy link
Contributor Author

We don't populate this, but this information is already available on the resource collection.

Yeah, i know about the importmap, but this applies only to scripts and not to styles correct?
For the integrated framework Script (blazor.web.js), there is no hash available either, correct?

Some way e.g. interface to access that build time static web assets data would bei quite nice.

We would definitely not add a public property on component base for this.

Perfectly fine, I think you missed a few opportunities when you added @Assets there.

@dotnet-policy-service dotnet-policy-service bot added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Mar 27, 2025
@javiercn
Copy link
Member

javiercn commented Mar 27, 2025

@Tornhoof thanks for the additional details.

The point of showing you the code that we reference is to give you a guide on how you can implement this feature/functionality yourself if you choose to do so. The ability to do this is already there (it's no coincidence that we chose to include the integrity and to do so in that format) so you can write your components/extensions around it.

@Tornhoof
Copy link
Contributor Author

Thank you for your clarification. I'll see how far I'll get myself.

@javiercn javiercn removed the Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. label Mar 27, 2025
@javiercn javiercn added this to the Backlog milestone Mar 27, 2025
@Tornhoof
Copy link
Contributor Author

Now I found out, why I couldn't find "integrity" in any of those collections during debugging.
If you don't set "EnableStaticAssetsDevelopmentIntegrity": true in the appsettings, then that propery gets removed.

var enableDevelopmentIntegrity = IsEnabled(config, "EnableStaticAssetsDevelopmentIntegrity");
if (!enableDevelopmentIntegrity)
{
RemoveIntegrityProperty(descriptor);
}
}

@alansingfieldcvn
Copy link

I pulled the git commit ID out of the Blazor library and used that as the version string.

        var assembly = typeof(Microsoft.Extensions.DependencyInjection.IServerSideBlazorBuilder).Assembly;
        var attr = assembly.GetCustomAttributes(typeof(AssemblyMetadataAttribute), false)
            .OfType<AssemblyMetadataAttribute>()
            .FirstOrDefault(x => x.Key == "CommitHash");

        var hash = attr?.Value;

<script src="_framework/blazor.web.js?v=@hash" 

So when you reference a new version of the Blazor library, your clients will download a new version of the blazor.web.js file. Maybe not totally perfect since the js file might stay the same from one version to the next, but it's probably "good enough".

I've omitted my caching code from this sample, you should calculate the hash in Program.cs once rather than using reflection for each page load ;->

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

3 participants