Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
899 stars 242 forks source link

[question] JWT decode failed #192

Closed klob closed 2 years ago

klob commented 2 years ago

Describe the bug decode jwt throw std::runtime_error("Invalid input: not within alphabet")

How To Reproduce (Include if Applicable) print-claims.cpp

#include <iostream>
#include <jwt-cpp/jwt.h>

int main() {
    std::string token =     "eyJ0eXAiOiJKV1QifQ==.eyJpc3MiOiJxdWlja2VyLWxpdmUiLCJhdWQiOiJsaXZlbGluayIsImlhdCI6MTYzOTAxODY1MCwiZXhwIjoxNjM5MDYxODUwLCJzcyI6eyJsbGlkIjoxMDAwMTIyLCJhcHBpZCI6ImxpdmVsaW5rIiwib3BlbmlkIjoia2xvYmxpdS1QQzMiLCJsb2dpblR5cGUiOjgsImNyZWF0ZVRpbWUiOjE2Mzg4NjA3MjUsImF1ZCI6ImxpdmVsaW5rIn19.f7d2cfc0f877077e1004af399309dee99f2d93155a6e8b481c9c3bc44d16140b";
    auto decoded = jwt::decode(token);

    for (auto& e : decoded.get_payload_claims())
        std::cout << e.first << " = " << e.second << std::endl;
}

Expected behavior

I decoded the jwt on a online JSON Web Tokens (JWT) (https://www.box3.cn/tools/jwt.html), the website can decode properly while jwt-cpp can not.

Screenshots image

image

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

Logs (Include/Attach if Applicable)

Click to expand log ``` 0x00007FFE92584F99 处(位于 print-claims.exe 中)引发的异常: Microsoft C++ 异常: std::runtime_error,位于内存位置 0x000000CF830FEF28 处。 0x00007FFE92584F99 处(位于 print-claims.exe 中)有未经处理的异常: Microsoft C++ 异常: std::runtime_error,位于内存位置 0x000000CF830FEF28 处。 0x00007FFE92584F99 处(位于 print-claims.exe 中)引发的异常: Microsoft C++ 异常: std::runtime_error,位于内存位置 0x000000CF830FEF28 处。 0x00007FFE92584F99 处(位于 print-claims.exe 中)有未经处理的异常: Microsoft C++ 异常: std::runtime_error,位于内存位置 0x000000CF830FEF28 处。 ```
prince-chrismc commented 2 years ago

Hmm, that's very interesting 🤔 right away I noticed the base64 padding characters which should not be present

I use this tool which flagged this spec

https://datatracker.ietf.org/doc/html/rfc4648#section-5

From https://www.rfc-editor.org/rfc/rfc7515.html#section-2

Base64url Encoding Base64 encoding using the URL- and filename-safe character set defined in Section 5 of RFC 4648 [RFC4648], with all trailing '=' characters omitted (as permitted by Section 3.2)

It's by design that this library rejects your "invalid" format token... but I'd love to hear why you are using token that way! Please provide sources if this is a missing feature

klob commented 2 years ago

@prince-chrismc Maybe our developers did't consider about it too much. You can fix this just in case other developers don't consider about it too. Or simply close the issue. Thanks for your help.

prince-chrismc commented 2 years ago

Since the behavior is to spec and adding an alternative could be error prone, I'd rather not make any changes at this time.

That being said you can very easily do this on your end. The base64 decoding (thats where the exception comes from) is a template, so your devs can write whatever base64 algorithm you need.

https://github.com/Thalhammer/jwt-cpp/blob/55aaf31ad852e0b4666b2daf6b8b9e2e68b6c04a/include/jwt-cpp/jwt.h#L2494

Hopefully this means you can benefit from our library 😄

prince-chrismc commented 2 years ago

Lastly thank you for the amazing bug 🐛 report!

Thalhammer commented 2 years ago

You might even get away without using a custom base64 decoding. We have an alphabet option for the default base64 decoder and we do ship a "default" base64 alphabet. (https://github.com/Thalhammer/jwt-cpp/blob/55aaf31ad852e0b4666b2daf6b8b9e2e68b6c04a/include/jwt-cpp/base.h#L26) So you should be able to do something like this (untested):

auto decoded = jwt::decode(token, [](const typename json_traits::string_type& str) {
                  return base::decode<alphabet::base64>(base::pad<alphabet::base64>(str));
              });