Skip to content

Solution to Drupal seckit module form field limits

Published: at 09:11 PM

Seckit module is a great module that allows many security related options to be set for a site at one place. But it has limits of 1024 characters on form input fields and these days one might require uch more entries to be added to e.g. connect-src XSS option. There are some patches that extend this to 2048 etc. but not always the most flexible solution (check https://www.drupal.org/project/seckit/issues/3206728). I needed to add around 3000 characters as I wanted to add connect-src for all google supported domains defined at https://www.google.com/supported_domains and in the end I opted to disable connect-src form field on seckit config page,

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Check CspEventSubscriber.php.
 */
function your_module_form_seckit_settings_form_alter(array &$form, FormStateInterface $form_state, string $form_id) {
  if (isset($form['seckit_xss']['csp']['connect-src'])) {
    $form['seckit_xss']['csp']['connect-src']['#attributes']['disabled'] = 'disabled';
  }
}

and implement onResponse event subscriber:

namespace Drupal\your_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * CSP Event Subscriber.
 */
class CspEventSubscriber implements EventSubscriberInterface {

  /**
   * Adds custom CSP headers.a
   */
  public function onResponse(ResponseEvent $event) {
    $response = $event->getResponse();
    $headers = $response->headers;

    // CSP connect-src directive entries.
    $connect_src = [
      '*.google.com', '*.google.ad', '*.google.ae', '*.google.com.af', '*.google.com.ag', '*.google.al', '*.google.am',
      '*.google.co.ao', '*.google.com.ar', '*.google.as', '*.google.at', '*.google.com.au', '*.google.az', '*.google.ba',
      '*.google.com.bd', '*.google.be', '*.google.bf', '*.google.bg', '*.google.com.bh', '*.google.bi', '*.google.bj',
      '*.google.com.bn', '*.google.com.bo', '*.google.com.br', '*.google.bs', '*.google.bt', '*.google.co.bw', '*.google.by',
      '*.google.com.bz', '*.google.ca', '*.google.cd', '*.google.cf', '*.google.cg', '*.google.ch', '*.google.ci',
      '*.google.co.ck', '*.google.cl', '*.google.cm', '*.google.cn', '*.google.com.co', '*.google.co.cr', '*.google.com.cu',
      '*.google.cv', '*.google.com.cy', '*.google.cz', '*.google.de', '*.google.dj', '*.google.dk', '*.google.dm',
      '*.google.com.do', '*.google.dz', '*.google.com.ec', '*.google.ee', '*.google.com.eg', '*.google.es', '*.google.com.et',
      '*.google.fi', '*.google.com.fj', '*.google.fm', '*.google.fr', '*.google.ga', '*.google.ge', '*.google.gg',
      '*.google.com.gh', '*.google.com.gi', '*.google.gl', '*.google.gm', '*.google.gr', '*.google.com.gt', '*.google.gy',
      '*.google.com.hk', '*.google.hn', '*.google.hr', '*.google.ht', '*.google.hu', '*.google.co.id', '*.google.ie',
      '*.google.co.il', '*.google.im', '*.google.co.in', '*.google.iq', '*.google.is', '*.google.it', '*.google.je',
      '*.google.com.jm', '*.google.jo', '*.google.co.jp', '*.google.co.ke', '*.google.com.kh', '*.google.ki', '*.google.kg',
      '*.google.co.kr', '*.google.com.kw', '*.google.kz', '*.google.la', '*.google.com.lb', '*.google.li', '*.google.lk',
      '*.google.co.ls', '*.google.lt', '*.google.lu', '*.google.lv', '*.google.com.ly', '*.google.co.ma', '*.google.md',
      '*.google.me', '*.google.mg', '*.google.mk', '*.google.ml', '*.google.com.mm', '*.google.mn', '*.google.com.mt',
      '*.google.mu', '*.google.mv', '*.google.mw', '*.google.com.mx', '*.google.com.my', '*.google.co.mz', '*.google.com.na',
      '*.google.com.ng', '*.google.com.ni', '*.google.ne', '*.google.nl', '*.google.no', '*.google.com.np', '*.google.nr',
      '*.google.nu', '*.google.co.nz', '*.google.com.om', '*.google.com.pa', '*.google.com.pe', '*.google.com.pg',
      '*.google.com.ph', '*.google.com.pk', '*.google.pl', '*.google.pn', '*.google.com.pr', '*.google.ps', '*.google.pt',
      '*.google.com.py', '*.google.com.qa', '*.google.ro', '*.google.ru', '*.google.rw', '*.google.com.sa', '*.google.com.sb',
      '*.google.sc', '*.google.se', '*.google.com.sg', '*.google.sh', '*.google.si', '*.google.sk', '*.google.com.sl',
      '*.google.sn', '*.google.so', '*.google.sm', '*.google.sr', '*.google.st', '*.google.com.sv', '*.google.td',
      '*.google.tg', '*.google.co.th', '*.google.com.tj', '*.google.tl', '*.google.tm', '*.google.tn', '*.google.to',
      '*.google.com.tr', '*.google.tt', '*.google.com.tw', '*.google.co.tz', '*.google.com.ua', '*.google.co.ug',
      '*.google.co.uk', '*.google.com.uy', '*.google.co.uz', '*.google.com.vc', '*.google.co.ve', '*.google.co.vi',
      '*.google.com.vn', '*.google.vu', '*.google.ws', '*.google.rs', '*.google.co.za', '*.google.co.zm', '*.google.co.zw',
      '*.google.cat', '*.staticflickr.com', '*.flickr.com', 'maps.google.com', 'analytics.google.com', '*.analytics.google.com',
    ];

    // Create the CSP directive.
    $connect_src_directive = "connect-src 'self' " . implode(' ', $connect_src);

    // Check if a Content-Security-Policy header already exists.
    if ($headers->has('Content-Security-Policy')) {
      // Get the existing CSP header.
      $existing_csp = $headers->get('Content-Security-Policy');

      // Append the new connect-src directive to the existing CSP header.
      $new_csp = $existing_csp . '; ' . $connect_src_directive;

      // Set the updated CSP header.
      $headers->set('Content-Security-Policy', $new_csp);
    }
    else {
      // Set the new CSP header if none exists.
      $headers->set('Content-Security-Policy', $connect_src_directive);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::RESPONSE => 'onResponse',
    ];
  }

}

and you also of course need to add service entry:

services:
  your_module.event_subscriber:
    class: Drupal\your_module\EventSubscriber\CspEventSubscriber
    tags:
      - { name: event_subscriber }

Keep in mind that HTTP header max size for Apache server is 8190 bytes so you shouldn't make your HTTP header bigger than what HTTP server supports.