- Added is_valid_directory function to validate directory paths, ensuring they do not contain control characters and are within a specified length.
- Introduced quote_shell_arg to safely quote shell arguments, preventing command injection.
- Created build_cd_command to generate a command for changing directories in a shell.
- Enhanced the LoginHandler to utilize a login rate limiter, preventing brute-force attacks by tracking failed login attempts.
- Implemented an EncodingCache to optimize encoding detection for SSH connections.
- Updated the UI to include an input field for specifying an initial directory upon login, with appropriate validation and hints.
- Added a quickbar in the terminal interface for easy access to copy and paste functionality.
- Introduced a toast notification system to provide feedback on copy actions.
- Refactored connection storage to encrypt passwords at rest, improving security.
- Updated various templates and styles to accommodate new features and improve user experience.
When establishing a connection to an SSH server, WebSSH tries to guess
at its encoding using a command sent prior to opening the terminal.
Unfortunately, sometimes this can return data which does not form proper
input for the `encode` function used by `is_valid_encoding` to test
whether the encoding is known.
In particular, we ran in to a case where the server was returning a
string which had a \0 in it when converted to ascii. That raised a
`ValueError` (as opposed to `LookupError`), which was uncaught.
Handle the `ValueError` case as well, treating it as an unknown encoding
so that we fall back on the default.
WsockHandler stores a weak reference to the ssh backend worker. The
worker closes itself if the backend connection closes (e.g. the user
exists the ssh session). That happens in parallel to the websocket
handler processing messages, so it is possible for a message to arrive
when the worker no longer has any strong references, leading to an
exception being thrown.
Handle this case by treating the None worker the same way we do invalid
messages: by simply returning.
The worker ID right now is typically based off the address of an object
in memory. This could be guessed. While the worker is tied to a
specific IP, there is a chance an off-path attacker could be hosted
behind the same IP as the caller. They could possibly guess the worker
id of an unclaimed session by observing the sequence of IDs presented to
themselves, leading to them gaining access to an already authenticated
SSH session.
Use the python secrets module to generate a cryptographically secure
token to use as the worker ID. This shoud be much harder to guess.