Content Security Policy Builder
Creates a strict but configurable CSP header from approved local and external service sources.
Function signature
ogBuildContentSecurityPolicy(directives = array(), options = array())
Categories
- Security
Parameters
directivesDirective map such as default-src => array('\'self\'').optionsOptional flags such as allow_inline_style. Recognized keys: `allow_inline_style`.Return value
Short public-safe status message.
- header
- directives
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Builds a Content-Security-Policy header value from explicit directives.
*
* Sources are sanitized conservatively. Use this to assemble a policy string;
* the controller should send it with header('Content-Security-Policy: ...').
*
* @param array $directives Directive map such as default-src => array('\'self\'').
* @param array $options Optional flags such as allow_inline_style.
* @return array CSP header value and directive map.
*/
function ogBuildContentSecurityPolicy($directives = array(), $options = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($directives)) {
$directives = array();
}
if (!is_array($options)) {
$options = array();
}
$policy = array(
'default-src' => array('\'self\''),
'base-uri' => array('\'self\''),
'object-src' => array('\'none\''),
'frame-ancestors' => array('\'self\'')
);
foreach ($directives as $directive => $sources) {
$directive = strtolower(trim((string)$directive));
if (!preg_match('/^[a-z0-9-]+$/', $directive)) {
continue;
}
if (!is_array($sources)) {
$sources = array($sources);
}
$clean_sources = array();
foreach ($sources as $source) {
$source = trim((string)$source);
if (empty($source)) {
continue;
}
if (preg_match('/^[a-z0-9:\/\.\*\-\'\s]+$/i', $source)) {
$clean_sources[] = $source;
}
}
if (!empty($clean_sources)) {
$policy[$directive] = array_values(array_unique($clean_sources));
}
}
if (!empty($options['allow_inline_style'])) {
if (empty($policy['style-src'])) {
$policy['style-src'] = array('\'self\'');
}
if (!in_array('\'unsafe-inline\'', $policy['style-src'], true)) {
$policy['style-src'][] = '\'unsafe-inline\'';
}
}
$parts = array();
foreach ($policy as $directive => $sources) {
$parts[] = $directive . ' ' . implode(' ', $sources);
}
$header_value = implode('; ', $parts);
$result['success'] = true;
$result['message'] = 'Content Security Policy built.';
$result['data'] = array(
'header' => $header_value,
'directives' => $policy
);
return $result;
}