-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New PSR for standardizing CAPTCHA (CaptchaInterface) #1330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
b8e5293
e04dd05
9d91b87
9bfbb82
506a0aa
8ef133d
4c89592
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
CaptchaInterface for various Captcha services | ||
============================================= | ||
|
||
This document describes common interfaces to query data. These data can be from different sources, from in-memory data to databases, as well as filesystem files. | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be | ||
interpreted as described in [RFC 2119][]. | ||
|
||
The final implementations MAY decorate the objects with more | ||
functionality than the one proposed but they MUST implement the indicated | ||
interfaces/functionality first. | ||
|
||
[RFC 2119]: http://tools.ietf.org/html/rfc2119 | ||
|
||
## 1. Specification | ||
|
||
### 1.1 Definitions | ||
|
||
* **CAPTCHA** - A Completely Automated Public Turing test to tell Computers and Humans Apart. A challenge-response test designed to distinguish human users from automated bots. | ||
* **Provider** - A service that implements CAPTCHA functionality by: | ||
* Generating challenges to distinguish humans from automated systems | ||
* Validating user responses to these challenges | ||
* Assessing interaction risk levels | ||
* **Client Token** - A string value generated by the **Provider**'s client-side implementation, representing a single challenge attempt. | ||
* MAY have **Provider**-specific format and expiration | ||
* **Verification** - The process of validating a **Client Token** against the **Provider**'s service. MUST be performed server-side. MAY include client IP validation if required by **Provider**. MAY involve additional risk analysis (e.g., behavioral **SCORING**) | ||
* **Successful Verification** - A determination that: | ||
* The **Client Token** is valid and unexpired | ||
* The challenge was completed satisfactorily | ||
* (When applicable) **SCORING** meets implementation thresholds | ||
* **Failed Verification** Occurs when: | ||
* The token is invalid/expired | ||
* The challenge response was incorrect | ||
* The risk score indicates automated behavior | ||
* Network/configuration errors prevent validation | ||
* **SCORING** - An OPTIONAL provider-specific value indicating confidence in the human/bot determination: | ||
* SHOULD be represented as float between 0.0 (likely bot) and 1.0 (likely human). | ||
* MAY be represented as vice-versa (0.0 = no risk, 1.0 = maximum risk). | ||
* MAY, but SHOULD NOT be represented in other than float formats, e.g. 0 - 100 (as percentages) | ||
* SHOULD be accessible through CaptchaResponseInterface extensions | ||
* Thresholds for success/failure are implementation-defined | ||
* Threshold SHOULD be configurable via CaptchaInterface extensions | ||
|
||
### 1.2 Goal | ||
This specification establishes a standardized interface for CAPTCHA implementations in PHP with the primary objective of **enabling immediate, low-effort substitution of CAPTCHA providers during critical vendor lock-in scenarios**. Specifically addressing real-world crises where: | ||
- Providers discontinue services or change pricing models abruptly | ||
- Security vulnerabilities require emergency provider migration | ||
- Sudden service bans | ||
|
||
The interface shall achieve: | ||
1. **Zero-Refactor Replacement**: Allow switching providers (e.g., Google reCAPTCHA -> hCaptcha -> Cloudflare Turnstile) through configuration/vendor changes only | ||
2. **DI Container Readiness**: Enable dependency injection of any compliant implementation without call-site modifications | ||
3. **Vendor Crisis Resilience**: Mitigate business continuity risks during: | ||
- Access restrictions | ||
- Provider API shutdowns | ||
- Compliance requirement changes | ||
4. **Cost Containment**: Eliminate: | ||
- System-wide code refactoring during migrations | ||
- Parallel implementation maintenance | ||
- Provider-specific testing overhead | ||
|
||
## 2. Interfaces | ||
|
||
### 2.1 CaptchaInterface | ||
|
||
```php | ||
namespace Psr\Captcha; | ||
|
||
/** | ||
* Interface of Captcha service itself. | ||
* MUST decide whether user passed the Captcha or not and return corresponding response. | ||
* SHOULD contain method to configure SCORING threshold (if applicable by PROVIDER) | ||
* SHOULD throw a CaptchaException as soon as possible if appears any non-user related error that prevents correct Captcha solving (e.g. network problems, incorrect secret token, e.g.) | ||
*/ | ||
interface CaptchaInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there might be a need for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Idk what did you mean by this, probably There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, for example, given a token that is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, that interface is not quite for that purpose, but rather to verify already solved captcha task by its token using some external (or even internal, it doesnt actually matter) captcha service. Roughly, it's an interface to build SDK on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Makes sense. |
||
{ | ||
/** | ||
* Verifies client token and decides whether verification was successful or not (is user a bot or not). | ||
* | ||
* @return CaptchaResponseInterface | ||
* @throws CaptchaException if Captcha cannot be validated (e.g. due to network problems, incorrect secret token, etc.) | ||
*/ | ||
public function verify(string $token): CaptchaResponseInterface; | ||
} | ||
``` | ||
|
||
### 2.2 CaptchaResponseInterface | ||
|
||
```php | ||
namespace Psr\Captcha; | ||
|
||
/** | ||
* Interface of the object that CaptchaInterface obliged to return on ::verify() method. | ||
* MUST contain enough information to consistently say whether user succesfully passed Captcha or not. | ||
* SHOULD contain actual user's SCORING | ||
* MAY contain additional information (e.g., gathered from it's captcha-vendor service's verification endpoint) (i.e. message, errors, etc.) | ||
*/ | ||
interface CaptchaResponseInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it an interface and not a bool? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be mentioned in meta-document. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mentioned it in |
||
{ | ||
/** | ||
* Return true/false depends on whether verification was successful or not (is user a bot or not). | ||
* | ||
* @return bool | ||
*/ | ||
public function isSuccess(): bool; | ||
} | ||
``` | ||
|
||
### 2.3 CaptchaException | ||
|
||
```php | ||
namespace Psr\Captcha; | ||
|
||
/** | ||
* MUST be thrown from CaptchaInterface methods if Captcha test itself cannot be passed due to any reason that is not user-related - network problems, incorrect secret token, unable to parse request-response, etc. | ||
*/ | ||
interface CaptchaException extends \RuntimeException | ||
{ | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line should now read:
Due to the code change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done