Skip to content

Cloudflare

AnalyticsAnalysis

Class: Drutiny\Cloudflare\Audit\AnalyticsAnalysis
Extends: Drutiny\Audit\AbstractAnalysis
Package: drutiny/cloudflare

Policies

These are the policies that use this class:

Name Title
cloudflare:threats Cloudflare Threat Management
cloudflare:content Cloudflare Content
cloudflare:caching Cloudflare Caching
cloudflare:encryption Cloudflare Encryption
cloudflare:http_status Cloudflare HTTP Status Codes

Parameters

Name Type Description Default
expression string An expression to evaluate to determine the outcome of the audit null

Tokens

Name Type Description Default
expression string An expression to evaluate to determine the outcome of the audit null
invalid_actions array A keyed list of actions the page rule that don't match the values set in the settings parameter. null
Source
  public function gather(Sandbox $sandbox)
  {
    $uri = $sandbox->getTarget()->uri();
    $host = strpos($uri, 'http') === 0 ? parse_url($uri, PHP_URL_HOST) : $uri;
    $sandbox->setParameter('host', $host);

    $zone  = $this->zoneInfo($sandbox->getParameter('zone', $host));
    $sandbox->setParameter('zone', $zone['name']);

    $response = $this->api()->request("GET", "zones/{$zone['id']}/analytics/dashboard", [], TRUE, [
      'since' => $sandbox->getReportingPeriodStart()->format(\DateTime::RFC3339),
      'until' => $sandbox->getReportingPeriodEnd()->format(\DateTime::RFC3339),
    ]);

    foreach ($response as $key => $value) {
      $sandbox->setParameter($key, $value);
    }
  }
  final public function audit(Sandbox $sandbox)
  {
    $this->gather($sandbox);

    $expressionLanguage = new ExpressionLanguage($sandbox);

    $variables  = $sandbox->getParameterTokens();
    $sandbox->logger()->debug(__CLASS__ . ': ' . Yaml::dump($variables));

    $expression = $sandbox->getParameter('not_applicable', 'false');
    $sandbox->logger()->debug(__CLASS__ . ': ' . $expression);
    if (@$expressionLanguage->evaluate($expression, $variables)) {
      return self::NOT_APPLICABLE;
    }

    $expression = $sandbox->getParameter('expression', 'true');
    $sandbox->logger()->info(__CLASS__ . ': ' . $expression);
    return @$expressionLanguage->evaluate($expression, $variables);
  }

ApiEnabledAudit

Class: Drutiny\Cloudflare\Audit\ApiEnabledAudit
Extends: Drutiny\Audit
Package: drutiny/cloudflare

NOTE: This Audit is abstract and cannot be used directly by a policy.

PageRuleAnalysis

Class: Drutiny\Cloudflare\Audit\PageRuleAnalysis
Extends: Drutiny\Audit\AbstractAnalysis
Package: drutiny/cloudflare

Policies

These are the policies that use this class:

Name Title
cloudflare:drupal-urlGenerator-workaround #2819197 - Cloudflare workaround for Drupal 8 urlGenerator

Parameters

Name Type Description Default
zone string The apex domain registered with Cloudflare. null
rule string The page rule pattern to look up. null
expression string An ExpressionLanguage expression to evaluate the outcome of a page rule. null
not_applicable string The expression language to evaludate if the analysis is not applicable. See https://symfony.com/doc/current/components/expression_language/syntax.html 'false'

Tokens

Name Type Description Default
zone string The apex domain registered with Cloudflare. null
rule string The page rule pattern to look up. null
expression string An ExpressionLanguage expression to evaluate the outcome of a page rule. null
not_applicable string The expression language to evaludate if the analysis is not applicable. See https://symfony.com/doc/current/components/expression_language/syntax.html 'false'
settings array A keyed list of settings for a rule. null
Source
  public function gather(Sandbox $sandbox)
  {
    $uri = $sandbox->getTarget()->uri();
    $host = strpos($uri, 'http') === 0 ? parse_url($uri, PHP_URL_HOST) : $uri;
    $sandbox->setParameter('host', $host);

    $zone  = $this->zoneInfo($sandbox->getParameter('zone', $host));
    $sandbox->setParameter('zone', $zone['name']);

    $response = $this->api()->request('GET', "zones/{$zone['id']}/pagerules");

    // Create a reusable translation function to allow settings to use variables.
    $t = function ($v) use ($zone, $host) {
      return strtr($v, [
        ':zone' => $zone['name'],
        ':host' => $host
      ]);
    };

    $constraint = $t($sandbox->getParameter('rule'));


    $rules = array_filter($response['result'], function ($rule) use ($constraint) {
      return $rule['targets'][0]['constraint']['value'] == $constraint;
    });

    // If we couldn't find an explicit match, see if there is a match on another
    // page rule.
    if (!count($rules)) {

      $rules = array_filter($response['result'], function ($rule) use ($constraint) {
        return fnmatch($rule['targets'][0]['constraint']['value'], $constraint);
      });

      if (!count($rules)) {
        throw new \Exception("Cannot find a rule for $constraint.");
      }
    }

    // Build action array.
    $rule = array_shift($rules);
    $sandbox->setParameter('settings', $rule);
    $sandbox->setParameter('rule', $rule['targets'][0]['constraint']['value']);

    foreach ($rule['actions'] as $value) {
      $rule[$value['id']] = isset($value['value']) ? $value['value'] : TRUE;
    }

    $sandbox->setParameter('settings', $rule);
  }
  final public function audit(Sandbox $sandbox)
  {
    $this->gather($sandbox);

    $expressionLanguage = new ExpressionLanguage($sandbox);

    $variables  = $sandbox->getParameterTokens();
    $sandbox->logger()->debug(__CLASS__ . ': ' . Yaml::dump($variables));

    $expression = $sandbox->getParameter('not_applicable', 'false');
    $sandbox->logger()->debug(__CLASS__ . ': ' . $expression);
    if (@$expressionLanguage->evaluate($expression, $variables)) {
      return self::NOT_APPLICABLE;
    }

    $expression = $sandbox->getParameter('expression', 'true');
    $sandbox->logger()->info(__CLASS__ . ': ' . $expression);
    return @$expressionLanguage->evaluate($expression, $variables);
  }

PageRuleMatch

Class: Drutiny\Cloudflare\Audit\PageRuleMatch
Extends: Drutiny\Cloudflare\Audit\ApiEnabledAudit
Package: drutiny/cloudflare

Policies

These are the policies that use this class:

Name Title
cloudflare:redirect_apex Cloudflare redirect Apex to primary domain
cloudflare:always_use_https Cloudflare always use HTTPS

Parameters

Name Type Description Default
zone string The apex domain registered with Cloudflare. null
rule string The page rule pattern to look up. null
settings array A keyed list of actions the page rule should action. null

Tokens

Name Type Description Default
zone string The apex domain registered with Cloudflare. null
rule string The page rule pattern to look up. null
settings array A keyed list of actions the page rule should action. null
actions array A keyed list of actions the page rule contains. null
extra_actions array A keyed list of actions the page rule contains that are not listed in the settings parameter. null
invalid_actions array A keyed list of actions the page rule that don't match the values set in the settings parameter. null
Source
  public function audit(Sandbox $sandbox)
  {
    $uri = $sandbox->getTarget()->uri();
    $host = strpos($uri, 'http') === 0 ? parse_url($uri, PHP_URL_HOST) : $uri;
    $sandbox->setParameter('host', $host);

    $zone  = $this->zoneInfo($sandbox->getParameter('zone', $host));
    $sandbox->setParameter('zone', $zone['name']);

    $response = $this->api()->request('GET', "zones/{$zone['id']}/pagerules");

    // Create a reusable translation function to allow settings to use variables.
    $t = function ($v) use ($zone, $host) {
      return strtr($v, [
        ':zone' => $zone['name'],
        ':host' => $host
      ]);
    };

    $constraint = $t($sandbox->getParameter('rule'));
    $sandbox->setParameter('rule', $constraint);


    $rules = array_filter($response['result'], function ($rule) use ($constraint) {
      return $rule['targets'][0]['constraint']['value'] == $constraint;
    });

    if (!count($rules)) {
      return FALSE;
    }

    // Build action array.
    $rule = array_shift($rules);
    foreach ($rule['actions'] as $action) {
      $actions[$action['id']] = isset($action['value']) ? $action['value'] : TRUE;
    }
    $this->recurKsort($actions);
    $sandbox->setParameter('actions', $actions);

    // Build settings array.
    $settings = $sandbox->getParameter('settings');
    if (isset($settings['forwarding_url'])) {
      $settings['forwarding_url']['url'] = $t($settings['forwarding_url']['url']);
    }
    $this->recurKsort($settings);
    $sandbox->setParameter('settings', $settings);

    // Format parameters so that array_diff_(key|assoc) can do the correct job.
    $settings = array_map(['Symfony\Component\Yaml\Yaml', 'dump'], $settings);
    $actions = array_map(['Symfony\Component\Yaml\Yaml', 'dump'], $actions);

    // Calculate the differences.
    $extra_actions = array_diff_key($actions, $settings);
    $test_actions = array_diff_key($actions, $extra_actions);
    $invalid_actions = array_diff_assoc($test_actions, $settings);

    // Format parameters so that array_diff_(key|assoc) can do the correct job.
    $extra_actions = array_map(['Symfony\Component\Yaml\Yaml', 'parse'], $extra_actions);
    $invalid_actions = array_map(['Symfony\Component\Yaml\Yaml', 'parse'], $invalid_actions);

    $sandbox->setParameter('extra_actions', $extra_actions);
    $sandbox->setParameter('invalid_actions', $invalid_actions);
    $sandbox->setParameter('invalid_actions_array', array_map(function ($key, $value) {
      return ['id' => $key, 'value' => Yaml::dump($value)];
    }, array_keys($invalid_actions), array_values($invalid_actions)));

    $sandbox->setParameter('settings_array', array_map(function ($key, $value) {
      return ['id' => $key, 'value' => $value];
    }, array_keys($settings), array_values($settings)));

    $sandbox->logger()->info(__CLASS__ . PHP_EOL . Yaml::dump(['parameters' => $sandbox->getParameterTokens()], 6));

    return empty($invalid_actions);
  }