• Resolved Guido

    (@guido07111975)


    Hi,

    For my captcha I want to store the result of a sum in a transient. This way I can compare it with the result that user has filled in. I thought about using a PHP session, but WP does not like that anymore.

    When contact form is loaded on a page, a transient is set that stores the result of the sum. But how does my script create an unique transient (name)? A transient (name) per browser session. And even more important, how to get the value of the correct transient?

    Guido

Viewing 15 replies - 1 through 15 (of 27 total)
  • Thread Starter Guido

    (@guido07111975)

    Update: found a way to create a kind of unique transient name by getting the IP-address of the current visitor and adding this as (decoded) suffix to the transient name. This also solves my problem of getting the value of the correct transient.

    But multiple devices can share the same IP-address, so this is not the best solution.

    Guido

    Moderator bcworkz

    (@bcworkz)

    Perhaps combine the user agent string and IP, then hash the combination? You still could get two different users using the same IP and same user agent through a reverse proxy or something. If the purpose of a Captcha is to confirm humanity, how important would it be to avoid such a situation? If two users use the same transient, what would be the harm?

    I understand there are ways to uniquely “fingerprint” a particular device. I’m unclear exactly how that is done, but I’m also unclear on how important it would be in this case.

    Thread Starter Guido

    (@guido07111975)

    Hi BC!

    After submission is succesful or fails, the transient is deleted and a new one is created. This new one contains another captcha value.

    So, if 2 users are using the same transient (because of similar IP-address), and 1 of them submits the form, the captcha of the other form becomes incorrect. So when the other one submits the form, the captcha returns an error. This means he has to re-submit the form with the correct captcha value.

    Guido

    Moderator bcworkz

    (@bcworkz)

    I see. Server side, all we have available that would identify a non-logged in user is their IP, port, and user agent. IP is the only thing that cannot be spoofed. More specific device data is available via JavaScript. I’m unsure of the specifics. After a quick search, I found this browser fingerprinting library.

    Of note:

    Accuracy of this version is 40-60%, accuracy of the commercial Fingerprint Identification is 99.5%.

    Apparently accurate fingerprinting is somewhat of a trade secret ??

    What if, when you serve the Captcha challenge, include the transient key to the correct solution in the form? When the solution is submitted, the key is included in the sent data. You can then compare the submitted solution to that saved under the key. Since transients are time sensitive, there’s nothing to be gained by saving a known good solution for later use or use by others. The user knowing the key value wouldn’t give them any advantage. In any case it’d be in the form as a hidden field. Casual users would not even know it’s there.

    Thread Starter Guido

    (@guido07111975)

    Hi BC,

    What’s the advantage of including the key in the form? It’s still possible that multiple users share an IP and using the same browser (user agent). So transient name and key (solution of sum) is the same for those users. Or am I missing something?

    About fingerprinting, have no idea whether this is allowed or not (privacy/GDPR in Europe). Same applies to using IP I guess, even an encoded version. Have to look into that. Besides that, I’m no fan of including third party code in my plugin.

    Thanks again! Including user agent data is a good idea.

    Guido

    Moderator bcworkz

    (@bcworkz)

    The advantage is you can generate a unique key for each user regardless of their IP or user agent. You wouldn’t actually send the entire key as I see it, just the variable part. It can be anything sufficiently unique, a UNIX timestamp perhaps, or random_int(). By sending it out in the form and getting it back as part of the Captcha solution means you don’t need to retain any information server side other than the correct solution for that particular key. No need for fingerprinting, sessions, cookies, or other privacy concerns.

    Thread Starter Guido

    (@guido07111975)

    It may be even better to include this random variable in form and in transient name, besides the encoded IP. Instead of adding it as key. That way I can create a unique transient for every visitor.

    Thanks BC!

    Guido

    Hi,

    I had the same problem with my captcha (plugin) .
    Choose a single ID, transmit the captcha as the value of a hidden input and then read it when it comes back.
    It works.

    greetings

    Thread Starter Guido

    (@guido07111975)

    Hi @alessandro12,

    Don’t fully understand what you mean.

    Choose a single ID

    You mean an unique/random value?

    Guido

    Hi, @guido07111975 ,

    Certainly, random.

    name transient = prefix + random value . Everytime


    You can pass the random value (input hidden) and the captcha value to the browser. Better to use the ajax method.
    When it comes back you get Captcha entered by the user and the name transient and you can do the verification.


    I have been trying this system live for about three months now. So far it has blocked all the bots.

    Greetings

    Thread Starter Guido

    (@guido07111975)

    Aha, I now fully understand it. Thanks. My method uses the IP-address of visitors and may be a violention of GDPR in Europe, even when it’s encoded.

    Guido

    Hi @guido07111975 ,

    Yes. Using the IP address could create problems. Really I think.
    About 6 months ago I had tried cookies. With poor results.
    Well, I’m glad I was helpful.
    I remain available.
    Sincerely.

    Thread Starter Guido

    (@guido07111975)

    Final question, if you create an unique transient for every visitor (every time contact page is being loaded), this causes many transients in database. You can set expiration time on transient, but still many temporary transients. How did you solve this?

    Guido

    Moderator bcworkz

    (@bcworkz)

    WP will eventually clean out expired transients, though possibly not frequently enough for your liking. At one time in the past it was only done during updates. I think it’s more frequent now, but IDK how frequent. You could schedule the following callback function to run on a regular basis:

    function do_this_regularly() {
    	global $wpdb;
    	$time = time(); 
    	$wpdb->query("DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE
    		a.option_name LIKE '\_transient\_%' AND
    		a.option_name NOT LIKE '\_transient\_timeout\_%' AND
    		b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
    		AND b.option_value < $time");
    }

    This is not code that I wrote, but I’ve lost the proper credit citation. Apologies and thanks to whomever wrote this. (it was offered freely, it’s not stolen ?? )

    Even with this clean up code, it’s probably good practice to explicitly remove any transients that had their related Captcha solution submitted, successful or not. Of course you’ll still accumulate transients from Captchas that were never submitted back.

    Thread Starter Guido

    (@guido07111975)

    Hi BC,

    I already did a check whether the transient is deleted or not after expiring, in my case it was. But a second related transient (name starts with “_transient_timeout_” (stores the timestamp) is still there. Guess those ones are also deleted later, as described by you.

    Guido

Viewing 15 replies - 1 through 15 (of 27 total)
  • The topic ‘Creating unique transient name per browser session’ is closed to new replies.