Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ In-scope components include:
- client-side settings/runtime scripts
- import/export and backup/restore flows
- release packaging and update metadata
- archive extraction, durable storage, and process-execution boundaries
- privacy sanitization and browser-side injection defenses

## Package Verification

The Unraid plugin manifest publishes SHA-256 digests for shipped archives. Stable
GitHub releases also publish GitHub artifact attestations for build provenance and
the CycloneDX SBOM. Verification steps and the trust model are documented in
[`docs/security/PACKAGE_TRUST.md`](../docs/security/PACKAGE_TRUST.md).

Out-of-scope:

Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/release-on-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:

permissions:
contents: write
id-token: write
attestations: write

concurrency:
group: folderview-plus-release
Expand Down Expand Up @@ -148,6 +150,21 @@ jobs:
chmod +x scripts/remote_publish_guard.sh
bash scripts/remote_publish_guard.sh

- name: Attest release archive provenance
if: steps.release_scope.outputs.should_publish == '1'
uses: actions/attest@36051bcae73b7c2a8a6945a48cbf80953c6baa35 # v4.2.0
with:
subject-path: |
${{ steps.release_meta.outputs.archive }}
${{ steps.release_meta.outputs.checksum }}

- name: Attest release archive SBOM
if: steps.release_scope.outputs.should_publish == '1'
uses: actions/attest@36051bcae73b7c2a8a6945a48cbf80953c6baa35 # v4.2.0
with:
subject-path: ${{ steps.release_meta.outputs.archive }}
sbom-path: docs/sbom.cdx.json

- name: Ensure GitHub CLI
if: steps.release_scope.outputs.should_publish == '1'
run: |
Expand Down
Binary file removed archive/folderview.plus-2026.07.23.12.txz
Binary file not shown.
1 change: 0 additions & 1 deletion archive/folderview.plus-2026.07.23.12.txz.sha256

This file was deleted.

Binary file added archive/folderview.plus-2026.07.28.04.txz
Binary file not shown.
1 change: 1 addition & 0 deletions archive/folderview.plus-2026.07.28.04.txz.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0c337e163cb23c7ebffc72d89d026c49ed70328706f4b22814eba18ecae4a4a2 folderview.plus-2026.07.28.04.txz
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This folder holds project documentation that does not need to stay at the reposi
- [TRANSLATING.md](TRANSLATING.md)
- [TRANSLATION_PLATFORM.md](TRANSLATION_PLATFORM.md)
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
- [Content Security Policy readiness](security/CSP_READINESS.md)
- [Package trust and provenance](security/PACKAGE_TRUST.md)

## Architecture

Expand Down
48 changes: 48 additions & 0 deletions docs/releases/2026.07.28.04.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# FolderView Plus 2026.07.28.04

This security update strengthens archive handling, operating-system boundaries,
browser injection defenses, durable storage, managed themes, and release
provenance without removing compatibility fallbacks required by Unraid.

## Archive and filesystem security

- Security: Preflight icon asset-pack archives before extraction with strict path,
file-type, entry-count, nesting-depth, per-file-size, and total-size limits.
- Security: Reject archive links, special files, traversal paths, unexpected
top-level content, and post-extraction filesystem objects.
- Security: Use private temporary staging, restrictive permissions, protected
cleanup, and atomic activation for verified icon packs.
- Security: Constrain durable writes to approved plugin and Docker storage roots,
reject symbolic-link components, and create atomic temporary files with mode
`0600`.
- Security: Harden custom-icon upload staging and reject symbolic-link source,
destination, rename, and deletion paths.

## Process and browser security

- Security: Replace direct shell execution with one allowlisted, shell-free
`proc_open` boundary for Docker, VM, and Tailscale operations.
- Security: Validate runtime object names and actions, use fixed executable
candidates and argument arrays, cap output, and terminate timed-out processes.
- Security: Replace plugin-owned inline event handlers with a delegated,
declarative event bridge that uses an explicit function allowlist and restricted
argument grammar without `eval` or the `Function` constructor.
- Security: Add a deterministic CSP-readiness report and CI guard while retaining
report-only guidance because FolderView Plus shares its document with Unraid and
other plugins.

## Theme and release supply-chain security

- Security: Reject executable legacy CSS, remote imports, external network URLs,
and HTML data URLs from managed or custom themes before persistence and render.
- Security: Publish SHA-256 package and icon-pack digests in the Unraid manifest
while retaining MD5 only for compatibility.
- Security: Validate package SHA-256 sidecars and embedded build metadata during
release and installation checks.
- Security: Publish commit-pinned GitHub OIDC provenance and CycloneDX SBOM
attestations for stable release archives.
- Docs: Document package verification, attestation verification, CSP constraints,
and the expanded vulnerability-reporting scope.
- Test: Add regression contracts for archive limits, shell-free argument handling,
durable-path containment, declarative event bindings, CSP readiness, package
checksums, provenance, and SBOM attestations.
15 changes: 14 additions & 1 deletion docs/sbom.cdx.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"component": {
"type": "application",
"name": "FolderView Plus",
"version": "2026.07.28.02",
"version": "2026.07.28.04",
"properties": [
{
"name": "folderview-plus:runtime-dependencies",
Expand All @@ -24,6 +24,19 @@
}
},
"components": [
{
"type": "application",
"name": "actions/attest",
"version": "36051bcae73b7c2a8a6945a48cbf80953c6baa35",
"scope": "optional",
"purl": "pkg:github/actions/attest@36051bcae73b7c2a8a6945a48cbf80953c6baa35",
"properties": [
{
"name": "folderview-plus:usage",
"value": "build-only-github-action"
}
]
},
{
"type": "application",
"name": "actions/cache",
Expand Down
30 changes: 30 additions & 0 deletions docs/security/CSP_READINESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Content Security Policy readiness

FolderView Plus runs inside web documents owned by the Unraid webGUI. It cannot safely
set an enforced page-wide Content Security Policy by itself: that header would also
govern Unraid and every other plugin loaded into the same document.

The repository therefore uses a staged, report-only approach:

1. Plugin-owned inline event attributes are prohibited. UI actions use
`folderviewplus.csp-events.js`, which accepts only an explicit function allowlist
and a restricted argument grammar. It does not use `eval()` or `Function`.
2. Managed theme CSS rejects executable legacy CSS, `@import`, external network
URLs, and HTML data URLs before storage or rendering.
3. `scripts/csp_readiness_guard.mjs` inventories remaining inline scripts, styles,
dynamic script creation, and HTML string sinks. Its deterministic output is
stored in `docs/security/csp-readiness.json`.
4. CI rejects any return of inline handlers, `eval()`, or the `Function`
constructor, and rejects a stale readiness report.

Regenerate and verify the report with:

```bash
node scripts/csp_readiness_guard.mjs --write
node scripts/csp_readiness_guard.mjs
```

The report includes a candidate report-only policy. It is documentation for
host-level testing, not a header emitted by the plugin. Enforced CSP should only be
considered after Unraid exposes a plugin-safe nonce/hash mechanism or after a
host-level report confirms that Unraid and installed peer plugins remain compatible.
41 changes: 41 additions & 0 deletions docs/security/PACKAGE_TRUST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Package trust and provenance

FolderView Plus uses layered verification so current Unraid releases remain
compatible while stronger supply-chain evidence is available to administrators.

## Installation verification

- The plugin manifest supplies both MD5 and SHA-256 for the core package and icon
asset pack. MD5 remains only for compatibility with older plugin-manager paths;
SHA-256 is the security boundary.
- `scripts/release_guard.sh` requires the manifest SHA-256, checked-in checksum
sidecar, archive filename, package version, and archive bytes to agree exactly.
- The package contains `build-metadata.json`, which records the channel, version,
source-content digest, archive URL, and icon-pack identity.
- Icon-pack installation verifies SHA-256 before a bounded archive preflight,
extracts into private staging, rejects links/special files/traversal, and
atomically activates the verified tree.
- The installed version is written only after package configuration and icon-pack
activation complete. Existing install reporting identifies upgrades, reinstalls,
downgrades, failures, and the prior version.

## GitHub attestations

Stable releases generated by `release-on-main.yml` publish:

- a signed provenance attestation for the `.txz` archive and `.sha256` sidecar;
- a signed CycloneDX SBOM attestation binding `docs/sbom.cdx.json` to the archive.

The workflow uses GitHub OIDC and the official, commit-pinned `actions/attest`
action. It does not use a stored signing key.

After downloading a stable release archive, verify it online with:

```bash
gh attestation verify folderview.plus-YYYY.MM.DD.UU.txz \
--repo alexphillips-dev/FolderView-Plus
```

Unraid installation does not require the GitHub CLI and continues to use manifest
SHA-256 verification. Attestations are an additional origin/build claim for
administrators and release auditing, not a replacement for the on-system checksum.
Loading
Loading