unverbuggt / mkdocs-encryptcontent-plugin

A MkDocs plugin that encrypt/decrypt markdown content with AES
https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/
MIT License
130 stars 16 forks source link

Feature request : pass decryption key as an url parameter #49

Closed vlebert closed 1 year ago

vlebert commented 1 year ago

Hi,

I was digging on this project, and I was wondering if it could be possible to pass the decryption key as an url parameter, or if the implementation of this feature is somehow possible ?

The idea is to be able to make "sharelinks" containing the decryption key. Doing so, the note would be readable for any people having the sharelink, and encrypted for other people.

This cool Obsidian project inspired me this idea : https://github.com/mcndt/obsidian-quickshare

Cheers

unverbuggt commented 1 year ago

I was thinking of a feature like this some time ago, but somehow forgot about it. As you can see, the whole password handling is being reworked to a password inventory during the last months, so it should be possible.

I'd suggest doing it like this:

If we add it to the url like this https://example.com/somesite/#encryptcontent=xxsharekeyyy it is readable by javascript, but we won't be able to pass anchors anymore (edit: anchors do not work anyway on decrypted pages is now fixed). I need to check if other options exist

unverbuggt commented 1 year ago

I've pushed some changes that enable adding credentials (base64url coded) to the link's hash part: testbench-share.

Good thing is that the hash part (normally intended for adding anchor links) is not transmitted to the server. Anchors still work, but they need to be added at the end of the URL.

But I haven't got a good idea how to generate these share codes (besides the testbench site)... Should we output them at the end of the build process?

Besides, I still think it is a good idea to auto generate long passwords for the credentials if intended to share them this way.

unverbuggt commented 1 year ago

I found a way to auto-generate safe share links https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/testbench/share/#automatic-sharelink.

However, the auto-generated passwords can be edited in the sharelinks.yml file. Just clone the current development version and activate the configuration with sharelinks: true.

vlebert commented 1 year ago

Hi @unverbuggt

Thank you very much for digging into this. I was wondering : why using # part instead of url parameters ?hash=xxx ?

Considering the workflow, I was thinking the following:

To make it possible to share with multiple users and allow revoking, the password frontmatter parameter could be a list instead of a single string value.

What do you think of this approach ? I didn't understand why do you wan to "encode" the secret with this page : https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/testbench/share/#automatic-sharelink

Last idea : to share multi-page private note, maybe it is possible to add an optionnal client-site JS script that will add current url parameters to all anchor links on the page ?

unverbuggt commented 1 year ago

The main reason for using # instead of ? is, that ? will pop up in the server's log files, while # won't be transmitted to the server at all.

The random strong passwords per level are saved to sharelinks.yml and you can edit them as you wish. The test bench where you can encode them yourself was just the first thought.

But one could also add the password directly to the markdown file with password: xxxx and we could encode the password to a sharelink with sharelink: true or something like that and output it somehow. I don't want to write to markdown files with the plugin, so it cannot be auto-generated this way...

But how should the plugin output the sharelinks? By console output or writing to a separate text file?

vlebert commented 1 year ago

Ok I get ii

You want to generate the "sharelink" with b64 encoding. I'll try next week your dev version

Maybe b64 encoding could be optionnal : I mean if we generate a password with only alphanulerical characters, there is no need to b64 encode or ?

And therefore the user could find the sharelink directly in the markdown file.

So maybe

But maybe you don't like quick and dirty :)

unverbuggt commented 1 year ago

I've made an additional change that allows non-base64url encoded credetials, see testbench.

So either https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/testbench/userpass1/#P2RhdmU6b3hpZGl6ZQ or https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/testbench/userpass1/#?dave:oxidize will work.

Use it like this:

https://urltosite.com/encryptedstuff/#?username:password#optionalanchor if credentials are username/password.
https://urltosite.com/encryptedstuff/#?:password#optionalanchor if credentials are just password or obfuscate.
If you don't want to jump to an anchor, leave the #optionalanchor part out.

But be aware: If non-alphanumeric characters are used in the username or password, you'll need to urlencode them (f.ex. writing %20 for the space character).

I think of reworking the automatic generated passwords for the sharelinks part. Maybe this is not really useful...
Instead, I think of writing the urls where sharelink:true metatag is set in markdown to a external text file, but I need to think about this...

vlebert commented 1 year ago

Hey @unverbuggt

So I did some tests, it works like a charm. Here are my notes :

Any idea for my last point ?

Now just waiting for a release to be able to use it with netlify deploy

cheers

unverbuggt commented 1 year ago

Hi,

thanks for testing. I've pushed some changes (please "git pull" and "pip --force-reinstall")

You'll need to add sharelinks: true to the plugin configuration to activate the feature (if you don't add this, it will be deactivated).

I came to the conclusion that auto-generation of passwords (even for sharelinks) is a two-sided sword. It could lead to false sense of security, as the generation could be faulty or manipulated. So it's best to leave it up to the user to generate strong passwords or better pass phrases.

So if you add sharelink: true (be aware it's not sharelinks) to the meta tag area of a markdown file, then it will look up the pages password/obfuscate or level (take the first credential it finds), use it to generate the share link and save it to a text file at the end of the build process.

For your last point: you forgot the '#' in front of '?'. But I found that some text editors seem to make the # disappear somehow (thinking you did a typo). Anyway, the character ? is not meant for the '#' part of the url, it is meant to add data to the GET request. So I've replaced '?' by '!' and ':' by '~' (because it wasn't safe from URLencode).

But it seems like I'm now in encoding hell: Made a few tests with non-latin1 characters at passwords and usernames and saw that python does encode differently than javascript. Need to figure this out... edit: omg this is dumb

edit: still in encoding hell: how to escape '~' if used in username or password? '!' is not a big problem, because it just marks the start of the sharelink.

unverbuggt commented 1 year ago

This really gave ma a headache. Now I know why I wanted to bas64 encode in the first place (same reason HTTP basic auth does it). There is only one rule: usernames must not include ":" character (passwords may use that character).

The plugin now creates base64url encoded sharelinks for all pages with meta sharelink: true and saves them to "sharelinks.txt".

However, If you wish to add alphanumeric passwords to the url yourself, you can do so (check out the "b" variations here).
The Syntax is https://example.com/protectedsite/#!user:password or https://example.com/protectedsite/#!password (":" can be omitted if only password).

But these links might only work one-way, because it seems browsers tend to strip the "#" once the link is copied from them