altcha-org / altcha

GDPR compliant, self-hosted CAPTCHA alternative with PoW mechanism and advanced anti-spam filter.
https://altcha.org
MIT License
241 stars 5 forks source link

Expires header makes browsers cache challenges #31

Closed ixnas closed 1 month ago

ixnas commented 1 month ago

Hi there!

The ALTCHA challenge provides a mechanism for the widget to automatically request a new challenge when the current one expires. It's using the Expires header for that.

However, (at least) using the public API, this header will make browsers cache the challenge. This causes an issue when the validating server guards against replay attacks. Because now when a user submits any subsequent ALTCHA challenge using the same API key (= same URL), it will use the same challenge that it solved before. The server will then rightfully reject this challenge.

The API should at least use Cache-Control to disable caching for this endpoint. But I feel using the Expires header in this way is a bit misplaced to begin with. These headers are meant for controlling caching behavior, and I think ALTCHA should not use this header for a different mechanic.

Instead of using HTTP headers, I would suggest either standardizing the format for the salt so that the client can extract the expiry from that, or (probably preferably) adding an (optional) JSON property expires to a challenge.

What do you think?

ovx commented 1 month ago

Hi, thanks for reporting. The API is fixed, Cloudflare was adding the cache-control:private header.

I agree that using the Expires header is a misuse. There might be also a need to add other parameters, which should be part of the signature, so I prefer adding it to the standardized salt, which is always signed.

To allow any extra params in the future, the params can be added as URL-encoded params to the salt, for example:

salt = <salt>?expires=1715259780&another_param=1

This way both the widget and the server can read and verify any extra params without the need to update existing libraries.

ixnas commented 1 month ago

Thanks for fixing! It allows me to add and test spam filter verification in my C# implementation. :)

Parameterizing the salt looks good, looking forward to your implementation!