Issue description
To distinguish robots from humans, the usual approach involves presenting an image with some more or less readable characters and requiring the deciphering of the characters. Or presenting images and requiring to identify a subset showing something, where something is described with natural language.
Consider a different approach which presents a sequence of numbers and letters (sent as plain text) and several tasks for reporting back, see example below.
It should be possible to generate random sequence (the token) and allow automatic selection of tasks from a given set. Tasks (or riddles) are a tie between function (formulated in one or more programming languages) and one to n ways of transcribing the instruction into a human readable sentence. The function computes the correct answer, a substring.
It is necessary to use temporary synonyms when communicating about the tasks with the client.
Developer comments
Here is a simple example:
Given the token %C8JN7%.
Given these tasks :
* Pick the first digit
* Pick the last letter
The correct solution is %8N%.
The functions would look like this in PHP:
[%function pick_first_digit($str) {
preg_match("/[0-9]/", $str, $matches);
return isset($matches[0]) ? $matches[0] : null;
}%]
[%function pick_last_letter($str) {
preg_match("/[a-z]/", $str, $matches);
return count($matches) > 0 ? array_pop($matches) : null;
}%]
Implementation comments: there is a static component and a dynamic temporary component. The static component is a collection of static functions. The dynamic component mainly manages a temporary mapping from random strings to the function names of the static component.
The dynamic component must be regenerated regularly. So there is a need to know the last usage of the dynamic component. If it is not within 60 seconds, it can be regenerated without having to worry that the temporary names that were sent to a client come back and are not understood. In the captcha on the client there could be a 60 seconds count down, but that is not a must, since usually users want to get that "done". In the rare case that the user needs more that 60 seconds (because he left his desk), he or she will most likely blame herself and will be rechallenged.
After clicking OK the client retrieves the challenge. The server computes a solvable riddle on the fly and sends it to the client. It contains the token and a task.
The client then augments the POST or puts a request header (XHR) containing the token, tasks paired with the users' answer.
To compute a solvable riddle the server follows this recipe:
* generate a 5-9 digit string (the token) consisting of digits and lower case characters
* pick a random task A from the instruction universe
* check if A returns a non-null result when applied to the token.
* if yes, add A to list of tasks. If no, discard.
* Pick 2-4 tasks.
These factors contribute to the difficulty for a robot (not for a human):
* Token length
* number of tasks per riddle
* bigger task universe
* more variants of the task text in a given language
* shorter temporary name regeneration intervalls
Usability hints:
* Limit the character universe to digits and upper case letters
* Present the tasks one at a time
* Allow the user to click on the token characters (as an answer)
* Allow keyboard entry (if present) as well
* After giving the answer immediately present the next task
* After doing the last pick send the POST request and rechallenge with a new riddle if it fails
In standard case, the user just has to solve n (=number of tasks, 2-4) fairly easy problems. Each problem requires one simple action.
In order to allow bigger variety in the natural language expressions when formulating the task text, the function should return a substring. If the answer to the task is a substring of the return value, it is correct.
This make it possible to formulate these tasks:
* Pick any of the last three characters
* Pick either the first or the second letter
The communication between server and client can be stateless. The problem with expiring temporary ids can be neglected. In this case the user will be just presented another riddle.
Does not work in the presented form unconditionally, since the tasks can be solved client side by applying the reverse process that was used during generation. Since the instruction is a constant text, it can be lookup up and matched to the producing and also solving algorithm. All the hacker needs to do else, is identify the token in the page. If the instruction would not be a text, but rather a sound file with a voice recording, …
|
Work sessions12
Start |
2021-02-22T09:15:27
|
End |
2021-02-22T12:21:20
|
Participant |
Robert Cerny
|
Start |
2021-02-22T13:53:18
|
End |
2021-02-22T14:44:32
|
Participant |
Robert Cerny
|
Start |
2021-02-22T20:31:18
|
End |
2021-02-22T22:56:05
|
Participant |
Robert Cerny
|
Start |
2021-02-23T10:29:37
|
End |
2021-02-23T13:06:59
|
Participant |
Robert Cerny
|
Start |
2021-02-23T14:58:01
|
End |
2021-02-23T15:37:14
|
Participant |
Robert Cerny
|
Start |
2021-02-24T07:16:57
|
End |
2021-02-24T12:04:32
|
Participant |
Robert Cerny
|
Start |
2021-02-24T14:15:58
|
End |
2021-02-24T15:29:09
|
Participant |
Robert Cerny
|
Start |
2021-02-24T19:48:40
|
End |
2021-02-24T21:05:03
|
Participant |
Robert Cerny
|
Start |
2021-02-25T08:19:29
|
End |
2021-02-25T10:41:20
|
Participant |
Robert Cerny
|
Start |
2021-02-25T16:25:43
|
End |
2021-02-25T17:29:43
|
Participant |
Robert Cerny
|
Start |
2021-02-26T10:02:56
|
End |
2021-02-26T16:03:00
|
Participant |
Robert Cerny
|
Start |
2021-02-28T08:38:25
|
End |
2021-02-28T09:38:29
|
Participant |
Robert Cerny
|
|