# Issues with SSO and '~' character

**URL:** https://meta.discourse.org/t/issues-with-sso-and-character/351582
**Category:** Support
**Created:** [February 11, 2025, 3:28am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582 "2025-02-11T03:28:44Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![sweetbeems](https://avatars.discourse-cdn.com/v4/letter/s/7c8e57/32.png) [@sweetbeems](https://meta.discourse.org/u/sweetbeems)
#### Post date: [February 11, 2025, 3:28am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/1 "2025-02-11T03:28:44Z")

</div>

Hi everyone,

So recently I discovered that if I inclue ‘~’ in a user’s bios, I get a base64decode error from Discourse. It can handle all sorts of other problematic characters just fine (spaces, =, %, &) but not ~ for some reason.

Anyone else encounter this issue?

My first thought is that perhaps my encoding could be wrong, but I haven’t been able figure it out.

Here is my python implementation of the encoding:

```plaintext
return_payload = base64.urlsafe_b64encode(parse.urlencode(params).encode())

```

which is then put directly into ‘sso’ in the requests (along with all the other necessary information)

```plaintext
resp = requests.post(
       ".../admin/users/sync_sso",
        data={'sso': return_payload, ...}
        headers={...}
)

```

I’ve updated my discourse to the newest version (3.5.0.beta1-dev), still persists.

Thanks for any help!

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [February 11, 2025, 6:51am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/2 "2025-02-11T06:51:05Z")

</div>

It propably should be fixed, but that question is above my paygrade and skills. But out of pure practical curiosity: why someone would use a tilde in a bio?

---

<div class="post-metadata">

### Author: ![sweetbeems](https://avatars.discourse-cdn.com/v4/letter/s/7c8e57/32.png) [@sweetbeems](https://meta.discourse.org/u/sweetbeems)
#### Post date: [February 11, 2025, 7:36am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/3 "2025-02-11T07:36:58Z")

</div>

Heh I guess that’s a reasonable question.

I run a multilingual forum and in other cultures ‘~’ is frequently used. As an example, in Korean, it’s often used at the end to soften your tone, like ‘If you have any questions, let me know~’

---

<div class="post-metadata">

### Author: ![thoka](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thoka/32/115652_2.png) [@thoka](https://meta.discourse.org/u/thoka)
#### Post date: [February 11, 2025, 7:42am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/4 "2025-02-11T07:42:59Z")

</div>

So this is a bug report and not a support request?

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [February 11, 2025, 7:47am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/5 "2025-02-11T07:47:38Z")

</div>

Is it? A bug is something that is done, but doesn’t work. This is more like question ”is it done or not” and then it’s more #Contribute > Feature if not a support question.

---

<div class="post-metadata">

### Author: ![sweetbeems](https://avatars.discourse-cdn.com/v4/letter/s/7c8e57/32.png) [@sweetbeems](https://meta.discourse.org/u/sweetbeems)
#### Post date: [February 11, 2025, 7:50am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/6 "2025-02-11T07:50:14Z")

</div>

> [@thoka](#):
>
> So this is a bug report and not a support request?

> [@Jagster](#):
>
> Is it? A bug is something that is done, but doesn’t work. This is more like question ”is it done or not” and then it’s more #feature::category if not a support question.

Yeah I think Bug is appropriate. I believe i’m base64 encoding it correctly, so discourse should decode it correctly too.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [February 11, 2025, 9:02am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/7 "2025-02-11T09:02:26Z")

</div>

I think it is a bug (provided we can repro it)

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [February 11, 2025, 10:43am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/8 "2025-02-11T10:43:40Z")

</div>

> [@sweetbeems](#):
>
> Here is my python implementation of the encoding:
> 
> ```plaintext
> return_payload = base64.urlsafe_b64encode(parse.urlencode(params).encode())
> 
> ```

It looks like `urlsafe_b64encode` replaces some characters in the base64 encoding. From [the docs](https://docs.python.org/3/library/base64.html#base64.urlsafe_b64encode):

> Encode [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object) _s_ using the URL- and filesystem-safe alphabet, which substitutes `-` instead of `+` and `_` instead of `/` in the standard Base64 alphabet, and return the encoded [`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes). The result can still contain `=` .

That means the result isn’t standard base64, and won’t be compatible with Discourse’s decoding.

I’d recommend using the normal `b64encode` function instead. Your HTTP library should take care of the URL escaping if needed.

---

<div class="post-metadata">

### Author: ![sweetbeems](https://avatars.discourse-cdn.com/v4/letter/s/7c8e57/32.png) [@sweetbeems](https://meta.discourse.org/u/sweetbeems)
#### Post date: [February 20, 2025, 7:13am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/9 "2025-02-20T07:13:38Z")

</div>

Upon further investigation, I was indeed encoding it wrong.

Here is what I ended up with, for posterity:

```plaintext
return_payload = base64.b64encode(parse.urlencode(kwargs).encode("utf-8"))
h = hmac.new(secret.encode("utf-8"), return_payload, digestmod=hashlib.sha256)
resp = requests.post(
       ".../admin/users/sync_sso",
        data={"sso": return_payload, "sig": h.hexdigest()}
        headers={...}
)

```

And if you’re doing the redirect, be sure to parse.urlencode that {“sso”…}.

Thanks for the help @sam and @david !

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [March 22, 2025, 7:14am UTC](https://meta.discourse.org/t/issues-with-sso-and-character/351582/10 "2025-03-22T07:14:04Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
