timvisee / send

:mailbox_with_mail: Simple, private file sharing. Mirror of https://gitlab.com/timvisee/send
https://send.vis.ee
Mozilla Public License 2.0
4.83k stars 280 forks source link

GUI Based Authentication #32

Open AliMickey opened 3 years ago

AliMickey commented 3 years ago

Implement built in authentication for uploading.

A simple password check should be enough i think, account based is overkill for this project.

ahrenstein commented 3 years ago

I agree. I originally tired using htaccess to protect the main page, but on the mobile site after the download succeeds, /download offers to let you try the service and upload without auth.

colans commented 3 years ago

I'm speculating here, but wouldn't authentication have fixed the original problem with malware on Mozilla's hosted version? If users are authenticated, that fixes the security hole. So with this in place, this tool becomes secure (or just running it behind a VPN).

AliMickey commented 3 years ago

I'm speculating here, but wouldn't authentication have fixed the original problem with malware on Mozilla's hosted version? If users are authenticated, that fixes the security hole. So with this in place, this tool becomes secure (or just running it behind a VPN).

Mozilla has been trying to cut costs recently, that could just be an excuse for shutting down this free service. Wouldn't have been cheap to run all that storage and traffic.

colans commented 3 years ago

Well, sure, but I mean it could have solved the malware problems.

timvisee commented 3 years ago

Implement built in authentication for uploading.

That would indeed be great for private instances.

I'm speculating here, but wouldn't authentication have fixed the original problem with malware on Mozilla's hosted version? If users are authenticated, that fixes the security hole.

Mozilla did implement this with Firefox Accounts, but Send was shut down before it reached the public due to other reasons.


I currently don't have the bandwidth to implement this, sadly. If there's someone that would like to give it a go, please do.

On a technical level, the password must be validated on the websocket before uploading. It doesn't affect end-to-end encryption on uploads so it shouldn't requite too significant changes. A password check on the upload page itself would probably be desirable as well.

AliMickey commented 3 years ago

I currently don't have the bandwidth to implement this, sadly. If there's someone that would like to give it a go, please do.

I'm happy to try, but i have never done anything with a project this 'big'. Is it possible if you could point towards the main files where uploading is done.

pirate commented 3 years ago

From reading through the code just now, it looks like a pretty decent auth system is actually already implemented in Send. It's designed to use Mozilla's open-source FXA (Firefox Accounts) service (which speaks OAuth 2.0 among other auth protocols):

To set up auth with Send + FXA, you should first run an FXA server in Docker, then point Send to it by configuring FXA_URL=https://url-of-fxa.example.com and the other FXA options here: https://github.com/timvisee/send/blob/master/server/config.js#L143.

I'm not sure if Send uses plain OAuth 2.0, or if it uses one of FXA's other hand-rolled auth protocols, that's something you'd have to dig into. The login() method here looks like plain OAuth 2.0 but I cant tell if there is more beyond that. If it just uses OAuth 2.0, then with some small tweaks you could point FXA_URL to any other OAuth 2.0 provider and use that instead (e.g. Auth0, CloudFlare Access, etc., many companies already have a compatible SAML provider).

You can find the existing auth flow and user account code in Send here:

If you want to re-implement auth to be simpler (e.g. password only instead of user accounts), I'd try to do so by reusing as much of the https://github.com/timvisee/send/blob/master/app/ui/account.js and https://github.com/timvisee/send/blob/master/app/user.js code as possible and just swapping out the API calls that Send makes to FXA methods https://github.com/timvisee/send/blob/master/app/fxa.js, instead of writing it completely from scratch.

Proposed implementation for simple hardcoded password re-using most of the existing Auth code:

  1. Add a hard-codable config var UI_PASSWORD to https://github.com/timvisee/send/blob/master/server/config.js (default is empty/null)
  2. Create a simple password entry form page ui/login.js that saves the password in a cookie on the frontend (no POST request needed)
  3. stub out the FXA/OAuth methods in https://github.com/timvisee/send/blob/master/app/ui/account.js used to cryptographically verify the OAuth 2.0 Bearer header in the old implementation, and have them check the cookie value against the static UI_PASSWORD config val instead
  4. Re-use the existing https://github.com/timvisee/send/blob/master/app/user.js User object and initialize it with dummy values for all authed users, that way the existing frontend https://github.com/timvisee/send/blob/master/app/ui/account.js UI shows them as a logged in user and provides a logout button
  5. Direct users to configure ANON_MAX_FILE_SIZE=0 if they want non-authed users to not be able to upload at all, otherwise they can keep it and have separate upload limits for anon users and users that have put the correct UI_PASSWORD on the /login page first

I don't have time to implement this myself, but maybe you or someone else can take a crack at it @AliMickey.

timvisee commented 3 years ago

CC @pirate

Thanks for taking a look into it. I do have some comments though.

From reading through the code just now, it looks like a pretty decent auth system is actually already implemented in Send.

Mozilla did indeed implement this. I am not sure if it was ever fully finished, and we're actually in the progress of fully removing it (see https://gitlab.com/timvisee/send/-/issues/3).

I'm not sure if Send uses plain OAuth 2.0, or if it uses one of FXA's other hand-rolled auth protocols, that's something you'd have to dig into.

It has been a while since I inspected their implementation, but I believe it was OAuth 2.0 with some hand rolled additions.

Direct users to configure ANON_MAX_FILE_SIZE=0 if they want non-authed users to not be able to upload at all, (...)

The ANON_MAX_FILE_SIZE variable has actually been removed.


Your proposed implementation seems like a valid approach. Thanks for writing it down!

pirate commented 3 years ago

Ah cool, didn't realize there was existing work to remove the old system. My proposed approach definitely wont work if the ANON_ values are totally removed, so scratch that path.

I think a minimalist login page -> cookie set -> header passed to unlock websocket as you originally suggested makes sense. We can tiptoe around the old auth code and leave the task of removing it for later.

dylangerdaly commented 3 years ago

Feel free to use my commit -> https://github.com/dylangerdaly/send/tree/password_protect

I've re-jigged the 'password' prompt to be used for authentication, it's super hacky and shouldn't be considered 'good'

timvisee commented 3 years ago

Feel free to use my commit -> https://github.com/dylangerdaly/send/tree/password_protect

I've re-jigged the 'password' prompt to be used for authentication, it's super hacky and shouldn't be considered 'good'

Nice work. At this moment your changes assume there always is a password to authenticate with, right? Meaning, this implementation doesn't make it optional.

dylangerdaly commented 3 years ago

Currently it's shoved in there, I'll try add a new UI element based on a config conditional time permitting.

timvisee commented 3 years ago

Currently it's shoved in there, I'll try add a new UI element based on a config conditional time permitting.

That would be awesome. I'd be happy to merge.

markuspfeifenberger commented 2 years ago

I agree. I originally tired using htaccess to protect the main page, but on the mobile site after the download succeeds, /download offers to let you try the service and upload without auth.

We did the same, using htaccess, but there are some tricky problems. One thing, that might help to hide the "try the service ..." button, to introduce a boolean ENV variable for this button (true ... show, false ...hide

dillfrescott commented 2 years ago

This suggestion seems to be exactly what Send needs at the moment. Seems like it would solve a lot of abuse of service situations!

readyblue commented 2 years ago

Feel free to use my commit -> https://github.com/dylangerdaly/send/tree/password_protect

I've re-jigged the 'password' prompt to be used for authentication, it's super hacky and shouldn't be considered 'good'

@dylangerdaly Your commit works great, thanks. Unfortunately ffsend (https://github.com/timvisee/ffsend) somehow does not work with it.

AliMickey commented 2 years ago

@timvisee Could we potentially get this merged and pushed to docker registry?

fritzcloud commented 2 years ago

That would be fantastic, also the environment for docker would be "AUTH_PASSWORD=xxxxx" correct?

martin-braun commented 2 years ago

This would also solve #72. I would welcome this feature a lot.

trymeouteh commented 2 years ago

I would like to see an optional password feature which is requires to upload files to an instance. This can allow the owner of the instance to use their instance for themselves only or with a group of friends they trust by sharing the password with.

yunhao-jiang commented 2 years ago

Also like this feature to be added. Since my server has limited storage space and bandwidth, I would only want the one with the password to use my server.

dylangerdaly commented 2 years ago

Just use my patch if you want to use it, I don't have the capacity to clean it up at the moment and don't need to password protect the files again

-------- Original Message -------- On Sep 30, 2022, 8:16 PM, YunhaoJiang wrote:

Also like this feature to be added. Since my server has limited storage space and bandwidth, I would only want the one with the password to use my server.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

dylangerdaly commented 2 years ago

It's possible to change ffsend to include the password, I'll create a patch and share it.

I haven't gotten around to adding a UI element for the password yet, I'm not very good at JavaScript/CSS lol.

Sent from ProtonMail mobile

-------- Original Message -------- On Jun 3, 2022, 2:49 AM, Fritz L. wrote:

That would be fantastic, also the environment for docker would be "AUTH_PASSWORD=xxxxx" correct?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

trymeouteh commented 2 years ago

If this is added, would be nice for the admin to add multiple password (accounts). This way you and let say a friend can only upload to the send instance and the admin has his own password while your friend has their own password for uploading files.

rcaillon-Iliad commented 2 years ago

If anyone is interested, I managed to setup an authentication portal which allows only some authenticated users to upload files using Caddy and Authelia. It supports Basic Authentication for uploading with ffsend.

Caddyfile

<DOMAIN> {
    # Authentication Portal
    handle /auth/* {
        reverse_proxy auth:9091
    }

    @basicauth {
        header Authorization Basic*
    }

    # Send via BasicAuth
    handle @basicauth {
        forward_auth auth:9091 {
            uri /auth/api/verify?auth=basic
            copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
        }
        reverse_proxy send:1443
    }

    # Send via Authentication Portal
    handle {
        forward_auth auth:9091 {
            uri /auth/api/verify?rd=https://<DOMAIN>/auth/
            copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
        }
        reverse_proxy send:1443
    }
}

authelia_configuration.yml

# ........

server:
  path: "auth"

# ........

access_control:
  default_policy: deny

  rules:
    - domain: '<DOMAIN>'
      policy: bypass
      resources:
        - '^(\/api)?\/download\/'
        - '^\/api\/metadata\/'
        - '\.(js|css|jpg|png|svg|woff2|txt)$'
      methods:
        - GET
        - HEAD
    - domain: '<DOMAIN>'
      policy: one_factor
      subject:
        - ['group:admins']

# ........
zt-luo commented 2 years ago

is this feature added now?

andresindlp commented 1 year ago

would love to have it added too

martin-braun commented 1 year ago

If this issue is still open, it's not, I cannot spot it. @timvisee is probably too busy to tackle this and I have him rather maintain this in peace. I'm pretty sure he is open for PRs though.

TheGITofTeo997 commented 1 year ago

@rcaillon-Iliad Hello, I've been trying the whole day to achieve your setup but unfortunately without success. I am very interested in it, could you please provide more detail or is it possible to contact you? Thanks

rcaillon-Iliad commented 1 year ago

@TheGITofTeo997 You can find here the full project. Feel free to ask if you need help.

TheGITofTeo997 commented 1 year ago

@rcaillon-Iliad I got the setup working now, thank you so much for sharing! Unfortunately i didn't know authelia so they were all new tools for me

xczh commented 1 year ago

Is there any progress on this issue? Uploading requires password verification while downloading not is a very practical feature. Is there any way to implement this function through nginx configuration files? 😄

martin-braun commented 1 year ago

I moved to https://github.com/psi-4ward/psitransfer/ which supports a simple password protection prior uploading as well as password protection on downloads, so it cannot be abused and shared links are protected.

trymeouteh commented 1 year ago

Would like this more than any other feature.

thmmsn commented 1 year ago

I moved to https://github.com/psi-4ward/psitransfer/ which supports a simple password protection prior uploading as well as password protection on downloads, so it cannot be abused and shared links are protected.

To clarify. Had a look on psitransfer and it looks like you dont can password protect the upload, but like Send you can protect the download with a password.

We would like to password protect access to the upload.

martin-braun commented 1 year ago

@thmmsn That's not true:

Screenshot 2023-06-25 at 12 04 32

It's off by default, but can be turned on in the configs.

You can also password protect the downloads:

Screenshot 2023-06-25 at 12 06 28

The unprotected hotlink is long and random and cannot be guessed, it can only be accessed when knowing the download password. So it serves me well, actually.