Merged PR #707 - Fixes password leakage to terminal

Created a new JSON serializer called `UNSAFE_JSON` that will serialize everything, including sensitive information. And `JSON` which is the default up to this point now safely ignores any sensitive information in dictionaries marked with `!`, for instance `{"!password" : "mypassword"}` will be omitted from any output.
This commit is contained in:
Anton Hvornum 2021-11-11 09:59:42 +00:00 committed by GitHub
commit e3e62039f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 20 additions and 15 deletions

View File

@ -94,15 +94,17 @@ class Filesystem:
if partition.get('filesystem', {}).get('format', False):
if partition.get('encrypted', False):
if not partition.get('password'):
if not partition.get('!password') and not storage['arguments'].get('!encryption-password'):
if storage['arguments'] == 'silent':
raise ValueError(f"Missing encryption password for {partition['device_instance']}")
else:
from ..user_interaction import get_password
partition['password'] = get_password(f"Enter a encryption password for {partition['device_instance']}")
partition['!password'] = get_password(f"Enter a encryption password for {partition['device_instance']}")
elif not partition.get('!password') and storage['arguments'].get('!encryption-password'):
partition['!password'] = storage['arguments']['!encryption-password']
partition['device_instance'].encrypt(password=partition['password'])
with luks2(partition['device_instance'], storage.get('ENC_IDENTIFIER', 'ai') + 'loop', partition['password']) as unlocked_device:
partition['device_instance'].encrypt(password=partition['!password'])
with luks2(partition['device_instance'], storage.get('ENC_IDENTIFIER', 'ai') + 'loop', partition['!password']) as unlocked_device:
if not partition.get('format'):
if storage['arguments'] == 'silent':
raise ValueError(f"Missing fs-type to format on newly created encrypted partition {partition['device_instance']}")

View File

@ -121,11 +121,11 @@ class JsonEncoder:
for key, val in list(obj.items()):
if isinstance(val, dict):
# This, is a EXTREMELY ugly hack.. but it's the only quick way I can think of to trigger a encoding of sub-dictionaries.
val = json.loads(json.dumps(val, cls=JSON))
val = json.loads(json.dumps(val, cls=UNSAFE_JSON))
else:
val = JsonEncoder._encode(val)
val = JsonEncoder._unsafe_encode(val)
copy[JsonEncoder._encode(key)] = val
copy[JsonEncoder._unsafe_encode(key)] = val
return copy
else:
return JsonEncoder._encode(obj)

View File

@ -176,7 +176,9 @@ class Installer:
for mountpoint in sorted(mountpoints.keys()):
if mountpoints[mountpoint]['encrypted']:
loopdev = storage.get('ENC_IDENTIFIER', 'ai') + 'loop'
password = mountpoints[mountpoint]['password']
if not (password := mountpoints[mountpoint].get('!password', None)):
raise RequirementError(f"Missing mountpoint {mountpoint} encryption password in layout: {mountpoints[mountpoint]}")
with luks2(mountpoints[mountpoint]['device_instance'], loopdev, password, auto_unmount=False) as unlocked_device:
unlocked_device.mount(f"{self.target}{mountpoint}")

View File

@ -195,7 +195,7 @@ def generic_multi_select(options, text="Select one or more of the options above
def select_encrypted_partitions(block_devices :dict, password :str) -> dict:
root = find_partition_by_mountpoint(block_devices, '/')
root['encrypted'] = True
root['password'] = password
root['!password'] = password
return block_devices

View File

@ -243,15 +243,16 @@ def perform_filesystem_operations():
fs.load_layout(archinstall.storage['disk_layouts'][drive.path])
def perform_installation(mountpoint):
user_credentials = json.dumps({
user_credentials = {
"!users" : archinstall.arguments['!users'],
"!superusers" : archinstall.arguments['!users'],
"!root-password" : archinstall.arguments['!users'],
"!encryption-password" : archinstall.arguments['!encryption-password'],
}, indent=4, sort_keys=True, cls=archinstall.UNSAFE_JSON)
"!superusers" : archinstall.arguments['!superusers'],
"!root-password" : archinstall.arguments['!root-password'],
}
if archinstall.arguments.get('!encryption-password'):
user_credentials["!encryption-password"] = archinstall.arguments.get('!encryption-password')
with open("/var/log/archinstall/user_credentials.json", "w") as config_file:
config_file.write(user_credentials)
config_file.write(json.dumps(user_credentials, indent=4, sort_keys=True, cls=archinstall.UNSAFE_JSON))
"""
Performs the installation steps on a block device.