shell bypass 403
<?php
declare(strict_types=1);
namespace Arcanedev\NoCaptcha;
use Arcanedev\NoCaptcha\Utilities\Request;
use Illuminate\Support\HtmlString;
use Psr\Http\Message\ServerRequestInterface;
/**
* Class AbstractNoCaptcha
*
* @author ARCANEDEV <arcanedev.maroc@gmail.com>
*/
abstract class AbstractNoCaptcha implements Contracts\NoCaptcha
{
/* -----------------------------------------------------------------
| Constants
| -----------------------------------------------------------------
*/
const CAPTCHA_NAME = 'g-recaptcha-response';
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The shared key between your site and ReCAPTCHA
*
* @var string
*/
protected $secret;
/**
* Your site key
*
* @var string
*/
protected $siteKey;
/**
* Forces the widget to render in a specific language.
* Auto-detects the user's language if unspecified.
*
* @var string
*/
protected $lang;
/**
* HTTP Request Client
*
* @var \Arcanedev\NoCaptcha\Contracts\Utilities\Request
*/
protected $request;
/**
* ReCaptcha's response.
*
* @var \Arcanedev\NoCaptcha\Utilities\ResponseV3|null
*/
protected $response;
/**
* Use the global domain.
*
* @var bool
*/
public static $useGlobalDomain = false;
/* -----------------------------------------------------------------
| Constructor
| -----------------------------------------------------------------
*/
/**
* NoCaptcha constructor.
*
* @param string $secret
* @param string $siteKey
* @param string|null $lang
*/
public function __construct($secret, $siteKey, $lang = null)
{
$this->setSecret($secret);
$this->setSiteKey($siteKey);
$this->setLang($lang);
$this->setRequestClient(new Request);
}
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Set the secret key.
*
* @param string $secret
*
* @return $this
*/
protected function setSecret($secret)
{
self::checkKey('secret key', $secret);
$this->secret = $secret;
return $this;
}
/**
* Get the site key.
*
* @return string
*/
public function getSiteKey()
{
return $this->siteKey;
}
/**
* Set Site key.
*
* @param string $siteKey
*
* @return $this
*/
protected function setSiteKey($siteKey)
{
self::checkKey('site key', $siteKey);
$this->siteKey = $siteKey;
return $this;
}
/**
* Set language code.
*
* @param string $lang
*
* @return $this
*/
public function setLang($lang)
{
$this->lang = $lang;
return $this;
}
/**
* Get language code.
*
* @return string|null
*/
public function getLang()
{
return $this->lang;
}
/**
* Set HTTP Request Client.
*
* @param \Arcanedev\NoCaptcha\Contracts\Utilities\Request $request
*
* @return $this
*/
public function setRequestClient(Contracts\Utilities\Request $request)
{
$this->request = $request;
return $this;
}
/**
* Get the last response.
*
* @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|null
*/
public function getLastResponse()
{
return $this->response;
}
/**
* Get the client url.
*
* @return string
*/
public static function getClientUrl()
{
return static::$useGlobalDomain
? 'https://www.recaptcha.net/recaptcha/api.js'
: 'https://www.google.com/recaptcha/api.js';
}
/**
* Get the verification url.
*
* @return string
*/
public static function getVerificationUrl()
{
return static::$useGlobalDomain
? 'https://www.recaptcha.net/recaptcha/api/siteverify'
: 'https://www.google.com/recaptcha/api/siteverify';
}
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Verify Response.
*
* @param string $response
* @param string $clientIp
*
* @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
*/
public function verify($response, $clientIp = null)
{
return $this->response = $this->sendVerifyRequest([
'secret' => $this->secret,
'response' => $response,
'remoteip' => $clientIp
]);
}
/**
* Calls the reCAPTCHA siteverify API to verify whether the user passes CAPTCHA
* test using a PSR-7 ServerRequest object.
*
* @param \Psr\Http\Message\ServerRequestInterface $request
*
* @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse
*/
public function verifyRequest(ServerRequestInterface $request)
{
$body = $request->getParsedBody();
$server = $request->getServerParams();
return $this->verify(
$body[self::CAPTCHA_NAME] ?? '',
$server['REMOTE_ADDR'] ?? null
);
}
/**
* Send verify request to API and get response.
*
* @param array $query
*
* @return \Arcanedev\NoCaptcha\Contracts\Utilities\Response
*/
protected function sendVerifyRequest(array $query = [])
{
$query = array_filter($query);
$json = $this->request->send(
$this->getVerificationUrl().'?'.http_build_query($query)
);
return $this->parseResponse($json);
}
/**
* Parse the response.
*
* @param string $json
*
* @return \Arcanedev\NoCaptcha\Contracts\Utilities\Response|mixed
*/
abstract protected function parseResponse($json);
/* -----------------------------------------------------------------
| Check Methods
| -----------------------------------------------------------------
*/
/**
* Check if has lang.
*
* @return bool
*/
protected function hasLang()
{
return ! empty($this->getLang());
}
/**
* Check key.
*
* @param string $name
* @param string $value
*/
private static function checkKey($name, &$value): void
{
self::checkIsString($name, $value);
$value = trim($value);
self::checkIsNotEmpty($name, $value);
}
/**
* Check if the value is a string value.
*
* @param string $name
* @param string $value
*
* @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
*/
private static function checkIsString($name, $value): void
{
if ( ! is_string($value)) {
throw new Exceptions\ApiException(
"The {$name} must be a string value, ".gettype($value).' given.'
);
}
}
/**
* Check if the value is not empty.
*
* @param string $name
* @param string $value
*
* @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
*/
private static function checkIsNotEmpty($name, $value): void
{
if (empty($value)) {
throw new Exceptions\ApiException("The {$name} must not be empty");
}
}
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Transform the string to an Html serializable object
*
* @param string $html
*
* @return \Illuminate\Support\HtmlString
*/
protected function toHtmlString($html)
{
return new HtmlString($html);
}
}