shell bypass 403
<?php
/**
* @package RSForm! Pro
* @copyright (C) 2007-2019 www.rsjoomla.com
* @license GPL, http://www.gnu.org/licenses/gpl-2.0.html
*/
defined('_JEXEC') or die;
class RSFormIBAN
{
/**
* Semantic IBAN structure constants
*/
const COUNTRY_CODE_OFFSET = 0;
const COUNTRY_CODE_LENGTH = 2;
const CHECKSUM_OFFSET = 2;
const CHECKSUM_LENGTH = 2;
const ACCOUNT_IDENTIFICATION_OFFSET = 4;
const INSTITUTE_IDENTIFICATION_OFFSET = 4;
const INSTITUTE_IDENTIFICATION_LENGTH = 4;
const BANK_ACCOUNT_NUMBER_OFFSET = 8;
const BANK_ACCOUNT_NUMBER_LENGTH = 10;
/**
* @var array Country code to size, regex format for each country that supports IBAN
*/
public static $ibanFormatMap = array(
'AA' => array(12, '^[A-Z0-9]{12}$'),
'AD' => array(20, '^[0-9]{4}[0-9]{4}[A-Z0-9]{12}$'),
'AE' => array(19, '^[0-9]{3}[0-9]{16}$'),
'AL' => array(24, '^[0-9]{8}[A-Z0-9]{16}$'),
'AO' => array(21, '^[0-9]{21}$'),
'AT' => array(16, '^[0-9]{5}[0-9]{11}$'),
'AX' => array(14, '^[0-9]{6}[0-9]{7}[0-9]{1}$'),
'AZ' => array(24, '^[A-Z]{4}[A-Z0-9]{20}$'),
'BA' => array(16, '^[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}$'),
'BE' => array(12, '^[0-9]{3}[0-9]{7}[0-9]{2}$'),
'BF' => array(23, '^[0-9]{23}$'),
'BG' => array(18, '^[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$'),
'BH' => array(18, '^[A-Z]{4}[A-Z0-9]{14}$'),
'BI' => array(12, '^[0-9]{12}$'),
'BJ' => array(24, '^[A-Z]{1}[0-9]{23}$'),
'BL' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'BR' => array(25, '^[0-9]{8}[0-9]{5}[0-9]{10}[A-Z]{1}[A-Z0-9]{1}$'),
'CH' => array(17, '^[0-9]{5}[A-Z0-9]{12}$'),
'CI' => array(24, '^[A-Z]{1}[0-9]{23}$'),
'CM' => array(23, '^[0-9]{23}$'),
'CR' => array(17, '^[0-9]{4}[0-9]{13}$'),
'CV' => array(21, '^[0-9]{21}$'),
'CY' => array(24, '^[0-9]{3}[0-9]{5}[A-Z0-9]{16}$'),
'CZ' => array(20, '^[0-9]{4}[0-9]{6}[0-9]{10}$'),
'DE' => array(18, '^[0-9]{8}[0-9]{10}$'),
'DK' => array(14, '^[0-9]{4}[0-9]{9}[0-9]{1}$'),
'DO' => array(24, '^[A-Z0-9]{4}[0-9]{20}$'),
'DZ' => array(20, '^[0-9]{20}$'),
'EE' => array(16, '^[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}$'),
'ES' => array(20, '^[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}$'),
'FI' => array(14, '^[0-9]{6}[0-9]{7}[0-9]{1}$'),
'FO' => array(14, '^[0-9]{4}[0-9]{9}[0-9]{1}$'),
'FR' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'GB' => array(18, '^[A-Z]{4}[0-9]{6}[0-9]{8}$'),
'GE' => array(18, '^[A-Z]{2}[0-9]{16}$'),
'GF' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'GI' => array(19, '^[A-Z]{4}[A-Z0-9]{15}$'),
'GL' => array(14, '^[0-9]{4}[0-9]{9}[0-9]{1}$'),
'GP' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'GR' => array(23, '^[0-9]{3}[0-9]{4}[A-Z0-9]{16}$'),
'GT' => array(24, '^[A-Z0-9]{4}[A-Z0-9]{20}$'),
'HR' => array(17, '^[0-9]{7}[0-9]{10}$'),
'HU' => array(24, '^[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}$'),
'IE' => array(18, '^[A-Z]{4}[0-9]{6}[0-9]{8}$'),
'IL' => array(19, '^[0-9]{3}[0-9]{3}[0-9]{13}$'),
'IR' => array(22, '^[0-9]{22}$'),
'IS' => array(22, '^[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}$'),
'IT' => array(23, '^[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}$'),
'JO' => array(26, '^[A-Z]{4}[0-9]{4}[A-Z0-9]{18}$'),
'KW' => array(26, '^[A-Z]{4}[A-Z0-9]{22}$'),
'KZ' => array(16, '^[0-9]{3}[A-Z0-9]{13}$'),
'LB' => array(24, '^[0-9]{4}[A-Z0-9]{20}$'),
'LC' => array(28, '^[A-Z]{4}[A-Z0-9]{24}$'),
'LI' => array(17, '^[0-9]{5}[A-Z0-9]{12}$'),
'LT' => array(16, '^[0-9]{5}[0-9]{11}$'),
'LU' => array(16, '^[0-9]{3}[A-Z0-9]{13}$'),
'LV' => array(17, '^[A-Z]{4}[A-Z0-9]{13}$'),
'MC' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'MD' => array(20, '^[A-Z0-9]{2}[A-Z0-9]{18}$'),
'ME' => array(18, '^[0-9]{3}[0-9]{13}[0-9]{2}$'),
'MF' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'MG' => array(23, '^[0-9]{23}$'),
'MK' => array(15, '^[0-9]{3}[A-Z0-9]{10}[0-9]{2}$'),
'ML' => array(24, '^[A-Z]{1}[0-9]{23}$'),
'MQ' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'MR' => array(23, '^[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}$'),
'MT' => array(27, '^[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$'),
'MU' => array(26, '^[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}$'),
'MZ' => array(21, '^[0-9]{21}$'),
'NC' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'NL' => array(14, '^[A-Z]{4}[0-9]{10}$'),
'NO' => array(11, '^[0-9]{4}[0-9]{6}[0-9]{1}$'),
'PF' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'PK' => array(20, '^[A-Z]{4}[A-Z0-9]{16}$'),
'PL' => array(24, '^[0-9]{8}[0-9]{16}$'),
'PM' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'PS' => array(25, '^[A-Z]{4}[A-Z0-9]{21}$'),
'PT' => array(21, '^[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}$'),
'QA' => array(25, '^[A-Z]{4}[0-9]{4}[A-Z0-9]{17}$'),
'RE' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'RO' => array(20, '^[A-Z]{4}[A-Z0-9]{16}$'),
'RS' => array(18, '^[0-9]{3}[0-9]{13}[0-9]{2}$'),
'SA' => array(20, '^[0-9]{2}[A-Z0-9]{18}$'),
'SC' => array(27, '^[A-Z]{4}[0-9]{4}[0-9]{16}[A-Z]{3}$'),
'SE' => array(20, '^[0-9]{3}[0-9]{16}[0-9]{1}$'),
'SI' => array(15, '^[0-9]{5}[0-9]{8}[0-9]{2}$'),
'SK' => array(20, '^[0-9]{4}[0-9]{6}[0-9]{10}$'),
'SM' => array(23, '^[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}$'),
'SN' => array(24, '^[A-Z]{1}[0-9]{23}$'),
'ST' => array(21, '^[0-9]{8}[0-9]{11}[0-9]{2}$'),
'TF' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'TL' => array(19, '^[0-9]{3}[0-9]{14}[0-9]{2}$'),
'TN' => array(20, '^[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$'),
'TR' => array(22, '^[0-9]{5}[0-9]{1}[A-Z0-9]{16}$'),
'UA' => array(25, '^[0-9]{6}[A-Z0-9]{19}$'),
'VG' => array(20, '^[A-Z]{4}[0-9]{16}$'),
'WF' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$'),
'XK' => array(16, '^[0-9]{4}[0-9]{10}[0-9]{2}$'),
'YT' => array(23, '^[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$')
);
/**
* @var string Internal IBAN number
*/
private $iban;
/**
* IBAN constructor.
*
* @param $iban
*/
public function __construct($iban)
{
$this->iban = $this->normalize($iban);
}
/**
* Validates the supplied IBAN and provides passthrough failure message when validation fails
*
* @return bool
*/
public function validate()
{
if (!$this->isCountryCodeValid() || !$this->isLengthValid() || !$this->isFormatValid() || !$this->isChecksumValid())
{
return false;
}
else
{
return true;
}
}
/**
* Pretty print IBAN
*
* @return string
*/
public function format()
{
return sprintf(
'%s %s %s',
$this->getCountryCode() . $this->getChecksum(),
substr($this->getInstituteIdentification(), 0, 4),
implode(' ', str_split($this->getBankAccountNumber(), 4))
);
}
/**
* Extract country code from IBAN
*
* @return string
*/
public function getCountryCode()
{
return substr($this->iban, static::COUNTRY_CODE_OFFSET, static::COUNTRY_CODE_LENGTH);
}
/**
* Extract checksum number from IBAN
*
* @return string
*/
public function getChecksum()
{
return substr($this->iban, static::CHECKSUM_OFFSET, static::CHECKSUM_LENGTH);
}
/**
* Extract Account Identification from IBAN
*
* @return string
*/
public function getAccountIdentification()
{
return substr($this->iban, static::ACCOUNT_IDENTIFICATION_OFFSET);
}
/**
* Extract Institute from IBAN
*
* @return string
*/
public function getInstituteIdentification()
{
return substr($this->iban, static::INSTITUTE_IDENTIFICATION_OFFSET, static::INSTITUTE_IDENTIFICATION_LENGTH);
}
/**
* Extract Bank Account number from IBAN
*
* @return string
*/
public function getBankAccountNumber()
{
$countryCode = $this->getCountryCode();
$length = static::$ibanFormatMap[$countryCode][0] - static::INSTITUTE_IDENTIFICATION_LENGTH;
return substr($this->iban, static::BANK_ACCOUNT_NUMBER_OFFSET, $length);
}
/**
* Validate IBAN length boundaries
*
* @return bool
*/
private function isLengthValid()
{
$countryCode = $this->getCountryCode();
$validLength = static::COUNTRY_CODE_LENGTH + static::CHECKSUM_LENGTH + static::$ibanFormatMap[$countryCode][0];
return strlen($this->iban) === $validLength;
}
/**
* Validate IBAN country code
*
* @return bool
*/
private function isCountryCodeValid()
{
$countryCode = $this->getCountryCode();
return !(isset(static::$ibanFormatMap[$countryCode]) === false);
}
/**
* Validate the IBAN format according to the country code
*
* @return bool
*/
private function isFormatValid()
{
$countryCode = $this->getCountryCode();
$accountIdentification = $this->getAccountIdentification();
return !(preg_match('/' . static::$ibanFormatMap[$countryCode][1] . '/', $accountIdentification) !== 1);
}
/**
* Validates if the checksum number is valid according to the IBAN
*
* @return bool
*/
private function isChecksumValid()
{
$countryCode = $this->getCountryCode();
$checksum = $this->getChecksum();
$accountIdentification = $this->getAccountIdentification();
$numericCountryCode = $this->getNumericCountryCode($countryCode);
$numericAccountIdentification = $this->getNumericAccountIdentification($accountIdentification);
$invertedIban = $numericAccountIdentification . $numericCountryCode . $checksum;
return $this->bcmod($invertedIban, 97) === '1';
}
/**
* Extract country code from the IBAN as numeric code
*
* @param $countryCode
*
* @return string
*/
private function getNumericCountryCode($countryCode)
{
return $this->getNumericRepresentation($countryCode);
}
/**
* Extract account identification from the IBAN as numeric value
*
* @param $accountIdentification
*
* @return string
*/
private function getNumericAccountIdentification($accountIdentification)
{
return $this->getNumericRepresentation($accountIdentification);
}
/**
* Retrieve numeric presentation of a letter part of the IBAN
*
* @param $letterRepresentation
*
* @return string
*/
private function getNumericRepresentation($letterRepresentation)
{
$numericRepresentation = '';
foreach (str_split($letterRepresentation) as $char) {
$ord = ord($char);
if ($ord >= 65 && $ord <= 90) {
$numericRepresentation .= (string) ($ord - 55);
} elseif ($ord >= 48 && $ord <= 57) {
$numericRepresentation .= (string) ($ord - 48);
}
}
return $numericRepresentation;
}
/**
* Normalize IBAN by removing non-relevant characters and proper casing
*
* @param $iban
*
* @return mixed|string
*/
private function normalize($iban)
{
return preg_replace('/[^a-z0-9]+/i', '', trim(strtoupper($iban)));
}
/**
* Get modulus of an arbitrary precision number
*
* @param $x
* @param $y
*
* @return string
*/
private function bcmod($x, $y)
{
if (!function_exists('bcmod')) {
$take = 5;
$mod = '';
do {
$a = (int)$mod . substr($x, 0, $take);
$x = substr($x, $take);
$mod = $a % $y;
} while (strlen($x));
return (string)$mod;
} else {
return bcmod($x, $y);
}
}
}