Problem to solve
Two independent hardening gaps found while reading the repository. Both are behavioural changes rather than one-line fixes, so per CONTRIBUTING.md I am raising them before opening anything. Filed separately from #125 because neither shares its cause.
1. Dockerfile has no USER instruction, so ENTRYPOINT ["skillevaluator"] runs as uid 0.
This matters more here than in a typical image. Tier 3's whole purpose is evaluating untrusted third-party skills, and the documented deployment is this container. Starting that work from root rather than an unprivileged account removes a cheap layer of containment.
2. Generated HTML reports load remote JavaScript with no Subresource Integrity.
src/skillevaluator/reporting/templates/report.html.j2:3468:
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
It is the only remote asset in the template, has no integrity attribute, and floats on a major version. Every generated report therefore executes whatever jsDelivr serves at the moment someone opens it — which can be long after the scan ran, on a reviewer's machine, in a page rendered from scan output. It also means a report cannot be read on an air-gapped machine, and an archived report does not render the same way twice.
Proposed approach
I have not sent patches for either, because both have a trade-off that is yours to decide rather than mine.
For the container: add a non-root user and USER before ENTRYPOINT. The catch is that the tool writes results directories, and a non-root uid can break bind-mounted output paths owned by root on the host. Tell me which paths must stay writable and I will send a PR that keeps them working.
For the report template, two ways to close it and I do not know which you would prefer:
- Pin + SRI —
chart.js@4.x.y with an integrity hash and crossorigin="anonymous". Smallest diff; still needs network to render a chart.
- Vendor
chart.js into the report — larger reports, but they render fully offline and an archived report stays reproducible years later. For a tool whose output is evidence, that second property may be worth the bytes.
Happy to send a PR for either once you have a preference.
Additional context
Found alongside #125 during an external read-only review of the public repository at ea9b23971f53f3123382d37ebca13c91753f8d24 (v0.2.1). No NVIDIA system was accessed. No credentials, private datasets, or benchmark content are involved in either observation.
Before submitting
Problem to solve
Two independent hardening gaps found while reading the repository. Both are behavioural changes rather than one-line fixes, so per CONTRIBUTING.md I am raising them before opening anything. Filed separately from #125 because neither shares its cause.
1.
Dockerfilehas noUSERinstruction, soENTRYPOINT ["skillevaluator"]runs as uid 0.This matters more here than in a typical image. Tier 3's whole purpose is evaluating untrusted third-party skills, and the documented deployment is this container. Starting that work from root rather than an unprivileged account removes a cheap layer of containment.
2. Generated HTML reports load remote JavaScript with no Subresource Integrity.
src/skillevaluator/reporting/templates/report.html.j2:3468:It is the only remote asset in the template, has no
integrityattribute, and floats on a major version. Every generated report therefore executes whatever jsDelivr serves at the moment someone opens it — which can be long after the scan ran, on a reviewer's machine, in a page rendered from scan output. It also means a report cannot be read on an air-gapped machine, and an archived report does not render the same way twice.Proposed approach
I have not sent patches for either, because both have a trade-off that is yours to decide rather than mine.
For the container: add a non-root user and
USERbeforeENTRYPOINT. The catch is that the tool writes results directories, and a non-root uid can break bind-mounted output paths owned by root on the host. Tell me which paths must stay writable and I will send a PR that keeps them working.For the report template, two ways to close it and I do not know which you would prefer:
chart.js@4.x.ywith anintegrityhash andcrossorigin="anonymous". Smallest diff; still needs network to render a chart.chart.jsinto the report — larger reports, but they render fully offline and an archived report stays reproducible years later. For a tool whose output is evidence, that second property may be worth the bytes.Happy to send a PR for either once you have a preference.
Additional context
Found alongside #125 during an external read-only review of the public repository at
ea9b23971f53f3123382d37ebca13c91753f8d24(v0.2.1). No NVIDIA system was accessed. No credentials, private datasets, or benchmark content are involved in either observation.Before submitting