/** * Gets the word that was stored in session data * @return string the retrieved and decoded word */ protected function getWord() { // Get cypher from session data $cypher = $this->word->getWordCypher(); // Decrypt the word $decryptedString = EncryptionUtility::decrypt($cypher); return implode('-', preg_split('//', $decryptedString, -1, PREG_SPLIT_NO_EMPTY)); }
/** * Renders the captcha image * * @return string empty string (the image is sent here) */ public function render() { // Avoid Brute Force Attacks: if (!$this->word->getAttempts()) { $this->word->setAttempts(1); } else { $this->word->setAttempts($this->word->getAttempts() + 1); // if more than ($this->settings['maxAttempts']) refreshes, block further refreshes // can be negated by connecting with new session id // could get round this by storing num attempts in database against IP // could get round that by connecting with different IP (eg, using proxy servers) // in short, there's little point trying to avoid brute forcing // the best way to protect against BF attacks is to ensure the dictionary is not // accessible via the web or use random string option if ($this->word->getAttempts() > $this->settings['maxAttempts']) { $this->word->setWordHash(''); $this->word->setWordCypher(array()); $this->word->setHashFunction(''); // Get an instance of the word repository $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $wordRepository = $objectManager->get('SJBR\\SrFreecap\\Domain\\Repository\\WordRepository'); // Reset the word $wordRepository->setWord($this->word); $string = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('max_attempts', $this->extensionName); $font = 5; $width = imagefontwidth($font) * strlen($string); $height = imagefontheight($font); $image = ImageCreate($width + 2, $height + 20); $background = ImageColorAllocate($image, 255, 255, 255); ImageColorTransparent($image, $background); $red = ImageColorAllocate($image, 255, 0, 0); ImageString($image, $font, 1, 10, $string, $red); \SJBR\SrFreecap\Utility\ImageContentUtility::sendImage($image, $this->settings['imageFormat']); ImageDestroy($image); // Return an empty string return ''; } } // Get random word $word = \SJBR\SrFreecap\Utility\RandomContentUtility::getRandomWord($this->settings['useWordsList'], $this->settings['wordsListLocation'], $this->settings['generateNumbers'], $this->settings['maxWordLength']); // Save hash of word for comparison // using hash so that if there's an insecurity elsewhere (eg on the form processor), // an attacker could only get the hash // also, shared servers usually give all users access to the session files // echo `ls /tmp`; and echo `more /tmp/someone_elses_session_file`; usually work // so even if your site is 100% secure, someone else's site on your server might not be // hence, even if attackers can read the session file, they can't get the freeCap word // (though most hashes are easy to brute force for simple strings) $this->word->setWordHash(md5($word)); // We use a simple encrypt to prevent the session from being exposed if ($this->settings['accessibleOutput']) { $this->word->setWordCypher(\SJBR\SrFreecap\Utility\EncryptionUtility::encrypt($word)); } // Build the image $image = $this->buildImage($word, $this->settings['imageWidth'], $this->settings['imageHeight'], $this->settings['backgroundType']); // Send the image \SJBR\SrFreecap\Utility\ImageContentUtility::sendImage($image, $this->settings['imageFormat']); // Cleanup ImageDestroy($image); // Return an empty string return ''; }