From 27f8f6956a1f44884b1ff07a71174a308e818e99 Mon Sep 17 00:00:00 2001 From: talyz Date: Tue, 4 May 2021 15:59:15 +0200 Subject: [PATCH] replace-secret: Init Add a small utility script which securely replaces secrets in files. Doing this with `sed`, `replace-literal` or similar utilities leaks the secrets through the spawned process' `/proc//cmdline` file. --- .../replace-secret/replace-secret.nix | 35 +++++++++++++++++++ .../replace-secret/replace-secret.py | 28 +++++++++++++++ .../replace-secret/test/expected_long_output | 30 ++++++++++++++++ .../replace-secret/test/expected_short_output | 4 +++ .../replace-secret/test/input_file | 4 +++ pkgs/build-support/replace-secret/test/passwd | 1 + pkgs/build-support/replace-secret/test/rsa | 27 ++++++++++++++ pkgs/top-level/all-packages.nix | 2 ++ 8 files changed, 131 insertions(+) create mode 100644 pkgs/build-support/replace-secret/replace-secret.nix create mode 100755 pkgs/build-support/replace-secret/replace-secret.py create mode 100644 pkgs/build-support/replace-secret/test/expected_long_output create mode 100644 pkgs/build-support/replace-secret/test/expected_short_output create mode 100644 pkgs/build-support/replace-secret/test/input_file create mode 100644 pkgs/build-support/replace-secret/test/passwd create mode 100644 pkgs/build-support/replace-secret/test/rsa diff --git a/pkgs/build-support/replace-secret/replace-secret.nix b/pkgs/build-support/replace-secret/replace-secret.nix new file mode 100644 index 00000000000..e04d1aed5f7 --- /dev/null +++ b/pkgs/build-support/replace-secret/replace-secret.nix @@ -0,0 +1,35 @@ +{ stdenv, lib, python3 }: + +stdenv.mkDerivation { + name = "replace-secret"; + buildInputs = [ python3 ]; + phases = [ "installPhase" "checkPhase" ]; + installPhase = '' + install -D ${./replace-secret.py} $out/bin/replace-secret + patchShebangs $out + ''; + doCheck = true; + checkPhase = '' + install -m 0600 ${./test/input_file} long_test + $out/bin/replace-secret "replace this" ${./test/passwd} long_test + $out/bin/replace-secret "and this" ${./test/rsa} long_test + diff ${./test/expected_long_output} long_test + + install -m 0600 ${./test/input_file} short_test + $out/bin/replace-secret "replace this" <(echo "a") short_test + $out/bin/replace-secret "and this" <(echo "b") short_test + diff ${./test/expected_short_output} short_test + ''; + meta = with lib; { + platforms = platforms.all; + maintainers = with maintainers; [ talyz ]; + license = licenses.mit; + description = "Replace a string in one file with a secret from a second file"; + longDescription = '' + Replace a string in one file with a secret from a second file. + + Since the secret is read from a file, it won't be leaked through + '/proc//cmdline', unlike when 'sed' or 'replace' is used. + ''; + }; +} diff --git a/pkgs/build-support/replace-secret/replace-secret.py b/pkgs/build-support/replace-secret/replace-secret.py new file mode 100755 index 00000000000..30ff41d491b --- /dev/null +++ b/pkgs/build-support/replace-secret/replace-secret.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +import argparse +from argparse import RawDescriptionHelpFormatter + +description = """ +Replace a string in one file with a secret from a second file. + +Since the secret is read from a file, it won't be leaked through +'/proc//cmdline', unlike when 'sed' or 'replace' is used. +""" + +parser = argparse.ArgumentParser( + description=description, + formatter_class=RawDescriptionHelpFormatter +) +parser.add_argument("string_to_replace", help="the string to replace") +parser.add_argument("secret_file", help="the file containing the secret") +parser.add_argument("file", help="the file to perform the replacement on") +args = parser.parse_args() + +with open(args.secret_file) as sf, open(args.file, 'r+') as f: + old = f.read() + secret = sf.read().strip("\n") + new_content = old.replace(args.string_to_replace, secret) + f.seek(0) + f.write(new_content) + f.truncate() diff --git a/pkgs/build-support/replace-secret/test/expected_long_output b/pkgs/build-support/replace-secret/test/expected_long_output new file mode 100644 index 00000000000..37bd66b905f --- /dev/null +++ b/pkgs/build-support/replace-secret/test/expected_long_output @@ -0,0 +1,30 @@ +beginning +middle $6$UcbJUl5g$HRMfKNKsLTfVbcQb.P5o0bmZUfHDYkWseMSuZ8F5jSIGZZcI3Jnit23f8ZeZOGi4KL86HVM9RYqrpYySOu/fl0 not this +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzrru6v5tfwQl6L+rOUjtLo8kbhMUlCLXP7TYngSGrkzPMWe+ +0gB04UAmiPZXfBmvj5fPqYiFjIaEDHE/SD41vJB/RJKKtId2gCAIHhBLkbr+4+60 +yEbLkJci5i4kJC1dt8OKFEzXkaVnwOSgjH+0NwO3bstZ+E70zMXS9+NS71qGsIEb +5J1TnacwW/u6CdFyakLljWOXOR14rLIpiPBBFLf+oZiepjIhlWXWHqsxZOb7zMI0 +T4W5WJ2dwGFsJ8rkYaGZ+A5qzYbi/KmHqaSPaNDsyoi7yJhAhKPByALJU916+8QO +xOnqZxWGki3PDzCslRwW4i3mGbZlBQMnlfbN3QIDAQABAoIBAHDn1W7QkFrLmCy6 +6bf6pVdFZF8d2qJhOPAZRClhTXFKj+pqv+QPzcXr9F/fMr6bhK/G+Oqdnlq2aM4m +16oMF+spe+impEyeo1CsreJFghBQcb9o8qFjUPBiKvROBP0hLcscZ4BYy29HSBgo +harWYEWfqQJA251q+fYQoP0z0WrZKddOZbRRnJ0ICRxAE7IEtDT6EYt8R9oGi2j4 +/rpdW+rYGjW3TcmzdR7lpVMJRLlbMbSdR8n6cI6rnfySygcoE5tFX5t/YZSNbBPg +GebKCbEHYNTTG8bC1qjUyzlbEQ6XYWvFO7HTKU7105XpjYTQFByeo0IVkin0o5KW +t7eQWb0CgYEA6zZUWsYoQ13nXEU6Ky89Q9uhesMfaJ/F2X5ikQSRqRvrR3QR+ULe +eNnCl10O9SiFpR4b5gSbLSHMffxGN60P1nEO4CiIKE+gOii8Kdk5htIJFy/dcZUc +PuPM+zD9/6Is5sAWUZo45bnT6685h6EjM2+6zNZtx/XMjSfWbHaY+HMCgYEA4QAy +6ZEgd6FHnNfM/q2o8XU3d6OCdhcu26u6ydnCalbSpPSKWOi6gnHK4ZnGdryXgIYw +hRkvYINfiONkShYytotIh4YxUbgpwdvJRyKa2ZdWhcMmtFzZOcEVzQTKBasFT74C +Wo0iybZ++XZh3M0+n7oyyx39aR7diZ+/zq6PnG8CgYB8B1QH4cHNdDDRqPd5WhmW +NLQ7xbREOSvc+hYDnkMoxz4TmZL4u1gQpdNEeZ+visSeQvg3HGqvK8lnDaYBKdLW +IxvS+8yAZSx6PoyqDI+XFh4RCf5dLGGOkBTAyB7Hs761lsiuEwK5sHmdJ/LQIBot +v1bjOJb/AA/yxvT8kLUtHQKBgGIA9iwqXJv/EfRNQytDdS0HQ4vHGtJZMr3YRVoa +kcZD3yieo4wqguLCsf4mPv4FE3CWAphW6f39+yTi9xIWLSy56nOtjdnsf7PDCh8E +AbL5amSFJly1fKDda6OLjHt/jKa5Osk6ZIa8CP6cA/BrLfXg4rL6cyDQouqJPMDH +5CHdAoGBAIChjbTyoYvANkoANCK4SuqLUYeiYREfiM3sqHe1xirK1PPHw03ZLITl +ltjo9qE6kPXWcTBVckTKGFlntyCT283FC0/vMmHo8dTdtxF4/wSbkqs3ORuJ3p5J +cNtLYGD3vgwLmg6tTur4U60XN+tYDzWGteez8J9GwTMfKJmuS9af +-----END RSA PRIVATE KEY----- +end diff --git a/pkgs/build-support/replace-secret/test/expected_short_output b/pkgs/build-support/replace-secret/test/expected_short_output new file mode 100644 index 00000000000..3c81b2e2f99 --- /dev/null +++ b/pkgs/build-support/replace-secret/test/expected_short_output @@ -0,0 +1,4 @@ +beginning +middle a not this +b +end diff --git a/pkgs/build-support/replace-secret/test/input_file b/pkgs/build-support/replace-secret/test/input_file new file mode 100644 index 00000000000..1e7eadfaab2 --- /dev/null +++ b/pkgs/build-support/replace-secret/test/input_file @@ -0,0 +1,4 @@ +beginning +middle replace this not this +and this +end diff --git a/pkgs/build-support/replace-secret/test/passwd b/pkgs/build-support/replace-secret/test/passwd new file mode 100644 index 00000000000..68f266226e4 --- /dev/null +++ b/pkgs/build-support/replace-secret/test/passwd @@ -0,0 +1 @@ +$6$UcbJUl5g$HRMfKNKsLTfVbcQb.P5o0bmZUfHDYkWseMSuZ8F5jSIGZZcI3Jnit23f8ZeZOGi4KL86HVM9RYqrpYySOu/fl0 diff --git a/pkgs/build-support/replace-secret/test/rsa b/pkgs/build-support/replace-secret/test/rsa new file mode 100644 index 00000000000..138cc99ed22 --- /dev/null +++ b/pkgs/build-support/replace-secret/test/rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzrru6v5tfwQl6L+rOUjtLo8kbhMUlCLXP7TYngSGrkzPMWe+ +0gB04UAmiPZXfBmvj5fPqYiFjIaEDHE/SD41vJB/RJKKtId2gCAIHhBLkbr+4+60 +yEbLkJci5i4kJC1dt8OKFEzXkaVnwOSgjH+0NwO3bstZ+E70zMXS9+NS71qGsIEb +5J1TnacwW/u6CdFyakLljWOXOR14rLIpiPBBFLf+oZiepjIhlWXWHqsxZOb7zMI0 +T4W5WJ2dwGFsJ8rkYaGZ+A5qzYbi/KmHqaSPaNDsyoi7yJhAhKPByALJU916+8QO +xOnqZxWGki3PDzCslRwW4i3mGbZlBQMnlfbN3QIDAQABAoIBAHDn1W7QkFrLmCy6 +6bf6pVdFZF8d2qJhOPAZRClhTXFKj+pqv+QPzcXr9F/fMr6bhK/G+Oqdnlq2aM4m +16oMF+spe+impEyeo1CsreJFghBQcb9o8qFjUPBiKvROBP0hLcscZ4BYy29HSBgo +harWYEWfqQJA251q+fYQoP0z0WrZKddOZbRRnJ0ICRxAE7IEtDT6EYt8R9oGi2j4 +/rpdW+rYGjW3TcmzdR7lpVMJRLlbMbSdR8n6cI6rnfySygcoE5tFX5t/YZSNbBPg +GebKCbEHYNTTG8bC1qjUyzlbEQ6XYWvFO7HTKU7105XpjYTQFByeo0IVkin0o5KW +t7eQWb0CgYEA6zZUWsYoQ13nXEU6Ky89Q9uhesMfaJ/F2X5ikQSRqRvrR3QR+ULe +eNnCl10O9SiFpR4b5gSbLSHMffxGN60P1nEO4CiIKE+gOii8Kdk5htIJFy/dcZUc +PuPM+zD9/6Is5sAWUZo45bnT6685h6EjM2+6zNZtx/XMjSfWbHaY+HMCgYEA4QAy +6ZEgd6FHnNfM/q2o8XU3d6OCdhcu26u6ydnCalbSpPSKWOi6gnHK4ZnGdryXgIYw +hRkvYINfiONkShYytotIh4YxUbgpwdvJRyKa2ZdWhcMmtFzZOcEVzQTKBasFT74C +Wo0iybZ++XZh3M0+n7oyyx39aR7diZ+/zq6PnG8CgYB8B1QH4cHNdDDRqPd5WhmW +NLQ7xbREOSvc+hYDnkMoxz4TmZL4u1gQpdNEeZ+visSeQvg3HGqvK8lnDaYBKdLW +IxvS+8yAZSx6PoyqDI+XFh4RCf5dLGGOkBTAyB7Hs761lsiuEwK5sHmdJ/LQIBot +v1bjOJb/AA/yxvT8kLUtHQKBgGIA9iwqXJv/EfRNQytDdS0HQ4vHGtJZMr3YRVoa +kcZD3yieo4wqguLCsf4mPv4FE3CWAphW6f39+yTi9xIWLSy56nOtjdnsf7PDCh8E +AbL5amSFJly1fKDda6OLjHt/jKa5Osk6ZIa8CP6cA/BrLfXg4rL6cyDQouqJPMDH +5CHdAoGBAIChjbTyoYvANkoANCK4SuqLUYeiYREfiM3sqHe1xirK1PPHw03ZLITl +ltjo9qE6kPXWcTBVckTKGFlntyCT283FC0/vMmHo8dTdtxF4/wSbkqs3ORuJ3p5J +cNtLYGD3vgwLmg6tTur4U60XN+tYDzWGteez8J9GwTMfKJmuS9af +-----END RSA PRIVATE KEY----- diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index d757226744a..a1f9240d59c 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -13592,6 +13592,8 @@ in remake = callPackage ../development/tools/build-managers/remake { }; + replace-secret = callPackage ../build-support/replace-secret/replace-secret.nix { }; + replacement = callPackage ../development/tools/misc/replacement { }; retdec = callPackage ../development/tools/analysis/retdec {