Skip to content

Commit 4819df0

Browse files
author
Gregor Pollak
committed
Create the initial (working) code base
1 parent 822d55f commit 4819df0

File tree

9 files changed

+253
-1
lines changed

9 files changed

+253
-1
lines changed

Config/Comment.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* RocketWeb
4+
*
5+
* NOTICE OF LICENSE
6+
*
7+
* This source file is subject to the Open Software License (OSL 3.0)
8+
* that is bundled with this package in the file LICENSE.txt.
9+
* It is also available through the world-wide-web at this URL:
10+
* http://opensource.org/licenses/osl-3.0.php
11+
*
12+
* @category RocketWeb
13+
* @copyright Copyright (c) 2020 RocketWeb (http://rocketweb.com)
14+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15+
* @author Rocket Web Inc.
16+
*/
17+
namespace RocketWeb\CaptchaBypass\Config;
18+
19+
use Magento\Config\Model\Config\CommentInterface;
20+
21+
/**
22+
* Simple class that takes care of showing additional code section of the comment with simple instructions
23+
* on how to include it inside of Cypress Test
24+
*/
25+
class Comment implements CommentInterface
26+
{
27+
/**
28+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
29+
*/
30+
public function getCommentText($elementValue): string
31+
{
32+
$html = '<p>This secret key gets used to match the Automated Test Sessions and disables ReCaptcha.</p>';
33+
$html .= '<p>To activate the Bypass, add the following to the Cypress Test:</p>
34+
<div style="background-color:lightgrey;">
35+
<code><pre>
36+
37+
let secretKey = \'-the-value-from-above-\'
38+
let date = new Date(). getTime()
39+
let hash = CryptoJS.MD5(secretKey + \'-\' + date)
40+
cy.setCookie(\'' . Provider::COOKIE_KEY . '\', hash);
41+
</pre></code>
42+
</div>';
43+
44+
return $html;
45+
}
46+
}

Config/Provider.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* RocketWeb
4+
*
5+
* NOTICE OF LICENSE
6+
*
7+
* This source file is subject to the Open Software License (OSL 3.0)
8+
* that is bundled with this package in the file LICENSE.txt.
9+
* It is also available through the world-wide-web at this URL:
10+
* http://opensource.org/licenses/osl-3.0.php
11+
*
12+
* @category RocketWeb
13+
* @copyright Copyright (c) 2020 RocketWeb (http://rocketweb.com)
14+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15+
* @author Rocket Web Inc.
16+
*/
17+
namespace RocketWeb\CaptchaBypass\Config;
18+
19+
/**
20+
* Standard configuration provider class.
21+
*/
22+
class Provider
23+
{
24+
private const XML_BYPASS_SECRET_KEY = 'recaptcha_frontend/bypass/secret_key';
25+
private \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig;
26+
27+
public const COOKIE_KEY = '__rbp';
28+
29+
public function __construct(
30+
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
31+
) {
32+
$this->scopeConfig = $scopeConfig;
33+
}
34+
35+
public function getSecretKey(): ?string
36+
{
37+
$secretKey = $this->scopeConfig->getValue(self::XML_BYPASS_SECRET_KEY);
38+
if (!$secretKey) {
39+
return null;
40+
}
41+
42+
return $secretKey;
43+
}
44+
}

Plugin/IsCaptchaEnabledPlugin.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* RocketWeb
4+
*
5+
* NOTICE OF LICENSE
6+
*
7+
* This source file is subject to the Open Software License (OSL 3.0)
8+
* that is bundled with this package in the file LICENSE.txt.
9+
* It is also available through the world-wide-web at this URL:
10+
* http://opensource.org/licenses/osl-3.0.php
11+
*
12+
* @category RocketWeb
13+
* @copyright Copyright (c) 2020 RocketWeb (http://rocketweb.com)
14+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15+
* @author Rocket Web Inc.
16+
*/
17+
namespace RocketWeb\CaptchaBypass\Plugin;
18+
19+
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
20+
use RocketWeb\CaptchaBypass\Config\Provider;
21+
22+
/**
23+
* The after-plugin in which we fetch the cookie value from the browser, and we compare it to what it should be
24+
*
25+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
26+
*/
27+
class IsCaptchaEnabledPlugin
28+
{
29+
private \Magento\Framework\Stdlib\Cookie\CookieReaderInterface $cookieReader;
30+
private \RocketWeb\CaptchaBypass\Config\Provider $configProvider;
31+
private \Psr\Log\LoggerInterface $logger;
32+
33+
public function __construct(
34+
\Magento\Framework\Stdlib\Cookie\CookieReaderInterface $cookieReader,
35+
\RocketWeb\CaptchaBypass\Config\Provider $configProvider,
36+
\Psr\Log\LoggerInterface $logger
37+
) {
38+
$this->cookieReader = $cookieReader;
39+
$this->configProvider = $configProvider;
40+
$this->logger = $logger;
41+
}
42+
43+
/**
44+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
45+
*/
46+
public function afterIsCaptchaEnabledFor(IsCaptchaEnabledInterface $subject, $result)
47+
{
48+
if ($result === false) {
49+
// If Captcha is disabled, then no point of checking if bypass is needed
50+
return false;
51+
}
52+
53+
$cookieData = (string)$this->cookieReader->getCookie(Provider::COOKIE_KEY);
54+
if (!$cookieData) {
55+
// cookie with data not set, skipping bypass
56+
return $result;
57+
}
58+
59+
$secretKey = $this->configProvider->getSecretKey();
60+
if (!$secretKey) {
61+
// Bypass Secret Key empty/not-set, skipping bypass
62+
return $result;
63+
}
64+
65+
/**
66+
* Define 1h window in which we look for hash values to compensate for any miss-configurations of system clocks
67+
*/
68+
$timestamp = time();
69+
$start = $timestamp - 1800;
70+
$end = $timestamp + 1800;
71+
72+
for ($i = $start; $i <= $end; $i++) {
73+
// since we are not using md5() for security reasons, it's safe to ignore it
74+
// @phpcs:ignore
75+
$hash = md5($secretKey . '-' . $i);
76+
if ($hash === $cookieData) {
77+
// We found a match for the hash, we are disabling captcha
78+
return false;
79+
}
80+
}
81+
// Log the missmatch. With cookie set, something had to go wrong?
82+
$this->logger->info(
83+
'RecaptchaBypass mismatch. Cookie data: ' . $cookieData . ' | start: ' . $start
84+
. ' | end: ' . $end . ' | key: ' . $secretKey
85+
);
86+
87+
return $result;
88+
}
89+
}

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
# magento-captcha-bypass
1+
# RocketWeb Captcha Bypass
22
The extension disables Google reCAPTCHA by providing a simple hashed value thru a cookie
3+
4+
More details to come soon!

composer.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "rocketweb/magento-captcha-bypass",
3+
"description": "The extension disables Google reCAPTCHA by providing a simple hashed value thru a cookie",
4+
"require": {
5+
"ext-simplexml": "*",
6+
"ext-dom": "*",
7+
"php": "^7.4.0",
8+
"magento/magento-composer-installer": "*"
9+
},
10+
"type": "magento2-module",
11+
"version": "1.0.0",
12+
"license": [
13+
"OSL-3.0",
14+
"AFL-3.0"
15+
],
16+
"autoload": {
17+
"files": [
18+
"registration.php"
19+
],
20+
"psr-4": {
21+
"RocketWeb\\CaptchaBypass\\": ""
22+
}
23+
},
24+
"extra": {
25+
"map": [
26+
[
27+
"RocketWeb/CaptchaBypass"
28+
]
29+
]
30+
}
31+
}

etc/adminhtml/system.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
3+
<system>
4+
<section id="recaptcha_frontend">
5+
<group id="bypass" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1"
6+
showInStore="0">
7+
<label>Bypass Storefront ReCaptcha</label>
8+
<field id="secret_key" translate="label" sortOrder="100" type="text" showInDefault="1"
9+
showInWebsite="1" showInStore="0">
10+
<comment><model>RocketWeb\CaptchaBypass\Config\Comment</model></comment>
11+
</field>
12+
</group>
13+
</section>
14+
</system>
15+
</config>

etc/frontend/di.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
4+
<type name="Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface">
5+
<plugin sortOrder="50" name="RocketWeb_CaptchaBypass_Plugin"
6+
type="RocketWeb\CaptchaBypass\Plugin\IsCaptchaEnabledPlugin"/>
7+
</type>
8+
</config>

etc/module.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
4+
<module name="RocketWeb_CaptchaBypass" setup_version="1.0.0">
5+
<sequence>
6+
<module name="Magento_ReCaptchaUi"/>
7+
<module name="Magento_ReCaptchaAdminUi"/>
8+
</sequence>
9+
</module>
10+
</config>

registration.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types=1);
2+
3+
\Magento\Framework\Component\ComponentRegistrar::register(
4+
\Magento\Framework\Component\ComponentRegistrar::MODULE,
5+
'RocketWeb_CaptchaBypass',
6+
__DIR__
7+
);

0 commit comments

Comments
 (0)