pg.ddx.io  pgsql-www@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tristan Partin <tristan@partin.io>
To: pgsql-www <pgsql-www@lists.postgresql.org>
Subject: Re: Broken SSH Key Parsing
Date: Mon, 17 Aug 2026 16:08:51 +0000
Message-ID: <DKRCKXI6J43G.3MQR3PFS7KB76@partin.io> (raw)
In-Reply-To: <DKMDXC18PP0D.126KL701ABSLA@partin.io>
References: <DKMDXC18PP0D.126KL701ABSLA@partin.io>

On Tue Aug 11, 2026 at 8:08 PM UTC, Tristan Partin wrote:
> Hey folks,
>
> I just got access to a Git repository on postgresql.org, so I started 
> going through the motions of adding an SSH key to my profile. I was 
> unable to add my key as-is, so I figured that I would flag the issue. My 
> public SSH key looks something like this:
>
> 	ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDPYnw8WWCrgL0sXijK7BY1Qz7KJlQZNe+ErNNwmfqazAd/CuTNNdENj21R6iR2CsjoEZ1prFcj/hPDV/j4nf7s= email@example.com (hostname)
>
> Accordingto to SSH key documentation[0], an SSH key is composed of 
> 3 components:
>
> 	A B C
>
> A: The key type
> B: Base64-encoded public key
> C: An optional comment
>
> The problem with this key in particular is the comment. If I remove 
> `(hostname)` from the key, postgresql.org will accept the key. I have 
> a suspicion that we are probably incorrectly validating the key. Some 
> pseudocode that would illustrate my hypothesis:
>
> 	keys = []
> 	for t in text.splitlines():
> 		sections = t.split(" ")
> 		if len(sections) < 2 or len(sections) > 3:
> 			raise ValueError("Invalid SSH key format")
>
> 		keys.append(OpenSSHKey(sections[0], sections[1], sections[2] if len(sections) == 3 else None))
>
> I am happy to investigate this further if I can get read access to the 
> postgresql.org site.
>
> I find my current comment format, including the hostname, to be useful 
> when identifying the email and machine the key belongs to. I'll work 
> around it for now.
>
> [0]: https://sshref.dev/#intro_legc_pub

Here is a patch to improve things a bit. We should probably add some 
unit tests for this.

-- 
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)

Attachments:

  [text/x-patch] v1-0001-Improve-SSH-key-parsing.patch (1.9K, ../DKRCKXI6J43G.3MQR3PFS7KB76@partin.io/2-v1-0001-Improve-SSH-key-parsing.patch)
  download | inline diff:
From 966817a060cbda6fe2fdc802c26eb197425e6ae4 Mon Sep 17 00:00:00 2001
From: Tristan Partin <tristan@partin.io>
Date: Mon, 17 Aug 2026 15:46:40 +0000
Subject: [PATCH v1] Improve SSH key parsing

We previously rejected SSH keys with comments that included spaces.
Nothing in the SSH key specification forbids that.

Signed-off-by: Tristan Partin <tristan@partin.io>
---
 pgweb/core/models.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/pgweb/core/models.py b/pgweb/core/models.py
index 63eb8275..0da661da 100644
--- a/pgweb/core/models.py
+++ b/pgweb/core/models.py
@@ -258,18 +258,22 @@ def date(self):
 
 
 # Options, keytype, key, comment. But we don't support options.
-def validate_sshkey(key):
+def validate_sshkey(key: str):
     lines = key.splitlines()
     for k in lines:
-        pieces = k.split()
+        pieces = k.split(maxsplit=2)
         if len(pieces) == 0:
             raise ValidationError("Empty keys are not allowed")
-        if len(pieces) > 3:
+        if len(pieces) < 2:
             raise ValidationError('Paste each ssh key without options, e.g. "ssh-rsa AAAAbbbcc mykey@machine"')
         if pieces[0] == 'ssh-dss':
             raise ValidationError("For security reasons, ssh-dss keys are not supported")
         if pieces[0] not in _valid_keytypes:
-            raise ValidationError("Only keys of types {0} are supported, not {1}.".format(", ".join(_valid_keytypes), pieces[0]))
+            raise ValidationError(
+                'Only keys of types {0} are supported, not "{1}". '
+                'If you pasted a key with options (e.g. from an authorized_keys file), '
+                'remove the options field before the key type.'.format(", ".join(_valid_keytypes), pieces[0])
+            )
         try:
             base64.b64decode(pieces[1])
         except Exception as e:
-- 
Tristan Partin
https://tristan.partin.io



view thread (7+ messages)  latest in thread

Message-ID: <DKRCKXI6J43G.3MQR3PFS7KB76@partin.io>
Permalink:  ../DKRCKXI6J43G.3MQR3PFS7KB76@partin.io/
Also on:    postgresql.org/message-id/DKRCKXI6J43G.3MQR3PFS7KB76@partin.io

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-www@postgresql.org
  Cc: tristan@partin.io, pgsql-www@lists.postgresql.org
  Subject: Re: Broken SSH Key Parsing
  In-Reply-To: <DKRCKXI6J43G.3MQR3PFS7KB76@partin.io>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox