Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crash on jwt encode command with @ in secret #335

Open
dhra opened this issue Jun 30, 2024 · 6 comments
Open

App crash on jwt encode command with @ in secret #335

dhra opened this issue Jun 30, 2024 · 6 comments

Comments

@dhra
Copy link

dhra commented Jun 30, 2024

Summary

The jwt encode command crashes when using a secret containing special characters. The crash occurs due to the inability to read the file specified by the --secret parameter.

Steps to reproduce

Run the following command

jwt encode --secret=@@@vovocha '{"hello":"world"}'

Actual result

thread 'main' panicked at src/utils.rs:42:44:
Unable to read file @@vovocha
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Expected behavior

Users should be able to create a valid JWT with secrets that start with the '@' symbol.

More details:

jwt --version
jwt 6.1.0

OS: Ubuntu

@mike-engel
Copy link
Owner

Thanks for writing in, and sorry for the delay @dhra. The use of @ in secrets denotes that the secret should be a path to a certificate to encrypt the body.

Unfortunately I don't have a good suggestion for how to get around this issue. You could change your secret to be something like --secret='\@@@vovocha', but that's not the same secret, so that may not work for you.

If you have suggestions for alternatives, please let me know

@t18n
Copy link

t18n commented Nov 11, 2024

This seems to affect also $ and some other special characters I also use the app to generate token to test jsonwebtoken lib, however, the backend always failed to verify the token. The weird thing is, when I test the token on jwt.io with the secret "Something$W", both Something\$W and Something$W are verified succcessfully.

The use of @ in secrets denotes that the secret should be a path to a certificate to encrypt the body.

@mike-engel isn't this more flexible with a new flag like --cert instead?

@mike-engel
Copy link
Owner

@mike-engel isn't this more flexible with a new flag like --cert instead?

In theory, yes. Using @, however, is a common command line pattern, and it's what we've chosen to adopt for this project.

@t18n I'm unable to get $ to break encoding. Can you provide an example where other special characters break the tool when used in a secret? The only special character we recognize is @.

jwt encode -S "$hi there" -P test=one

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MzI1NTgzODAsInRlc3QiOiJvbmUifQ.xlqNPiPOemiHJewgefV_bKrmpozbtKMVLx9MbsMOy1M

@t18n
Copy link

t18n commented Nov 25, 2024

@t18n I'm unable to get $ to break encoding. Can you provide an example where other special characters break the tool when used in a secret? The only special character we recognize is @.

It will still return the token, but if I verify it with the secret used to generate the token, it will fail (testable with jwt.io). For example:

jwt encode --secret="LyT$W" '{"iss":"test", "aud": "test"}'

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ0ZXN0IiwiaWF0IjoxNzMyNTcxOTM2LCJpc3MiOiJ0ZXN0In0.k1CvGNfbqyHr3FZPIOi3vst2IlUS7I_seXERvm7UTwk

This will fail when verified with LyT$W as a JWT secret.

@mike-engel
Copy link
Owner

@t18n I believe this is a shell issue, and not an issue with jwt-cli or rust.

I'm using zsh locally, and I've added a dbg!(env::args_os); at the top of main. Here are some experiments and the results:

λ cargo run -- encode -S hi$there -P test=one

[src/main.rs:40:5] env::args_os() = ArgsOs {
    inner: [
        "target/debug/jwt",
        "encode",
        "-S",
        "hi",
        "-P",
        "test=one",
    ],
}
λ cargo run -- encode -S 'hi$there' -P test=one

[src/main.rs:40:5] env::args_os() = ArgsOs {
    inner: [
        "target/debug/jwt",
        "encode",
        "-S",
        "hi$there",
        "-P",
        "test=one",
    ],
}
λ cargo run -- encode -S "hi$there" -P test=one

[src/main.rs:40:5] env::args_os() = ArgsOs {
    inner: [
        "target/debug/jwt",
        "encode",
        "-S",
        "hi",
        "-P",
        "test=one",
    ],
}
λ cargo run -- encode -S hi\$there -P test=one

[src/main.rs:40:5] env::args_os() = ArgsOs {
    inner: [
        "target/debug/jwt",
        "encode",
        "-S",
        "hi$there",
        "-P",
        "test=one",
    ],
}

As you can see, the shell is truncating the string after $ before it even gets to rust. You (and everyone else) have two options:

  1. Escape special characters (e.g. hi\$there, hi\"there, etc.)
  2. Use your shell's feature that preserves the literal values in the string (e.g. 'hi$there' instead of "hi$there" in bash/zsh)

@t18n
Copy link

t18n commented Dec 3, 2024

@mike-engel thank you so much for the investigation and the solution. I use zsh as well and this is it. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants