Programmatical share access token

Description

Background:

Client is currently evaluating the use of External Share for Confluence to create an online user guide.

To ensure a seamless experience for their customers, we need the ability to programmatically auto-login to Password Protected external share links. This will eliminate the need to manually enter the password and restrict access to the Confluence page exclusively through our system via iFrame.

Secure Solution

  • When a share link is password-protected, append a special parameter to the URL, as follows:
    {{https://confluence.external-share.com/content/ {UUID}

    ?unlock=

    {jwt}

    }}

  • The unlock parameter is a JSON Web Token defined as follow:
    • JWT header:
      • alg: HS256
    • JWT payload:
      • nbf: Time on which the JWT will start to be accepted for processing. Integer representing seconds past 1970-01-01 00:00:00Z
      • exp: Expiration time on and after which the JWT must not be accepted for processing. Integer representing seconds past 1970-01-01 00:00:00Z.
      • iss: UUID of the share
    • JWT signature:
      • secret: random 256 bits stored in the db as shared_page.unlock_secret column of type bytea
  • The unlock_secret value:
    • may be stored plain in db for the time being as share’s UUID and password are unencrypted too
    • will be autogenerated using secure pseudo random generator guarana.security.RandomUtil.generateBytes(32)
    • will be automatically created on share creation
    • after column creation, existing shares will receive secrets in a migration routine
    • is shown in UI below password field as a read only text input with hexadecimal representation and Copy button
    • can be changed in the UI via Change button
    • is returned in Web API as a hexadecimal string
  • JWT checks on unlocking:
    • alg == HS256
    • nbf <= now < exp
    • exp - nbf <= 60
    • scope == share’s UUID
    • JWT signature
  • on successful JWT validation:
    • store the same cookie as the page would have been accessed using password

For testing:

Website for generating JWT:
https://dinochiesa.github.io/jwt/

What to fill:

After filling data you have to click left arrow to generate JWT.

Linked issues

relates to
Issue Type Icon ESFC-408 Programmatical share access token Priority: Medium
Released
Issue Type Icon ESFJ-651 Delete null checks and add database NOT NULL constrain after unlockSecret DB migration Priority: Medium
Released
Issue Type Icon ESFJ-562 External share for Jira link protected with password does not function in iframe on Confluence Page and shared page Priority: Medium
Released
Issue Type Icon ESFJ-695 Add custom domain support for programmatical share access token Priority: Medium
Released
Issue Type Icon ESFJ-697 Add link to docs for share access token in share form Priority: Medium
Released
Issue Type Icon SUP-395 Embedde confluence articles via external share + iframe Compnay Intranet Priority: Medium
Closed

Activity

Automation for Jira 24 October 2023, 08:00

Hello @Michał Błaszczykowski,

Please merge code to dev branch.
This is the best moment to add more information that can be helpful to prepare release notes.

  • Can you prepare short overview of change that can be used in release notes?

  • Please provide short GIF that showcase feature.

  • If GIF make no sense, can you provide image that highlights feature that can be used in release notes (cropped & annotated)?

Parsa Shiva 23 October 2023, 11:40

@Michał Błaszczykowski Fix verified and Improvement implemented - QA environment.

Parsa Shiva 20 October 2023, 13:58

@Michał Błaszczykowski Following issue occurs - QA environment.

After adding the key the page loads back into the access URL endpoint: https://jes-qa.warsawdynamics.com/access?uuid=e9806b06-29ba-45f4-93d5-f59dc802dffc&redirect=https://jira-test-3.kz-test.ovh/issue/e9806b06-29ba-45f4-93d5-f59dc802dffc

Improvement suggestion

In case of expired JWT - an unknown issue occurred message is displayed. This error messaged can be improved and handled.

Michał Błaszczykowski 9 October 2023, 11:32

@Krzysztof Surdacki please take a final look

Krzysztof Surdacki 6 October 2023, 05:33

@{712020:7f4a5822-7b83-4950-ad69-f30f97b87f71} Found one major bug and a couple enhancements.

Michał Błaszczykowski 5 October 2023, 10:22

@Krzysztof Surdacki please take a look at corrected version

Krzysztof Surdacki 3 October 2023, 15:53

@Michał Błaszczykowski Please change commented parts of the change or explain why it is ok the way it is now.

Michał Błaszczykowski 3 October 2023, 13:41

@Krzysztof Surdacki it’s ready

Krzysztof Surdacki 3 October 2023, 13:05

@Michał Błaszczykowski Please resolve all conflicts with dev before asking for review.

Build also failed:

https://bitbucket.org/%7B8d3fc384-2d68-40d9-a994-c4d0d7086569%7D/%7B1dbc18bb-54b4-4788-8de0-44bdf37fe7ca%7D/pipelines/results/28315

Automation for Jira 3 October 2023, 13:01

Hello @Krzysztof Bogdan,
Task is ready for review.

@Michał Błaszczykowski please make sure reviewer
have easy access to contend to be reviewed.

If this is code change. Please make sure PR is created.
If this is new documentation, blogpost, etc. Please provide link to page.

Michał Błaszczykowski 3 October 2023, 12:59

@Krzysztof Bogdan please check new implementation

Krzysztof Surdacki 25 September 2023, 13:28

my insights:

  1. there is no need for base64 encoding integer representing expiration time

  2. requiring only expiration time we cannot check lifespan of an authorization token, so instead standard not valid before and not valid after timestamps should be use

  3. as the expiration timestamp is known, the only unknown is a password part which we should assume is week in cryptography sens (low entropy) so the problem here is the same as with hashing password in the database - it should not be done without really good salt (like 128~256 random bits) to protect against rainbow tables and it should be computationally expensive to prevent brute force attacks (PBKDF2, scrypt, Argon2).

  4. When the same password is used in different shares. The same token will unlock all those shares.

  5. SHA-256 is vulnerable to the Length extension attack. So I can imagine this:

    1. you somehow obtain some expired token with expiration like 1695646946

    2. because SHA-256 is vulnerable to the length extension attack you may simply generate new hash with a digit added at the end: 16956469460 !

my recommendations:

  1. we should not use the password used to protect the page as after intercepting the unlock key the attacker may work as long as he/she likes to brute-force the hash and obtain the password from it

    1. If we are insisted to use user provided passwords we should at least salt and computationally strengthen the password and limit the number or unlocking retries per minute.

  2. I think the shares should also have unlock secret generated alongside which would be some random 256 bits key like ovh.atlasinc.guarana.security.RandomUtil#generateSecretKey() which we could use for unlock key instead of user provided password.

  3. I see this situation as signing the timestamp of expiration. So we should not use our home made algorithm but instead use some well defined MAC algorithm. How about JWT (HS256 with payload containing exp, nbf and scp)?

@Krzysztof Bogdan

Automation for Jira 19 September 2023, 12:27

Hello @Michał Błaszczykowski ]

This is the best moment to add more information that can be helpful for tester.

  • What areas are affected?

  • What are potential edge cases?

  • Was it checked for XSS problems?

  • Does change affect security, is new data exposed?

Please attach - Before / After screenshot if possible.

Automation for Jira 18 September 2023, 13:25

Hello @Michał Błaszczykowski,
Change was reviewed and approved.
Task is ready to be deployed to QA.
Once it is deployed to QA please move ticket to "To Test"

Thank you!

Michał Błaszczykowski 18 September 2023, 13:18

@Krzysztof Bogdan changes implemented

Krzysztof Bogdan 18 September 2023, 09:12

@Michał Błaszczykowski I have requested changes

Automation for Jira 18 September 2023, 08:29

Hello @Krzysztof Bogdan,
Task is ready for review.

@Michał Błaszczykowski please make sure reviewer
have easy access to contend to be reviewed.

If this is code change. Please make sure PR is created.
If this is new documentation, blogpost, etc. Please provide link to page.

Automation for Jira 14 September 2023, 13:59

Hello @Krzysztof Bogdan

This is the best moment to add more description, wire-frames, comments.
Why we doing this?
What is expected result?