feat: implement brute force protection for public links#460
feat: implement brute force protection for public links#460jvillafanez merged 5 commits intomainfrom
Conversation
kobergj
left a comment
There was a problem hiding this comment.
Some questions/remarks.
| } | ||
|
|
||
| func (m *manager) Authenticate(ctx context.Context, token, secret string) (*user.User, map[string]*authpb.Scope, error) { | ||
| if !m.bfp.Verify(token) && !m.bfp.CleanInfo(token) { |
There was a problem hiding this comment.
Why do we need two methods calls here? Isn't CleanInfo already checking max attempts?
There was a problem hiding this comment.
The Verify method is intended to provide a fast response (only read lock needed) while the CleanInfo might take more time (write lock plus more operations).
The expected scenario is that most of the requests will be successful, so only the Verify method is called, allowing better concurrency with just the read lock.
There was a problem hiding this comment.
Makes sense. But couldn't that all be done by the Verify method? It could check with readlock and return if successful, otherwise writelock.
I don't see a scenario where we would only call one of the methods, or am I missing something?
There was a problem hiding this comment.
It might be possible, but the code would be more complex. There are a couple of things to notice:
- Current code uses the standard pattern of "
lock+defer unlock" to ensure the lock is always released. If we put everything in the same method, this won't be possible because we must release the read lock before obtaining the write lock, and unlocking manually has its drawbacks. - Since we're dealing with locks, these are usually handled within public methods. Dealing with them in private methods might limit the reusability of those methods. It might cause problems with the previous point too because you might be forced to manually release the lock almost always.
I don't see a scenario where we would only call one of the methods, or am I missing something?
You can use just the CleanInfo method (now I see it's a bad name, maybe AccurateVerify fits better) if you don't really care about performance.
You can also use just the Verify method assuming you also have some background thread cleaning the information so the result is "accurate enough". However, this seems tricky and I'd rather not rely on a background thread that can't be easily controlled.
We can provide a convenience function such as the one below, but since the locks will be handled implicitly inside the Verify and CleanInfo methods it might cause issues if we need to make changes in that code later: you'd either assume the code isn't thread-safe because locks aren't explicitly handled in the method, or forget to handle the locks
func (bfp *BruteForceProtection) MasterVerify(token string) bool {
if !bfp.Verify(token) && !bfp.CleanInfo(token) {
return false
}
return true
}
There was a problem hiding this comment.
Updated info in this regard: the CleanInfo method has been removed because we'd need to read from the store twice. The updated code will use a write lock always and conditionally write into the store if there is obsolete data.
| // AddAttempt register a new failed attempt for the provided public share | ||
| // If the time gap or the max attempts are 0, the failed attempt won't be | ||
| // registered | ||
| func (bfp *BruteForceProtection) AddAttempt(shareToken string) { | ||
| if bfp.timeGap <= 0 || bfp.maxAttempts <= 0 { | ||
| return | ||
| } | ||
|
|
||
| bfp.rwmutex.Lock() | ||
| defer bfp.rwmutex.Unlock() | ||
|
|
||
| attempt := &attemptData{ | ||
| Timestamp: time.Now().Unix(), | ||
| } | ||
|
|
||
| bfp.attemptMap[shareToken] = append(bfp.attemptMap[shareToken], attempt) | ||
|
|
||
| // clean data if needed | ||
| bfp.checkProtection(shareToken) | ||
| } |
There was a problem hiding this comment.
Unfortunately this won't work so easy. In production we use multiple instances of this service. We need a global counter of this value so we are sure all intances behave the same at the same moment in time.
There was a problem hiding this comment.
We'll have to move the counter to natsjs (not sure what alternatives we have inside reva). We need to ensure it's thread-safe too.
There was a problem hiding this comment.
Yes. Or we store it as an additional property on the public link itself. Not sure what is more feasible.
There was a problem hiding this comment.
I'll change the plans a bit
Discarded solutions:
- Reva stores don't provide thread-safety. This means that there could be problems when multiple replicas try to store failed attempts over the same share.
- The public link doesn't have a good place to store additional information.
- Changing the public link definition in the cs3org API doesn't seem a good idea.
- Adding the information at storage level implies changing all the implementations to prepare them to store random information.
Proposed solution:
We'll keep the current code. However, when a failed attempt happens, the service will emit a "public share password failed" event. The event will be received by all the replicas that will adjust the related information on their side.
The additional benefit is that other services like audit can also receive the event and act accordingly. For example, the audit service might want to log something about the failed attempt.
There was a problem hiding this comment.
@jvillafanez Do we need to implement some event based logic if we already have the nats-kv in a reva/pkg/store ?
// Create initializes a new store func Create(opts ...microstore.Option) microstore.Store
There was a problem hiding this comment.
The store doesn't provide any thread-safety mechanism, so there is a high risk of race conditions.
If there are 2 or more failures happening at the same time and going to different replicas, all the replicas will try to write the data at the same time. There is a high risk of one replica overwriting the data of any other and messing up with the failure count.
It's the classic "get and set" problem that doesn't have solution without thread-safety mechanisms, either (distributed) locks or atomic operations.
There was a problem hiding this comment.
Final implementation will use the store. In order to mitigate (not completely prevent) the risk of overwriting data, we'll check that the data we've just written can be read from the store. If the data isn't there, we'll retry the operation several times (up to 10 at the moment) before failing.
Right now, the algorithm is pretty strict with the check (basically the data must match exactly), which might cause problems: replica A might fail to write despite the retries because replicas B and C keep overwriting the data.
It's probably fine to check if the failed attempt we want to add is present even if the full data isn't exactly the same. This should lead to less retries and faster responses in congested scenarios.
There was a problem hiding this comment.
I think this implementation is quite good since we don't need high accuracy.
| case publicShareResponse.Status.Code == rpcv1beta1.Code_CODE_NOT_FOUND: | ||
| return nil, nil, errtypes.NotFound(publicShareResponse.Status.Message) | ||
| case publicShareResponse.Status.Code == rpcv1beta1.Code_CODE_PERMISSION_DENIED: | ||
| if secret != "" && secret != "|" && !CheckSkipAttempt(ctx, token) { // FIXME: needs better detection |
There was a problem hiding this comment.
I do understand why secret != "". It makes no sense to increase wrong password counter if none was given. But I don't understand
- Why
secret != "|"? Why does anyone set the secret to"|"? Why do we need to care about this here? - What is the purpose of the
CheckSkipAttemptfunctions? Why do we need them at all?
There was a problem hiding this comment.
Why secret != "|"? Why does anyone set the secret to "|"? Why do we need to care about this here?
We get | as secret for empty password attempts, which happens when loading the share link in the web. The actual secret we get somewhere on top is publicshare|pass or signed|pass|expiration, so something is likely wrong and it isn't working properly in that scenario.
What is the purpose of the CheckSkipAttempt functions? Why do we need them at all?
That's for the duplicated authentication that happens in the server (owncloud/ocis#11862). There is one authentication happening in the proxy middleware to get a reva access token, plus the one to access the share.
Removing the authentication from the middleware didn't work because we need it if a user access to an office document via the public share.
This solution allows us to tell this code not to count the authentication coming from the middleware as a failed attempt.
There was a problem hiding this comment.
We get | as secret for empty password attempts, which happens when loading the share link in the web. The actual secret we get somewhere on top is publicshare|pass or signed|pass|expiration, so something is likely wrong and it isn't working properly in that scenario.
So this means there is some error before where the publicshare|pass (or signed|pass|expiration) isn't converted properly to pass. The best option would be to fix it there, but I would be fine with a FIXME comment describing the problem if the actual fix is too cumbersome.
There is one authentication happening in the proxy middleware to get a reva access token, plus the one to access the share.
Why don't we just return immediately when the first one fails? This way second authentication would never happen and we don't have a problem with the counter.
There was a problem hiding this comment.
Why don't we just return immediately when the first one fails? This way second authentication would never happen and we don't have a problem with the counter.
I don't think it's that easy... I've already tried removing the related code in the middleware, but it failed because we need the returned reva access token for the office integration (collaboration service). Access to office documents with collabora / onlyoffice through a public link wasn't possible with that change.
The only alternative I see is to move the brute force protection code to the middleware, but any internal request that bypasses the proxy would also bypass the brute force protection, and I don't think we want to do that.
The context data is propagated through the GRPC reva services using the configured metadata interceptors
82c8fa8 to
115854f
Compare
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [docker.io/owncloud/ocis](https://redirect.github.com/owncloud/ocis) | major | `7.3.2` → `8.0.0` | --- > [!WARNING] > Some dependencies could not be looked up. Check the Dependency Dashboard for more information. --- ### Release Notes <details> <summary>owncloud/ocis (docker.io/owncloud/ocis)</summary> ### [`v8.0.0`](https://redirect.github.com/owncloud/ocis/blob/HEAD/CHANGELOG.md#Changelog-for-800-2026-02-13) [Compare Source](https://redirect.github.com/owncloud/ocis/compare/v7.3.2...v8.0.0) The following sections list the changes for 8.0.0. [8.0.0]: https://redirect.github.com/owncloud/ocis/compare/v7.3.1...v8.0.0 #### Summary - Bugfix - Fix user light creation: [#​11765](https://redirect.github.com/owncloud/ocis/pull/11765) - Bugfix - OCM Specification Compliance: [#​11773](https://redirect.github.com/owncloud/ocis/pull/11773) - Bugfix - Remove leading dot before checking disabled extension: [#​11814](https://redirect.github.com/owncloud/ocis/pull/11814) - Bugfix - Support pointer types in config environment variable decoding: [#​11815](https://redirect.github.com/owncloud/ocis/pull/11815) - Bugfix - Replace obsolete docker image in the deployment example: [#​11828](https://redirect.github.com/owncloud/ocis/pull/11828) - Bugfix - Fix error code when a user can't disable a space: [#​11845](https://redirect.github.com/owncloud/ocis/pull/11845) - Bugfix - Fix Sharingroles: [#​11898](https://redirect.github.com/owncloud/ocis/pull/11898) - Bugfix - Fix the error handling for empty name on space update: [#​11933](https://redirect.github.com/owncloud/ocis/pull/11933) - Bugfix - Fix group creation in ocis-multi example: [#​12019](https://redirect.github.com/owncloud/ocis/pull/12019) - Change - Remove deprecated OCIS\_SHOW\_USER\_EMAIL\_IN\_RESULTS: [#​11942](https://redirect.github.com/owncloud/ocis/pull/11942) - Enhancement - Bump Reva: [#​460](https://redirect.github.com/owncloud/reva/pull/460) - Enhancement - Set Referrer-Policy to no-referrer: [#​11722](https://redirect.github.com/owncloud/ocis/pull/11722) - Enhancement - Bump Reva: [#​11748](https://redirect.github.com/owncloud/ocis/pull/11748) - Enhancement - Support disabling editors by extensions: [#​11750](https://redirect.github.com/owncloud/ocis/pull/11750) - Enhancement - Add CLI to move stuck uploads: [#​11762](https://redirect.github.com/owncloud/ocis/pull/11762) - Enhancement - Use externalID in Provisioning API: [#​11799](https://redirect.github.com/owncloud/ocis/pull/11799) - Enhancement - Add CLI to clean orphned grants: [#​11804](https://redirect.github.com/owncloud/ocis/pull/11804) - Enhancement - Bump Reva: [#​11808](https://redirect.github.com/owncloud/ocis/pull/11808) - Enhancement - Bump Web to v12.2.0: [#​11834](https://redirect.github.com/owncloud/ocis/pull/11834) - Enhancement - Introduce claims for multi-instance-ocis: [#​11848](https://redirect.github.com/owncloud/ocis/pull/11848) - Enhancement - Update the ocis\_full deployment example images: [#​11860](https://redirect.github.com/owncloud/ocis/pull/11860) - Enhancement - Implement brute force protection for public links: [#​11864](https://redirect.github.com/owncloud/ocis/pull/11864) - Enhancement - Update the ocis\_full deployment example traefik image: [#​11867](https://redirect.github.com/owncloud/ocis/pull/11867) - Enhancement - Added a graph endpoint alias: [#​11871](https://redirect.github.com/owncloud/ocis/pull/11871) - Enhancement - Force Strict-Transport-Security: [#​11880](https://redirect.github.com/owncloud/ocis/pull/11880) - Enhancement - Relocate Transifex resources: [#​11889](https://redirect.github.com/owncloud/ocis/pull/11889) - Enhancement - Update the ocis\_full deployment example images: [#​11890](https://redirect.github.com/owncloud/ocis/pull/11890) - Enhancement - Allow sharing between instances: [#​11893](https://redirect.github.com/owncloud/ocis/pull/11893) - Enhancement - Add photo EXIF metadata to search index and WebDAV results: [#​11912](https://redirect.github.com/owncloud/ocis/pull/11912) - Enhancement - Update the traefik image for some deployment examples: [#​11915](https://redirect.github.com/owncloud/ocis/pull/11915) - Enhancement - Add users instances: [#​11925](https://redirect.github.com/owncloud/ocis/pull/11925) - Enhancement - Introduce external shares permission: [#​11931](https://redirect.github.com/owncloud/ocis/pull/11931) - Enhancement - Update to go 1.25: [#​12011](https://redirect.github.com/owncloud/ocis/pull/12011) - Enhancement - Bump Web to 12.3.1: [#​12016](https://redirect.github.com/owncloud/ocis/pull/12016) - Enhancement - Bump Web to 12.3.0: [#​13519](https://redirect.github.com/owncloud/web/pull/13519) #### Details - Bugfix - Fix user light creation: [#​11765](https://redirect.github.com/owncloud/ocis/pull/11765) When trying to switch a user to user light before they logged in for the first time, an error would occur. The server now correctly handles this case and allows switching to user light even before the first login. [#​11765](https://redirect.github.com/owncloud/ocis/pull/11765) - Bugfix - OCM Specification Compliance: [#​11773](https://redirect.github.com/owncloud/ocis/pull/11773) OCM Specification Compliance [#​11773](https://redirect.github.com/owncloud/ocis/pull/11773) - Bugfix - Remove leading dot before checking disabled extension: [#​11814](https://redirect.github.com/owncloud/ocis/pull/11814) We have fixed a bug where the leading dot was not removed before checking if an extension is disabled. The original behavior would have caused the `COLLABORATION_WOPI_DISABLED_EXTENSIONS` config to be ignored. [#​11814](https://redirect.github.com/owncloud/ocis/pull/11814) - Bugfix - Support pointer types in config environment variable decoding: [#​11815](https://redirect.github.com/owncloud/ocis/pull/11815) Added support for decoding pointer types (\*bool, \*int, \*string, etc.) in the envdecode package, allowing configuration fields to distinguish between unset (nil) and explicitly set values. Changed `WEB_OPTION_EMBED_ENABLED` from string to \*bool type to enable explicit false values. [#​11815](https://redirect.github.com/owncloud/ocis/pull/11815) - Bugfix - Replace obsolete docker image in the deployment example: [#​11828](https://redirect.github.com/owncloud/ocis/pull/11828) In the ocis\_ldap deployment example, we were using the bitnami/openldap docker image. This image isn't available any longer, so the example couldn't be deployed as intended. We've replaced the docker image with the osixia/openldap image and we've adjusted some of the configuration of the openldap image. [#​11828](https://redirect.github.com/owncloud/ocis/pull/11828) - Bugfix - Fix error code when a user can't disable a space: [#​11845](https://redirect.github.com/owncloud/ocis/pull/11845) Previously, if the user couldn't disable a space due to wrong permissions, the request returned a 404 error code, as if the space wasn't found even though the space was visible. Now it will return the expected 403 error code. [#​11845](https://redirect.github.com/owncloud/ocis/pull/11845) - Bugfix - Fix Sharingroles: [#​11898](https://redirect.github.com/owncloud/ocis/pull/11898) Sharing roles were inconsistent, now they are fixed. [#​11898](https://redirect.github.com/owncloud/ocis/pull/11898) - Bugfix - Fix the error handling for empty name on space update: [#​11933](https://redirect.github.com/owncloud/ocis/pull/11933) Fix the error handling for empty name on space update. [#​11887](https://redirect.github.com/owncloud/ocis/issues/11887) [#​11933](https://redirect.github.com/owncloud/ocis/pull/11933) - Bugfix - Fix group creation in ocis-multi example: [#​12019](https://redirect.github.com/owncloud/ocis/pull/12019) Group creation was not working in ocis.ocm instance [#​12019](https://redirect.github.com/owncloud/ocis/pull/12019) - Change - Remove deprecated OCIS\_SHOW\_USER\_EMAIL\_IN\_RESULTS: [#​11942](https://redirect.github.com/owncloud/ocis/pull/11942) Deprecated OCIS\_SHOW\_USER\_EMAIL\_IN\_RESULTS environment variable was removed from frontend service config. Use OCIS\_USER\_SEARCH\_DISPLAYED\_ATTRIBUTES instead to control which user attributes are displayed in search results. [#​11942](https://redirect.github.com/owncloud/ocis/pull/11942) - Enhancement - Bump Reva: [#​460](https://redirect.github.com/owncloud/reva/pull/460) This updates the ownCloud Reva dependency to include brute force protection for public links. The feature implements rate-limiting that blocks access to password-protected public shares after exceeding a configurable maximum number of failed authentication attempts within a time window. [owncloud/reva#460](https://redirect.github.com/owncloud/reva/pull/460) - Enhancement - Set Referrer-Policy to no-referrer: [#​11722](https://redirect.github.com/owncloud/ocis/pull/11722) Change the Referrer-Policy from 'strict-origin-when-cross-origin' to 'no-referrer' to enhance user privacy and security. Previously, the origin was sent on cross-origin requests. This change completely removes the Referrer header from all outgoing requests, preventing any potential leakage of browsing information to third parties. This is a more robust approach to protecting user privacy. [#​11722](https://redirect.github.com/owncloud/ocis/pull/11722) - Enhancement - Bump Reva: [#​11748](https://redirect.github.com/owncloud/ocis/pull/11748) This updates the ownCloud Reva dependency to commit `82c22e954c1cdabb62a14fbe5c1a4ec3e1dabd45`. Changelog: [owncloud/reva@`cb98fe5...82c22e9`](https://redirect.github.com/owncloud/reva/compare/cb98fe521deb55ae339d6ddc4a4b60d6d4da9e14...82c22e954c1cdabb62a14fbe5c1a4ec3e1dabd45) [#​11748](https://redirect.github.com/owncloud/ocis/pull/11748) - Enhancement - Support disabling editors by extensions: [#​11750](https://redirect.github.com/owncloud/ocis/pull/11750) We have extended the configuration of collaboration service to support disabling editors for specific file extensions. [#​11750](https://redirect.github.com/owncloud/ocis/pull/11750) - Enhancement - Add CLI to move stuck uploads: [#​11762](https://redirect.github.com/owncloud/ocis/pull/11762) In some cases of saturated disk usage ocis metadata may get stuck. This command relieves this case. [#​11762](https://redirect.github.com/owncloud/ocis/pull/11762) - Enhancement - Use externalID in Provisioning API: [#​11799](https://redirect.github.com/owncloud/ocis/pull/11799) This PR adds the externalID as optional parameter to the Provisioning API that can be used as the primary identifier. It also contains a switch to enable this setting. [#​11799](https://redirect.github.com/owncloud/ocis/pull/11799) - Enhancement - Add CLI to clean orphned grants: [#​11804](https://redirect.github.com/owncloud/ocis/pull/11804) Add CLI `ocis shares clean-orphaned-grants` to find and optionally remove storage grants without corresponding share-manager entries. [#​11804](https://redirect.github.com/owncloud/ocis/pull/11804) - Enhancement - Bump Reva: [#​11808](https://redirect.github.com/owncloud/ocis/pull/11808) This updates the ownCloud Reva dependency to commit `a122a9538794530267743edfd5dc67b48aa90325`. Changelog: [owncloud/reva@`751223b...a122a95`](https://redirect.github.com/owncloud/reva/compare/751223b32d4852c73a43388f6f55308c2065afeb...a122a9538794530267743edfd5dc67b48aa90325) [#​11808](https://redirect.github.com/owncloud/ocis/pull/11808) - Enhancement - Bump Web to v12.2.0: [#​11834](https://redirect.github.com/owncloud/ocis/pull/11834) - Bugfix [owncloud/web#13177](https://redirect.github.com/owncloud/web/pull/13177): Fix copying public link and password on Safari - Bugfix [owncloud/web#13198](https://redirect.github.com/owncloud/web/pull/13198): Fix incorrect translations - Bugfix [owncloud/web#13203](https://redirect.github.com/owncloud/web/pull/13203): Remove duplicate resource links - Bugfix [owncloud/web#13213](https://redirect.github.com/owncloud/web/pull/13213): Do not disable sharing of resources when managing spaces via claims - Bugfix [owncloud/web#13223](https://redirect.github.com/owncloud/web/pull/13223): Fix spinner loading continuously when resource is deleted - Bugfix [owncloud/web#13233](https://redirect.github.com/owncloud/web/pull/13233): Include Ubuntu font - Bugfix [owncloud/web#13253](https://redirect.github.com/owncloud/web/pull/13253): External share ID fallback - Bugfix [owncloud/web#13274](https://redirect.github.com/owncloud/web/pull/13274): Handle file loading error - Bugfix [owncloud/web#13329](https://redirect.github.com/owncloud/web/pull/13329): Use sticky header composable in deleted files - Enhancement [owncloud/web#13168](https://redirect.github.com/owncloud/web/pull/13168): Hide trashed spaces - Enhancement [owncloud/web#13169](https://redirect.github.com/owncloud/web/pull/13169): Drop beta badge from GeoGebra pinboards - Enhancement [owncloud/web#13172](https://redirect.github.com/owncloud/web/pull/13172): Add Excalidraw file icon - Enhancement [owncloud/web#13197](https://redirect.github.com/owncloud/web/pull/13197): Add Visio file icons - Enhancement [owncloud/web#13224](https://redirect.github.com/owncloud/web/pull/13224): Add table caption - Enhancement [owncloud/web#13235](https://redirect.github.com/owncloud/web/pull/13235): Use API groups search in admin settings - Enhancement [owncloud/web#13296](https://redirect.github.com/owncloud/web/pull/13296): Embed mode share links with password [#​11834](https://redirect.github.com/owncloud/ocis/pull/11834) <https://github.com/owncloud/web/releases/tag/v12.2.0> - Enhancement - Introduce claims for multi-instance-ocis: [#​11848](https://redirect.github.com/owncloud/ocis/pull/11848) Reads claims from the oidc token to add users to ocis with specific roles. [#​11848](https://redirect.github.com/owncloud/ocis/pull/11848) - Enhancement - Update the ocis\_full deployment example images: [#​11860](https://redirect.github.com/owncloud/ocis/pull/11860) - Traefik 3.6.2 - Collabora 27.4.7.3 - OnlyOffice 9.2.0 - Mailpit 1.28.0 [#​11860](https://redirect.github.com/owncloud/ocis/pull/11860) - Enhancement - Implement brute force protection for public links: [#​11864](https://redirect.github.com/owncloud/ocis/pull/11864) 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). The failure rate is configurable, so it can be 10 failures each 2 hours or 3 failures per minute. [#​11864](https://redirect.github.com/owncloud/ocis/pull/11864) [owncloud/reva#460](https://redirect.github.com/owncloud/reva/pull/460) - Enhancement - Update the ocis\_full deployment example traefik image: [#​11867](https://redirect.github.com/owncloud/ocis/pull/11867) - Traefik: 3.6.4 - Traefik fix for Collabora [#​11867](https://redirect.github.com/owncloud/ocis/pull/11867) - Enhancement - Added a graph endpoint alias: [#​11871](https://redirect.github.com/owncloud/ocis/pull/11871) We added a graph endpoint alias that uses the unified roles instead of cs3 roles [#​11871](https://redirect.github.com/owncloud/ocis/pull/11871) - Enhancement - Force Strict-Transport-Security: [#​11880](https://redirect.github.com/owncloud/ocis/pull/11880) Added `PROXY_FORCE_STRICT_TRANSPORT_SECURITY` environment variable to force emission of `Strict-Transport-Security` header on all responses, including plain HTTP requests when TLS is terminated upstream. Useful when oCIS is deployed behind a proxy. [#​11880](https://redirect.github.com/owncloud/ocis/pull/11880) - Enhancement - Relocate Transifex resources: [#​11889](https://redirect.github.com/owncloud/ocis/pull/11889) The resources for services with translations are relocated in Transifex from owncloud to owncloud-web. Now all ocis related resources are in one project. [#​11889](https://redirect.github.com/owncloud/ocis/pull/11889) - Enhancement - Update the ocis\_full deployment example images: [#​11890](https://redirect.github.com/owncloud/ocis/pull/11890) - Traefic: v3.6.6 - Collabora: 25.04.8.1.1 - Onlyoffice: 9.2.1.1 [#​11890](https://redirect.github.com/owncloud/ocis/pull/11890) - Enhancement - Allow sharing between instances: [#​11893](https://redirect.github.com/owncloud/ocis/pull/11893) In Multi-Instance ocis it is now possible to share between instances. [#​11893](https://redirect.github.com/owncloud/ocis/pull/11893) - Enhancement - Add photo EXIF metadata to search index and WebDAV results: [#​11912](https://redirect.github.com/owncloud/ocis/pull/11912) We've added support for photo metadata fields in the Bleve search index and WebDAV REPORT responses. This enables photo gallery applications to efficiently query photos by their EXIF metadata and display camera information. The following photo metadata fields are now indexed and searchable: - `photo.takenDateTime` - When the photo was taken (supports date range queries) - `photo.cameraMake` - Camera manufacturer (e.g., Canon, Nikon, Samsung) - `photo.cameraModel` - Camera model name - `photo.fNumber` - Aperture f-stop value - `photo.focalLength` - Focal length in millimeters - `photo.iso` - ISO sensitivity - `photo.orientation` - Image orientation - `photo.exposureNumerator` - Exposure time numerator (for shutter speed calculation) - `photo.exposureDenominator` - Exposure time denominator (for shutter speed calculation) GPS location data is also included when available: - `photo.location.latitude` - GPS latitude - `photo.location.longitude` - GPS longitude - `photo.location.altitude` - GPS altitude These fields are returned in WebDAV search results using the `oc:photo-*` property namespace, allowing web extensions to build photo timeline views, filter by camera, or show photos on a map. [#​11912](https://redirect.github.com/owncloud/ocis/pull/11912) - Enhancement - Update the traefik image for some deployment examples: [#​11915](https://redirect.github.com/owncloud/ocis/pull/11915) - Traefik: 3.6.6 --> 3.6.7 [#​11915](https://redirect.github.com/owncloud/ocis/pull/11915) - Enhancement - Add users instances: [#​11925](https://redirect.github.com/owncloud/ocis/pull/11925) The user endpoint now returns the instances that the user is either a member or a guest of and the cross instance reference. [#​11925](https://redirect.github.com/owncloud/ocis/pull/11925) - Enhancement - Introduce external shares permission: [#​11931](https://redirect.github.com/owncloud/ocis/pull/11931) Introduces a permission allowing to share between instances in multi-instance ocis. This permission is by default added to the admin and space-admin role. [#​11931](https://redirect.github.com/owncloud/ocis/pull/11931) - Enhancement - Update to go 1.25: [#​12011](https://redirect.github.com/owncloud/ocis/pull/12011) We have updated go to version 1.25 and alpine to version 3.23.3 [#​12011](https://redirect.github.com/owncloud/ocis/pull/12011) [#​12004](https://redirect.github.com/owncloud/ocis/pull/12004) - Enhancement - Bump Web to 12.3.1: [#​12016](https://redirect.github.com/owncloud/ocis/pull/12016) Bugfix [owncloud/web#13553](https://redirect.github.com/owncloud/web/pull/13553): Search Text Overalps With Search Icon In The Search Bar [#​12016](https://redirect.github.com/owncloud/ocis/pull/12016) <https://github.com/owncloud/web/releases/tag/v12.3.1> - Enhancement - Bump Web to 12.3.0: [#​13519](https://redirect.github.com/owncloud/web/pull/13519) Bugfix [owncloud/web#13406](https://redirect.github.com/owncloud/web/pull/13406): Prevent overlapping search content Bugfix [owncloud/web#13415](https://redirect.github.com/owncloud/web/pull/13415) Filter only personal trashed spaces Enhancement [owncloud/web#5847](https://redirect.github.com/owncloud/web/pull/5847) Dynamic theme-color meta tag based on loaded theme Enhancement [owncloud/web#13412](https://redirect.github.com/owncloud/web/pull/13412) Use beta endpoint for single drive operations Enhancement [owncloud/web#13426](https://redirect.github.com/owncloud/web/pull/13426) Add crash page Enhancement [owncloud/web#13426](https://redirect.github.com/owncloud/web/pull/13426)Catch spaces loading error Enhancement [owncloud/web#13485](https://redirect.github.com/owncloud/web/pull/13485)Drop custom share filters Enhancement [owncloud/web#13499](https://redirect.github.com/owncloud/web/pull/13499)Add cross-instance reference Enhancement [owncloud/web#13500](https://redirect.github.com/owncloud/web/pull/13500)Add instance switcher [owncloud/web#13519](https://redirect.github.com/owncloud/web/pull/13519) <https://github.com/owncloud/web/releases/tag/v12.3.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://redirect.github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNS4zIiwidXBkYXRlZEluVmVyIjoiNDMuMTYuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsicmVub3ZhdGUvY29udGFpbmVyIiwidHlwZS9tYWpvciJdfQ==-->
Note: https://github.com/cs3org/go-cs3apis/blob/main/cs3/rpc/v1beta1/code.pb.go#L121-L125 has a recommended RPC matching for the "Too Many Requests" error, so we're following along.
Implement brute force protection for public shares. The implementation follows a rate-limit approach. This means that you can access the share while the access failure rate is below certain threshold. If such threshold is surpassed, the public share won't be accessible until the failure rate goes below the threshold.
By default, the failure rate is 5 failures per hour (configurable). This means that you're allowed to fail the password for the share up to 5 times per hour before the share is blocked.
The duration of the blockage will be undefined, but between 0 and the configuration duration:
Note that this is an in-memory implementation, so the data won't be shared with other service replicas. This means that the protection will be effective per-server replica, which might not behave as expected: if there are 3 replicas, requests might block one replica but not others, and you might be allowed additional failures because requests will hit different replicas.Current implementation will use a reva store to make the related data accessible to all the service's replicas.
The recommended environment for the replicas is below (adjust the values if needed):
TODO:
It needs a way to disable the feature. Right now, we need to keep timestamps in memory to keep track of the failed attempts. The greater the maximum number of attempts is, the more memory we might need to use; this also applies to the duration we need to store the timestamps.Setting the configuration values with zeros will effectively disable the feature
areEqualLists) is too strict and could lead to excessive retries and / or failures.