diff options
| author | Reepca Russelstein <reepca@russelstein.xyz> | 2026-06-09 22:35:20 -0500 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2026-07-02 19:42:47 +0200 |
| commit | fc06ada0602983350646c741531ec2b1887f3407 (patch) | |
| tree | 6189efa43a32ae9968931984d187b0b6b0364a8d /tests | |
| parent | ed0a9721f8a20d6ddcf6a0495302f502b3f7bb17 (diff) | |
scripts: substitute: restrict where "file://" URIs can be used [security fix].
There are two potential places where file:// URIs could be used in 'guix
substitute':
1. The substitute urls, which are used for fetching narinfos. These can come
from the daemon, via daemon option "substitute-urls", from the client, via
daemon option "untrusted-substitute-urls", or from 'guix discover'. The
latter two must not be allowed to provide file:// URIs, since that could be
used to cause the daemon to read private files, files in /proc or /dev,
etc, and various parts of those files may show up in the backtrace from
'guix substitute'.
2. The narinfos themselves, which may offer arbitrarily many URIs to download
the nar of the store item in question. These URIs do not need to be
in the signed portion of the narinfo, so they may be attacker-controlled.
These should also not be allowed to provide file:// URIs, with the sole
exception being in the case of the test suite for the sake of simplifying
the tests.
To accomplish this, we error out of 'guix substitute' if
"untrusted-substitute-urls" includes a file:// URI, and we filter out all
file:// URIs from those provided by 'guix discover'. We also ignore all
narinfos containing file:// URIs unless '%allow-unsafe-substitute-uris?' is #t.
* guix/scripts/substitute.scm (%allow-unsafe-substitute-uris?,
%allow-unsafe-narinfo-uris?): new parameters.
(process-substitution, process-substitution/fallback): honor
'%allow-unsafe-substitute-uris?'.
(uri-safe?, narinfo-uris-safe?, assert-safe-uris): new procedures.
(%default-substitute-urls): use assert-safe-uris for the
"untrusted-substitute-urls" daemon option.
(%local-substitute-urls): filter out file:// URIs.
* tests/substitute.scm ("file:// URI prohibited by default"): new test. Set
'%allow-unsafe-substitute-uris?' to #t after it finishes.
Change-Id: I34d7e58b5a01c7cc61b52fcd61b547bba2ce4300
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/substitute.scm | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/tests/substitute.scm b/tests/substitute.scm index cd75d56b981..10b74db084e 100644 --- a/tests/substitute.scm +++ b/tests/substitute.scm | |||
| @@ -206,6 +206,26 @@ a file for NARINFO." | |||
| 206 | ;; daemon. | 206 | ;; daemon. |
| 207 | (%reply-file-descriptor #f) | 207 | (%reply-file-descriptor #f) |
| 208 | 208 | ||
| 209 | (test-equal "file:// URI prohibited by default" | ||
| 210 | "not-found\n" | ||
| 211 | (with-output-to-string | ||
| 212 | (lambda () | ||
| 213 | (%allow-unsafe-substitute-uris? #f) | ||
| 214 | (let ((narinfo %narinfo)) | ||
| 215 | (with-narinfo (string-append narinfo "Signature: " | ||
| 216 | (signature-field narinfo) "\n") | ||
| 217 | (call-with-temporary-directory | ||
| 218 | (lambda (directory) | ||
| 219 | (with-input-from-string (string-append | ||
| 220 | "substitute " (%store-prefix) | ||
| 221 | "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo " | ||
| 222 | directory "/shouldnotbewritten\n") | ||
| 223 | (lambda () | ||
| 224 | (guix-substitute "--substitute")))))))))) | ||
| 225 | |||
| 226 | ;; Allow these for ease of testing for the rest of the tests | ||
| 227 | (%allow-unsafe-substitute-uris? #t) | ||
| 228 | |||
| 209 | 229 | ||
| 210 | (test-equal "query narinfo without signature" | 230 | (test-equal "query narinfo without signature" |
| 211 | "" ; not substitutable | 231 | "" ; not substitutable |
