Skip to content

feat: implement brute force protection for public shares#11864

Merged
kobergj merged 10 commits intomasterfrom
brute_force_protection_link
Jan 23, 2026
Merged

feat: implement brute force protection for public shares#11864
kobergj merged 10 commits intomasterfrom
brute_force_protection_link

Conversation

@jvillafanez
Copy link
Copy Markdown
Member

Description

Requires owncloud/reva#460

Configuration for the brute force protection from oCIS

Note that the authentication done in the middleware will be fully delegated to reva (related to #11862)

Related Issue

  • Fixes <issue_link>

Motivation and Context

How Has This Been Tested?

Manually tested. After several failed attempts the access to the public share is blocked.

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation ticket raised:

Notes:

@jvillafanez jvillafanez self-assigned this Dec 5, 2025
@update-docs
Copy link
Copy Markdown

update-docs bot commented Dec 5, 2025

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Dec 9, 2025

Will this go into Curie?
Mind to add some text to the readme describing the behavior?
(We also need a changelog)

@jvillafanez
Copy link
Copy Markdown
Member Author

@kobergj there are some unit tests failing, likely caused by the change in the middleware here, so I'm not sure if we should remove those tests of explore a different solution.

Comment on lines +3 to +6
Public links will be protected by default, allowing up to 5 wrong password
attempts per hour. If such rate is exceeded, the link will be blocked for
all the users until the failure rate goes below the configured threshold
(5 failures per hour by default, as said).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have questions on the behavior:

  1. One mad user can block the whole PL for the time defined.
  2. If there is another user typing in the wrong pwd, the counter starts from the beginning.
  3. No user can see when the blocking time ends.
  4. No user can login even with a correct password if the treshold has been exeeded before.
  5. Consequently, if a user would be able to login with the correct pwd (which is a violation of the description above), login would be reenabled for all.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Technically yes. However, that could also be considered as an attack, which is what we want to prevent.
    Public links are intended for external anonymous access, and the security team decided that trying to block access by IP could be bypassed, so the access will be blocked for everyone, including regular logged-in users.
  2. There is no counter. We're tracking the timestamp of each failed attempt (no longer useful data will be removed eventually) and ensuring that, given a duration, there are less than the maximum allowed failed attempts in it.
  3. Correct. I'm not entirely sure how useful showing that information will be related to the effort to implement it. If we need to show an accurate information, we'll need to propagate the information from very deep; alternatively, we could show the worst case ("retry after one hour", by default). It could also give information to potential attackers. Definitely something to check with the security team.
  4. Right. However, if a user could login with a correct password during the block, an attacker could keep trying passwords ignoring the block until he succeeds, which would defeat the purpose of the feature.
  5. Point 4 explains it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Expected bahaviour. This is the point of the whole story
  2. The counter should be global and not reset when another user enters a wrong password
  3. Expected behaviour. We do not want attackers to automate waiting time between brute force attacks.
  4. Expected behaviour. As stated above it would render the whole feature useless if we allow access to blocked resources.
  5. NO user should be able to access the link while it is blocked due to an attack.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the insight 😄
Addon question:

  1. If one has entered a valid pwd for the PL and accesses the resource and another user triggers the limit and blocks access, will the first user be kicked out?

Copy link
Copy Markdown
Collaborator

@kobergj kobergj Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends. I would expect ongoing Office session to not break. But I would expect the user cannot upload/download the file from this point. @jvillafanez is this the actual behaviour?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I would expect the user cannot upload/download the file from this point.

Really? First you successfully login, then you cant do anything without being notified?

As logged in user, I would expect at least a notification on the screen. Then it would be ok.
Would this also affect any running up/download? Means, they will get interrupted and the session closed?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First you successfully login

No login involved - this is about public links.

As logged in user, I would expect at least a notification on the screen.

Ideally yes - but from a security POV not needed.

Would this also affect any running up/download? Means, they will get interrupted and the session closed?

I would expect not. Once the download has started it uses a different sort of access token that is not bound to the user. So download should succeed. Not sure about Upload. Needs to be tested.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to double-check, but I think the office session will work normally. Pretty sure that almost all the operations will target the office server, and when the office server needs to contact oCIS it will use the provided reva access token, which should still be valid (unless it's expired). There shouldn't be any public share authentication needed while in the office app.

I haven't tested all cases, but taking into account that there are no related changes in web, the behavior seems to be fine: you can edit the file (assuming enough permissions), upload the file correctly to the server with the changes, BUT you get a "resource not found" error when you exit the editor.

@kobergj
Copy link
Copy Markdown
Collaborator

kobergj commented Dec 10, 2025

@jvillafanez why is this unit test failing? Could we increase the threshold of failed tries to make this tests pass?

@jvillafanez
Copy link
Copy Markdown
Member Author

https://github.com/owncloud/ocis/pull/11864/files#diff-6d13e529ff282391653d164b7fe8654c0580bf59dd90e7b81e26a2c84ad12a92L94-L122 is likely the cause. It was needed because there was a double authentication going on that was messing with the failure count (#11862)

Could we increase the threshold of failed tries to make this tests pass?

The feature is mainly in reva, and this PR doesn't update it, so there shouldn't be any brute force protection going on. This PR is mostly configuration for the reva service.

@jvillafanez
Copy link
Copy Markdown
Member Author

I think I'll need to look at a different solution for the double authentication. There is a 401 error when trying to open a docx file from the public link with onlyoffice.

ocis-1          | {"level":"warn","service":"frontend","pkg":"rhttp","traceid":"15700baf3978712796c25f3a4cb33b8b","time":"2025-12-10T10:23:15Z","line":"/home/juan/src/ocis/ocis/vendor/github.com/owncloud/reva/v2/internal/http/interceptors/auth/auth.go:249","message":"core access token not set for URL /app/open"}
ocis-1          | {"level":"warn","service":"frontend","pkg":"rhttp","traceid":"15700baf3978712796c25f3a4cb33b8b","host":"127.0.0.1","method":"POST","uri":"/app/open?file_id=e704b38b-6725-4810-9084-dc95d02e62fc%24a73c6ea6-6e7c-103f-8110-dd19ecb0bb36%212f89376b-025c-46a3-833c-a7641d5b7c97&lang=en&mobile=0&app_name=ByCS-Office&view_mode=view","url":"/app/open?file_id=e704b38b-6725-4810-9084-dc95d02e62fc%24a73c6ea6-6e7c-103f-8110-dd19ecb0bb36%212f89376b-025c-46a3-833c-a7641d5b7c97&lang=en&mobile=0&app_name=ByCS-Office&view_mode=view","proto":"HTTP/1.1","status":401,"size":0,"start":"10/Dec/2025:10:23:15 +0000","end":"10/Dec/2025:10:23:15 +0000","time_ns":792645,"time":"2025-12-10T10:23:15Z","line":"/home/juan/src/ocis/ocis/vendor/github.com/owncloud/reva/v2/internal/http/interceptors/log/log.go:112","message":"http"}
ocis-1          | {"level":"info","service":"proxy","proto":"HTTP/1.1","request-id":"b6af202c-ac26-4c48-ad56-2dfd0bd9b87f","traceid":"dbff61fb90739a8cdd65f1baf01ed212","remote-addr":"10.0.2.28","method":"POST","status":401,"path":"/app/open","duration":14.99147,"bytes":0,"time":"2025-12-10T10:23:15Z","line":"/home/juan/src/ocis/ocis/services/proxy/pkg/middleware/accesslog.go:34","message":"access-log"}

@sonarqubecloud
Copy link
Copy Markdown

@jvillafanez
Copy link
Copy Markdown
Member Author

jvillafanez commented Dec 16, 2025

The build is currently failing because it requires owncloud/reva#460 . Reva library is not updated with those changes at the moment.
I'm not sure if it's better to wait until the reva PR is merged, update all the libraries and rebase the PR.

Fix for the double authentication (#11864 (comment)) is ready and it will work when both reva and ocis pieces work together.

@jvillafanez jvillafanez force-pushed the brute_force_protection_link branch from 5fee98c to 3477f8e Compare January 20, 2026 14:01
@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Jan 23, 2026

@jvillafanez will that PR go into curie?
If so, can you pls rebase and run from the ocis root make docs-local. This will generate a file named env_vars.yaml. No worry that it will change on each run, but if you add it here, I do not need to extra work updating it in a seperate PR after merging this PR. This file is required for the added/removed/deprecated envvars process.
If it is not going into curie, all good, the steps above are not required.

@jvillafanez jvillafanez force-pushed the brute_force_protection_link branch 2 times, most recently from aa912ad to e4457cb Compare January 23, 2026 09:50
@jvillafanez jvillafanez force-pushed the brute_force_protection_link branch from e4457cb to c9722c3 Compare January 23, 2026 11:07
@jvillafanez jvillafanez marked this pull request as ready for review January 23, 2026 12:03
@jvillafanez
Copy link
Copy Markdown
Member Author

This is ready to review.

The sonarcloud error seems to be caused due to a literal being used a part of the default configuration, so not a big deal. We can ignore it.

@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Jan 23, 2026

I changed sonarcloud to a false positive, so it is green now.
Assinging MaxAttempts: 5, is really not an error (Magic number: 5, in detected)

@mmattel mmattel requested a review from 2403905 January 23, 2026 12:30
@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Jan 23, 2026

I have added the relevant doc changes directly into this PR.
This saves us a bunch of post PRs and guarantees that all is included in Curie properly

@jvillafanez jvillafanez changed the title [WIP] feat: implement brute force protection for public shares feat: implement brute force protection for public shares Jan 23, 2026
@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Jan 23, 2026

@jvillafanez Removed the textblocks as requested. Glad that we had the time to update it before merging 😃 Hard to find afterwards if the code got fixed but the description is behind 😅

@sonarqubecloud
Copy link
Copy Markdown

@mmattel mmattel requested a review from mklos-kw January 23, 2026 14:18
@kobergj kobergj merged commit ea9c3f8 into master Jan 23, 2026
4 checks passed
@kobergj kobergj deleted the brute_force_protection_link branch January 23, 2026 14:40
ownclouders pushed a commit that referenced this pull request Jan 23, 2026
feat: implement brute force protection for public shares
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants