Skip to content

Pin executable Hugging Face model downloads to revisions#1688

Open
ungrav wants to merge 2 commits into
LykosAI:mainfrom
ungrav:security/pin-hf-model-revisions
Open

Pin executable Hugging Face model downloads to revisions#1688
ungrav wants to merge 2 commits into
LykosAI:mainfrom
ungrav:security/pin-hf-model-revisions

Conversation

@ungrav

@ungrav ungrav commented Jul 16, 2026

Copy link
Copy Markdown

Summary

  • pin the four bundled ADetailer .pt downloads to the exact Hugging Face commit that contains the already-declared SHA-256 objects
  • add a regression test that rejects resolve/main URLs for executable Hugging Face model formats in the built-in Ultralytics model list

Why

PyTorch checkpoint formats are executable deserialization surfaces. Stability Matrix already verifies SHA-256 values, which prevents a changed object from being accepted, but resolving a mutable branch can still turn a routine download into a failure after upstream changes. Pinning the revision makes provenance and availability deterministic and matches the pattern already used by built-in upscaler and ControlNet resources.

The selected revision is b0a075fd35454c86bb453a1ca06b29ffee704c20. Its four Git LFS pointers match the SHA-256 values already present in RemoteModels.cs.

Validation

  • verified all four LFS object IDs at the pinned revision against the existing HashSha256 values
  • verified no executable Hugging Face URL in the affected built-in model collection uses resolve/main
  • git diff --check

A local .NET SDK was unavailable, so the focused xUnit test was not executed locally; CI should provide the compile/runtime check.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

CLA Assistant Lite bot CLA Assistant bot All Contributors have signed the CLA.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request pins several Hugging Face model URLs to specific commit hashes instead of using the mutable 'main' branch, ensuring stability and security. It also introduces a regression test to verify that executable Hugging Face models are pinned. The reviewer suggested using reflection in the test to scan all public static properties of RemoteModels for downloadable resources, which would make the test comprehensive and future-proof against any new model collections.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +1 to +27
using StabilityMatrix.Core.Helper;

namespace StabilityMatrix.Tests.Core;

public class RemoteModelsTests
{
[Fact]
public void ExecutableHuggingFaceModelsUsePinnedRevisions()
{
var executableExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".bin",
".ckpt",
".pt",
".pth",
};

var unpinnedModels = RemoteModels
.UltralyticsModelFiles
.Where(model => model.DownloadableResource?.Url.Host == "huggingface.co")
.Where(model => executableExtensions.Contains(Path.GetExtension(model.DownloadableResource!.Value.Url.AbsolutePath)))
.Where(model => model.DownloadableResource!.Value.Url.AbsolutePath.Contains("/resolve/main/", StringComparison.Ordinal))
.Select(model => model.DownloadableResource!.Value.Url)
.ToArray();

Assert.Empty(unpinnedModels);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current regression test only validates RemoteModels.UltralyticsModelFiles. To make this test comprehensive and future-proof against any new model collections or properties added to RemoteModels, we can use reflection to scan all public static properties for downloadable resources (RemoteResource and HybridModelFile). This ensures that any executable Hugging Face models added anywhere in RemoteModels in the future will automatically be validated.

using System.Reflection;
using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Models;

namespace StabilityMatrix.Tests.Core;

public class RemoteModelsTests
{
    [Fact]
    public void ExecutableHuggingFaceModelsUsePinnedRevisions()
    {
        var executableExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
        {
            ".bin",
            ".ckpt",
            ".pt",
            ".pth",
        };

        var properties = typeof(RemoteModels).GetProperties(BindingFlags.Public | BindingFlags.Static);
        var resources = new List<RemoteResource>();

        foreach (var prop in properties)
        {
            var value = prop.GetValue(null);
            if (value is IEnumerable<RemoteResource> remoteResources)
            {
                resources.AddRange(remoteResources);
            }
            else if (value is IEnumerable<HybridModelFile> hybridModels)
            {
                resources.AddRange(hybridModels
                    .Where(m => m.DownloadableResource.HasValue)
                    .Select(m => m.DownloadableResource!.Value));
            }
            else if (value is HybridModelFile singleHybrid && singleHybrid.DownloadableResource.HasValue)
            {
                resources.Add(singleHybrid.DownloadableResource.Value);
            }
        }

        var unpinnedModels = resources
            .Where(resource => resource.Url.Host == "huggingface.co")
            .Where(resource => executableExtensions.Contains(Path.GetExtension(resource.Url.AbsolutePath)))
            .Where(resource => resource.Url.AbsolutePath.Contains("/resolve/main/", StringComparison.Ordinal))
            .Select(resource => resource.Url)
            .ToArray();

        Assert.Empty(unpinnedModels);
    }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have read the CLA Document and I hereby sign the CLA

@ungrav

ungrav commented Jul 16, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@ungrav

ungrav commented Jul 16, 2026

Copy link
Copy Markdown
Author

recheck

@mohnjiles

Copy link
Copy Markdown
Contributor

Hi @ungrav, thanks for the submission! Seems reasonable, though we use MSTest in the StabilityMatrix.Tests project, not XUnit, which is why the build is failing. Happy to review again once that's fixed. Thank you!


public class RemoteModelsTests
{
[Fact]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm not sure this PR needs tests exactly, but you will need to change to MSTest format, we're not using xunit and this isn't building right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants