From 82cb52d64830c6831aa42913ecfce011d3d2c7ce Mon Sep 17 00:00:00 2001 From: joeywashburn <58124021+joeywashburn@users.noreply.github.com> Date: Mon, 2 Feb 2026 08:16:28 -0800 Subject: [PATCH] Sanitize SSH key whitespace to prevent validation errors (#16179) Strip leading and trailing whitespace from SSH keys in validate_ssh_private_key() to handle common copy-paste scenarios where hidden newlines cause base64 decoding failures. Changes: - Added data.strip() in validate_ssh_private_key() before calling validate_pem() - Added test_ssh_key_with_whitespace() to verify keys with leading/trailing newlines are properly sanitized and validated This prevents the confusing "HTTP 500: Internal Server Error" and "binascii.Error: Incorrect padding" errors when users paste SSH keys with accidental whitespace. Fixes #14219 Signed-off-by: Joey Washburn --- awx/main/tests/unit/test_validators.py | 19 +++++++++++++++++++ awx/main/validators.py | 2 ++ 2 files changed, 21 insertions(+) diff --git a/awx/main/tests/unit/test_validators.py b/awx/main/tests/unit/test_validators.py index 925ea64335..2512ab28af 100644 --- a/awx/main/tests/unit/test_validators.py +++ b/awx/main/tests/unit/test_validators.py @@ -132,6 +132,25 @@ def test_cert_with_key(): assert not pem_objects[1]['key_enc'] +def test_ssh_key_with_whitespace(): + # Test that SSH keys with leading/trailing whitespace/newlines are properly sanitized + # This addresses issue #14219 where copy-paste can introduce hidden newlines + valid_key_with_whitespace = "\n\n" + TEST_SSH_KEY_DATA + "\n\n" + pem_objects = validate_ssh_private_key(valid_key_with_whitespace) + assert pem_objects[0]['key_type'] == 'rsa' + assert not pem_objects[0]['key_enc'] + + # Test with just leading whitespace + valid_key_leading = "\n\n\n" + TEST_SSH_KEY_DATA + pem_objects = validate_ssh_private_key(valid_key_leading) + assert pem_objects[0]['key_type'] == 'rsa' + + # Test with just trailing whitespace + valid_key_trailing = TEST_SSH_KEY_DATA + "\n\n\n" + pem_objects = validate_ssh_private_key(valid_key_trailing) + assert pem_objects[0]['key_type'] == 'rsa' + + @pytest.mark.parametrize( "var_str", [ diff --git a/awx/main/validators.py b/awx/main/validators.py index 751d38060b..ad1552996b 100644 --- a/awx/main/validators.py +++ b/awx/main/validators.py @@ -181,6 +181,8 @@ def validate_ssh_private_key(data): certificates; should handle any valid options for ssh_private_key on a credential. """ + # Strip leading and trailing whitespace/newlines to handle common copy-paste issues + data = data.strip() return validate_pem(data, min_keys=1)