/** * @param array $matches * @return string */ private function highlightParam($matches) { $value = ''; if (is_array($this->highlightMatches)) { // preg_match_all if (is_array($this->highlightMatches[0])) { $value = $matches[3]; $replace = array(); foreach ($this->highlightMatches[0] as $key => $match) { $this->highlightMatches[0][$key] = $this->callHighlightMatchFilter($match); $replace[] = sprintf($this->highlightMatchFormat, $this->callHighlightMatchFilter($match)); } if ($replace) { $value = str_replace($this->highlightMatches[0], $replace, $value); } } else { // preg_match $param = $this->callHighlightMatchFilter($this->highlightMatches[0]); $value = str_replace($param, sprintf($this->highlightMatchFormat, $param), $matches[3]); } } if (wfWAFUtils::strlen($value) === 0) { $value = sprintf($this->highlightMatchFormat, $value); } return $matches[1] . sprintf($this->highlightParamFormat, $matches[2] . '=' . $value) . $matches[4]; }
/** * @param wfWAFAttackDataStorageFileEngineRow $row * @return bool * @throws wfWAFStorageFileException */ public function addRow($row) { $this->open(); $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE) + 8 + 8); $this->lockRead(); list(, $rowCount) = unpack('V', $this->read(4)); if ($rowCount >= self::MAX_ROWS) { $this->unlock(); return false; } $this->header = array(); $this->offsetTable = array(); $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE) + 8 + 8 + 4 + $rowCount * 4); list(, $nextRowOffset) = unpack('V', $this->read(4)); $rowString = $row->pack(); $this->lockWrite(); // Update offset table $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE) + 8 + 8 + 4 + ($rowCount + 1) * 4); $this->write(pack('V', $nextRowOffset + wfWAFUtils::strlen($rowString))); // Update rowCount $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE) + 8 + 8); $this->write(pack('V', $rowCount + 1)); // Write data $this->seek($nextRowOffset); $packedTimestamp = wfWAFUtils::substr($rowString, 0, 8); $this->write($rowString); // Update oldest timestamp if ($rowCount === 0) { $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE)); $this->write($packedTimestamp); } // Update newest timestamp $this->seek(wfWAFUtils::strlen(wfWAFStorageFile::LOG_FILE_HEADER) + wfWAFUtils::strlen(self::FILE_SIGNATURE) + 8); $this->write($packedTimestamp); $this->unlock(); $this->header = array(); $this->offsetTable = array(); return true; }
/** * @return bool|wfWAFLexerToken * @throws wfWAFParserSyntaxError */ public function nextToken() { if (!$this->scanner->eos()) { /** @var wfWAFLexerTokenMatcher $tokenMatcher */ foreach ($this->tokenMatchers as $tokenMatcher) { $this->scanner->skip('/^\\s+/s'); if ($this->scanner->eos()) { return false; } if (($this->flags & self::FLAG_TOKENIZE_MYSQL_PORTABLE_COMMENTS) === 0 && ($tokenMatcher->getTokenID() === self::MYSQL_PORTABLE_COMMENT_START || $tokenMatcher->getTokenID() === self::MYSQL_PORTABLE_COMMENT_END)) { continue; } if (!$this->hasPortableCommentStart && $tokenMatcher->getTokenID() === self::MYSQL_PORTABLE_COMMENT_END) { continue; } if ($tokenMatcher->useMaximalMunch() && ($match = $this->scanner->check($tokenMatcher->getMatch())) !== null) { $biggestToken = $this->createToken($tokenMatcher->getTokenID(), $match); /** @var wfWAFLexerTokenMatcher $tokenMatcher2 */ foreach ($this->tokenMatchers as $tokenMatcher2) { if ($tokenMatcher === $tokenMatcher2) { continue; } if (($match2 = $this->scanner->check($tokenMatcher2->getMatch())) !== null) { $biggestToken2 = $this->createToken($tokenMatcher2->getTokenID(), $match2); if (wfWAFUtils::strlen($biggestToken2->getValue()) > wfWAFUtils::strlen($biggestToken->getValue())) { $biggestToken = $biggestToken2; } } } $this->scanner->advancePointer(wfWAFUtils::strlen($biggestToken->getValue())); return $biggestToken; } else { if (($match = $this->scanner->scan($tokenMatcher->getMatch())) !== null) { $token = $this->createToken($tokenMatcher->getTokenID(), $match); if ($tokenMatcher->getTokenID() === self::MYSQL_PORTABLE_COMMENT_START) { $this->hasPortableCommentStart = true; } else { if ($tokenMatcher->getTokenID() === self::MYSQL_PORTABLE_COMMENT_END) { $this->hasPortableCommentStart = false; } } return $token; } } } $char = $this->scanner->scanChar(); $e = new wfWAFParserSyntaxError(sprintf('Invalid character "%s" (\\x%02x) found on line %d, column %d', $char, ord($char), $this->scanner->getLine(), $this->scanner->getColumn())); $e->setParseLine($this->scanner->getLine()); $e->setParseColumn($this->scanner->getColumn()); throw $e; } return false; }
/** * Polyfill for random_int. * * @param int $min * @param int $max * @return int */ public static function random_int($min = 0, $max = 0x7fffffff) { if (function_exists('random_int')) { try { return random_int($min, $max); } catch (Exception $e) { // Fall through } catch (TypeError $e) { // Fall through } catch (Error $e) { // Fall through } } $diff = $max - $min; $bytes = self::random_bytes(4); if ($bytes === false || wfWAFUtils::strlen($bytes) != 4) { throw new RuntimeException("Unable to get 4 bytes"); } $val = unpack("Nint", $bytes); $val = $val['int'] & 0x7fffffff; $fp = (double) $val / 2147483647.0; // convert to [0,1] return (int) (round($fp * $diff) + $min); }
public function lengthLessThan($subject) { return wfWAFUtils::strlen(is_array($subject) ? join('', $subject) : (string) $subject) < $this->getExpected(); }
/** * @param string $string * @throws InvalidArgumentException */ public function setString($string) { if (!is_string($string)) { throw new InvalidArgumentException(sprintf('String expected, got [%s]', gettype($string))); } $this->setLength(wfWAFUtils::strlen($string)); $this->string = $string; $this->reset(); }
/** * @todo Implement wfWAFHTTPTransportStreams::send. * @param wfWAFHTTP $request * @return mixed * @throws wfWAFHTTPTransportException */ public function send($request) { $timeout = 5; $url = $request->getUrl(); if ($queryString = $request->getQueryString()) { if (is_array($queryString)) { $queryString = http_build_query($queryString); } $url .= (wfWAFUtils::strpos($url, '?') !== false ? '&' : '?') . $queryString; } $urlParsed = parse_url($request->getUrl()); $headers = "Host: {$urlParsed['host']}\r\n"; if ($auth = $request->getAuth()) { $headers .= 'Authorization: Basic ' . base64_encode($auth['user'] . ':' . $auth['password']) . "\r\n"; } if ($cookies = $request->getCookies()) { if (is_array($cookies)) { $cookies = self::buildCookieString($cookies); } $headers .= "Cookie: {$cookies}\r\n"; } $hasUA = false; if ($_headers = $request->getHeaders()) { if (is_array($_headers)) { foreach ($_headers as $header => $value) { if (trim(wfWAFUtils::strtolower($header)) === 'user-agent') { $hasUA = true; } $headers .= $header . ': ' . $value . "\r\n"; } } } if (!$hasUA) { $headers .= "User-Agent: Wordfence Streams UA\r\n"; } $httpOptions = array('method' => $request->getMethod(), 'ignore_errors' => true, 'timeout' => $timeout, 'follow_location' => 1, 'max_redirects' => 5); if (wfWAFUtils::strlen($request->getBody()) > 0) { $httpOptions['content'] = $request->getBody(); $headers .= 'Content-Length: ' . wfWAFUtils::strlen($httpOptions['content']) . "\r\n"; } $httpOptions['header'] = $headers; $options = array(wfWAFUtils::strtolower($urlParsed['scheme']) => $httpOptions); $context = stream_context_create($options); $stream = fopen($request->getUrl(), 'r', false, $context); if (!is_resource($stream)) { return false; } $metaData = stream_get_meta_data($stream); // Get the HTTP response code $httpResponse = array_shift($metaData['wrapper_data']); if (preg_match_all('/(\\w+\\/\\d\\.\\d) (\\d{3})/', $httpResponse, $matches) !== false) { // $protocol = $matches[1][0]; $status = (int) $matches[2][0]; } else { // $protocol = null; $status = null; } $responseObj = new wfWAFHTTPResponse(); $responseObj->setHeaders(join("\r\n", $metaData['wrapper_data'])); $responseObj->setBody(stream_get_contents($stream)); $responseObj->setStatusCode($status); // Close the stream after use fclose($stream); return $responseObj; }