28define(
'MAIN_SECURITY_FORCECSP',
'*');
31require
'../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
40require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
41require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
44$langs->loadLangs(array(
"users",
"admin",
"other",
"website"));
50$action =
GETPOST(
'action',
'aZ09');
51$cancel =
GETPOST(
'cancel',
'alpha');
69if (preg_match(
'/set_([a-z0-9_\-]+)/i', $action, $reg)) {
73 header(
"Location: ".$_SERVER[
"PHP_SELF"]);
78} elseif (preg_match(
'/del_([a-z0-9_\-]+)/i', $action, $reg)) {
81 header(
"Location: ".$_SERVER[
"PHP_SELF"]);
86} elseif ($action ==
'removecspsource') {
89 $sourcecsp = explode(
"_",
GETPOST(
"sourcecsp"));
90 $directive = $sourcecsp[0];
91 $sourcekey = isset($sourcecsp[1]) ? $sourcecsp[1] :
null;
92 $sourcedata = isset($sourcecsp[2]) ? $sourcecsp[2] :
null;
96 if (empty($directive)) {
100 if (!empty($directivesarray[$directive])) {
101 $directivetype = (
string) $directivesarray[$directive][
"data-directivetype"];
102 if (isset($sourcekey)) {
103 $sourcetype = $sourcesarray[$directivetype][$sourcekey][
"data-sourcetype"];
107 $securitycspstring =
"";
108 if (!$error && !empty($forceCSPArr)) {
109 if (isset($sourcekey) && !empty($forceCSPArr[$directive][$sourcekey])) {
110 unset($forceCSPArr[$directive][$sourcekey]);
112 if (count($forceCSPArr[$directive]) == 0) {
113 unset($forceCSPArr[$directive]);
115 foreach ($forceCSPArr as $directive => $sourcekeys) {
116 if ($securitycspstring !=
"") {
117 $securitycspstring .=
"; ";
120 foreach ($sourcekeys as $key => $source) {
121 $directivetype = $directivesarray[$directive][
"data-directivetype"];
122 $sourcetype = $sourcesarray[$directivetype][$source][
"data-sourcetype"];
123 if ($sourcetype ==
"quoted") {
124 $sourcestring .=
" '".$source.
"'";
126 $sourcestring .=
" ".$source;
129 $securitycspstring .= $directive . $sourcestring;
143 setEventMessages($langs->trans(
"MainSecurityPolicySucesfullyRemoved"),
null,
'mesgs');
146 setEventMessages($langs->trans(
"MainErrorRemovingSecurityPolicy"),
null,
'errors');
149 header(
"Location: ".$_SERVER[
"PHP_SELF"]);
151} elseif ($action ==
"updateform" &&
GETPOST(
"btn_MAIN_SECURITY_FORCECSP")) {
152 $directivecsp =
GETPOST(
"select_identifier_MAIN_SECURITY_FORCECSP");
153 $sourcecsp =
GETPOST(
"select_source_MAIN_SECURITY_FORCECSP");
154 $sourcedatacsp =
GETPOST(
"input_data_MAIN_SECURITY_FORCECSP");
160 if (empty($directivecsp)) {
163 if ($error || (!isset($sourcecsp) && $directivesarray[$directivecsp][
"data-directivetype"] !=
"none")) {
167 $directivetype = $directivesarray[$directivecsp][
"data-directivetype"];
168 if (isset($sourcecsp)) {
169 $sourcetype = $sourcesarray[$directivetype][$sourcecsp][
"data-sourcetype"];
171 $securitycspstring =
"";
172 if ($sourcetype ==
"data") {
173 $forceCSPArr[$directivecsp][] =
"data:".$sourcedatacsp;
174 } elseif (isset($sourcetype) && $sourcetype ==
"blob") {
175 $forceCSPArr[$directivecsp][] =
"blob:".$sourcedatacsp;
176 } elseif (isset($sourcetype) && $sourcetype ==
"input") {
177 if (empty($forceCSPArr[$directivecsp])) {
178 $forceCSPArr[$directivecsp] = array();
180 $forceCSPArr[$directivecsp] = array_merge(explode(
" ", $sourcedatacsp), $forceCSPArr[$directivecsp]);
182 if (empty($forceCSPArr[$directivecsp])) {
183 $forceCSPArr[$directivecsp] = array();
185 if (!isset($sourcecsp)) {
188 array_unshift($forceCSPArr[$directivecsp], $sourcecsp);
190 foreach ($forceCSPArr as $directive => $sourcekeys) {
191 if ($securitycspstring !=
"") {
192 $securitycspstring .=
"; ";
195 foreach ($sourcekeys as $key => $source) {
196 $directivetype = $directivesarray[$directive][
"data-directivetype"];
197 $sourcetype = $sourcesarray[$directivetype][$source][
"data-sourcetype"];
198 if (isset($sourcetype) && $sourcetype ==
"quoted") {
199 $sourcestring .=
" '".$source.
"'";
200 } elseif ($directivetype !=
"none") {
201 $sourcestring .=
" ".$source;
204 $securitycspstring .= $directive . $sourcestring;
218 setEventMessages($langs->trans(
"MainSecurityPolicySucesfullyAdded"),
null,
'mesgs');
221 setEventMessages($langs->trans(
"MainErrorAddingSecurityPolicy"),
null,
'errors');
223 header(
"Location: ".$_SERVER[
"PHP_SELF"]);
225} elseif ($action ==
"updateform") {
227 $res1 = $res2 = $res3 = $res4 = 0;
228 $securityrp =
GETPOST(
'MAIN_SECURITY_FORCERP',
'alpha');
229 $securitysts =
GETPOST(
'MAIN_SECURITY_FORCESTS',
'alpha');
230 $securitypp =
GETPOST(
'MAIN_SECURITY_FORCEPP',
'alpha');
231 $securitycsp =
GETPOST(
'MAIN_SECURITY_FORCECSP',
'alpha');
232 $securitycspro =
GETPOST(
'MAIN_SECURITY_FORCECSPRO',
'alpha');
244 if ($res1 >= 0 && $res2 >= 0 && $res3 >= 0 && $res4 >= 0 && $res5 >= 0) {
248 header(
"Location: ".$_SERVER[
"PHP_SELF"]);
266 if (!empty($securitycsp)) {
268 if (!preg_match(
'/script-src[^;]*self/', $securitycsp) || !preg_match(
'/script-src[^;]*unsafe-inline/', $securitycsp)) {
269 if (!preg_match(
'/script-src/', $securitycsp)) {
271 $securitycsp .= (preg_match(
'/;\s*$/', $securitycsp) ?
'' :
'; ').
' script-src \'self\' \'unsafe-inline\'';
273 $securitycsp .=
' *.paypal.com';
276 $securitycsp .=
' *.stripe.com';
280 if (!preg_match(
'/script-src[^;]*self/', $securitycsp)) {
281 $securitycsp = preg_replace(
'/script-src\s+/',
'script-src \'self\' ', $securitycsp);
283 if (!preg_match(
'/script-src[^;]*unsafe-inline/', $securitycsp)) {
284 $securitycsp = preg_replace(
'/script-src\s+/',
'script-src \'unsafe-inline\' ', $securitycsp);
287 if (
isModEnabled(
'paypal') && !preg_match(
'/script-src[^;]*paypal/', $securitycsp)) {
288 $securitycsp = preg_replace(
'/script-src\s+/',
'script-src *.paypal.com ', $securitycsp);
290 if (
isModEnabled(
'stripe') && !preg_match(
'/script-src[^;]*stripe/', $securitycsp)) {
291 $securitycsp = preg_replace(
'/script-src\s+/',
'script-src *.stripe.com ', $securitycsp);
296 if (!preg_match(
'/style-src[^;]*self/', $securitycsp) || !preg_match(
'/style-src[^;]*unsafe-inline/', $securitycsp)) {
297 if (!preg_match(
'/style-src/', $securitycsp)) {
298 $securitycsp .= (preg_match(
'/;\s*$/', $securitycsp) ?
'' :
'; ').
' style-src \'self\' \'unsafe-inline\';';
300 if (!preg_match(
'/style-src[^;]*self/', $securitycsp)) {
301 $securitycsp = preg_replace(
'/style-src\s+/',
'style-src \'self\' ', $securitycsp);
303 if (!preg_match(
'/style-src[^;]*unsafe-inline/', $securitycsp)) {
304 $securitycsp = preg_replace(
'/style-src\s+/',
'style-src \'unsafe-inline\' ', $securitycsp);
308 if (!preg_match(
'/dolibarr\.org/', $securitycsp)) {
309 if (!preg_match(
'/default-src/', $securitycsp)) {
310 $securitycsp .= (preg_match(
'/;\s*$/', $securitycsp) ?
'' :
'; ').
' default-src *.dolibarr.org;';
312 $securitycsp = preg_replace(
'/default-src\s+/',
'default-src *.dolibarr.org ', $securitycsp);
316 $securitycsp = preg_replace(
'/\s+/',
' ', $securitycsp);
328$wikihelp =
'EN:Setup_Security|FR:Paramétrage_Sécurité|ES:Configuración_Seguridad';
329llxHeader(
'', $langs->trans(
"MainHttpSecurityHeaders"), $wikihelp,
'', 0, 0,
'',
'',
'',
'mod-admin page-security_other');
334print
'<div class="info">'.$langs->trans(
"HTTPHeaderEditor").
'. '.$langs->trans(
"ReservedToAdvancedUsers").
'.</div>';
340print
'<form action="'.$_SERVER[
"PHP_SELF"].
'" method="POST">';
341print
'<input type="hidden" name="token" value="'.newToken().
'">';
342print
'<input type="hidden" name="action" value="updateform">';
344print
'<div class="div-table-responsive-no-min">';
345print
'<table class="noborder centpercent">';
346print
'<tr class="liste_titre">';
347print
'<td>'.$langs->trans(
"HTTPHeader").
'</td>';
348print
'<td></td>'.
"\n";
352print
'<tr class="oddeven">';
353print
'<td>'.$form->textwithpicto($langs->trans(
'MainSecurityForceRP'),
'HTTP Header Referer-Policy<br><br>'.$langs->trans(
"Recommended").
':<br>strict-origin-when-cross-origin <span class="opacitymedium"> '.$langs->trans(
"or").
' </span> same-origin <span class="opacitymedium">(more secured)</span>', 1,
'help',
'valignmiddle', 0, 3,
'MAIN_SECURITY_FORCERP').
'</td>';
354print
'<td><input class="minwidth500" name="MAIN_SECURITY_FORCERP" id="MAIN_SECURITY_FORCERP" value="'.getDolGlobalString(
"MAIN_SECURITY_FORCERP").
'" spellcheck="false"></td>';
357print
'<tr class="oddeven">';
358print
'<td>'.$form->textwithpicto($langs->trans(
'MainSecurityForceSTS'),
'HTTP Header Strict-Transport-Security<br><br>'.$langs->trans(
"Example").
':<br>max-age=31536000; includeSubDomains', 1,
'help',
'valignmiddle', 0, 3,
'MAIN_SECURITY_FORCESTS').
'</td>';
359print
'<td><input class="minwidth500" name="MAIN_SECURITY_FORCESTS" id="MAIN_SECURITY_FORCESTS" value="'.getDolGlobalString(
"MAIN_SECURITY_FORCESTS").
'" spellcheck="false"></td>';
362print
'<tr class="oddeven">';
363print
'<td>'.$form->textwithpicto($langs->trans(
'MainSecurityForcePP'),
'HTTP Header Permissions-Policy<br><br>'.$langs->trans(
"Example").
':<br>camera=*, microphone=(), geolocation=*', 1,
'help',
'valignmiddle', 0, 3,
'MAIN_SECURITY_FORCEPP').
'</td>';
364print
'<td><input class="minwidth500" name="MAIN_SECURITY_FORCEPP" id="MAIN_SECURITY_FORCEPP" value="'.getDolGlobalString(
"MAIN_SECURITY_FORCEPP").
'" spellcheck="false"></td>';
367$examplecsprule =
"frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
370print
'<tr class="oddeven nohover">';
371print
'<td class="tdtop">'.$form->textwithpicto($langs->trans(
'MainContentSecurityPolicy'),
'HTTP Header Content-Security-Policy<br><br>'.$langs->trans(
"Example").
":<br>".$examplecsprule, 1,
'help',
'valignmiddle', 0, 3,
'MAIN_SECURITY_FORCECSP').
'</td>';
374print
'<div class="div-table-responsive-no-min">';
376print
'<input class="minwidth500 quatrevingtpercent" name="MAIN_SECURITY_FORCECSP" id="MAIN_SECURITY_FORCECSP" value="'.$forceCSP.
'" spellcheck="false"> <span id="btnaddcontentsecuritypolicy" class="cursorpointer">'.
img_picto(
'',
'add').
'</span><br>';
378print
'<br class="selectaddcontentsecuritypolicy hidden">';
380print
'<div id="selectaddcontentsecuritypolicy" class="hidden selectaddcontentsecuritypolicy">';
381print $form->selectarray(
"select_identifier_MAIN_SECURITY_FORCECSP", $selectarrayCSPDirectives,
"select_identifier_MAIN_SECURITY_FORCECSP", $langs->trans(
"FillCSPDirective"), 0, 0,
'', 0, 0, 0,
'',
'minwidth200 maxwidth350 inline-block');
383print
'<input type="hidden" id="select_source_MAIN_SECURITY_FORCECSP" name="select_source_MAIN_SECURITY_FORCECSP">';
384foreach ($selectarrayCSPSources as $key => $values) {
385 print
'<div class="div_MAIN_SECURITY_FORCECSP hidden inline-block maxwidth350" id="div_'.$key.
'_MAIN_SECURITY_FORCECSP">';
386 print $form->selectarray(
"select_".$key.
"_MAIN_SECURITY_FORCECSP", $values,
"select_".$key.
"_MAIN_SECURITY_FORCECSP", $langs->trans(
"FillCSPSource"), 0, 0,
'', 0, 0, 0,
'',
'minwidth200 maxwidth300 inline-block select_MAIN_SECURITY_FORCECSP');
390print
'<div class="div_input_data_MAIN_SECURITY_FORCECSP hidden inline-block maxwidth200"><input id="input_data_MAIN_SECURITY_FORCECSP" name="input_data_MAIN_SECURITY_FORCECSP" class="valignmiddle marginright"></div>';
392print
'<div class="div_btn_class_MAIN_SECURITY_FORCECSP inline-block maxwidth200 marginleftonly"><input type="submit" id="btn_MAIN_SECURITY_FORCECSP" name="btn_MAIN_SECURITY_FORCECSP" class="butAction small smallpaddingimp valignmiddle" value="'.$langs->trans(
"Add").
'" disabled></div>';
396if (!empty($forceCSP)) {
399 print
'<div class="div-table-responsive-no-min">';
400 print
img_picto(
'',
'graph',
'class="pictofixedwidth"').$langs->trans(
"HierarchicView").
'<br>';
402 foreach ($forceCSPArr as $directive => $sources) {
404 if (in_array($directive, array_keys($selectarrayCSPDirectives))) {
405 print
'<span>'.$directive.
'</span>';
407 print $form->textwithpicto($directive, $langs->trans(
"UnknowContentSecurityPolicyDirective"), 1,
'warning');
409 if (!empty($sources)) {
411 foreach ($sources as $key => $source) {
412 print
'<li><span>'.$source.
'</span> <a href="'.$_SERVER[
"PHP_SELF"].
'?action=removecspsource&sourcecsp='.$directive.
'_'.$key.
'&token='.
newToken().
'">'.
img_delete().
'</a></li>';
416 print
' <a href="'.$_SERVER[
"PHP_SELF"].
'?action=removecspsource&sourcecsp='.$directive.
'&token='.
newToken().
'">'.
img_delete().
'</a>';
430 print
'<tr class="oddeven">';
431 print
'<td>'.$form->textwithpicto($langs->trans(
'MainSecurityForceCSPRO'),
'HTTP Header Content-Security-Policy-Report-Only<br><br>'.$langs->trans(
"Example").
":<br>".$examplecsprule, 1,
'help',
'valignmiddle', 0, 3,
'MAIN_SECURITY_FORCECSPRO').
'</td>';
432 print
'<td><input class="minwidth500" name="MAIN_SECURITY_FORCECSPRO" id="MAIN_SECURITY_FORCECSPRO" value="'.getDolGlobalString(
"MAIN_SECURITY_FORCECSPRO").
'"></td>';
440print
'<div class="center">';
442print
'<input type="submit" class="button small" name="updateandstay" value="'.$langs->trans(
"Save").
'">';
443print
'<input class="button button-cancel small" type="submit" name="cancel" value="'.$langs->trans(
"Cancel").
'">';
449 $(document).ready(function() {
450 $("#btnaddcontentsecuritypolicy").on("click", function(){
451 if($("#selectaddcontentsecuritypolicy").is(":visible")){
452 console.log("We hide select to add Content Security Policy");
453 $(".selectaddcontentsecuritypolicy").hide();
455 console.log("We show select to add Content Security Policy");
456 $(".selectaddcontentsecuritypolicy").show();
460 $("#select_identifier_MAIN_SECURITY_FORCECSP").on("change", function() {
461 key = $(this).find(":selected").data("directivetype");
462 console.log("We hide all select div");
463 $(".div_MAIN_SECURITY_FORCECSP").hide();
464 $(".select_MAIN_SECURITY_FORCECSP").val(null).trigger("change");
465 $(".div_input_data_MAIN_SECURITY_FORCECSP").hide();
466 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",true);
468 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",false);
470 console.log("We show div select with key "+key);
471 $("#div_"+key+"_MAIN_SECURITY_FORCECSP").css("display", "inline-block");
475 $(".select_MAIN_SECURITY_FORCECSP").on("change", function() {
476 keysource = $(this).find(":selected").data("sourcetype");
477 $("#select_source_MAIN_SECURITY_FORCECSP").val($(this).val());
478 console.log("We hide and show fields");
479 if (keysource == "data" || keysource == "input") {
480 $(".div_input_data_MAIN_SECURITY_FORCECSP").css("display", "inline-block");
481 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",true);
483 $("#input_data_MAIN_SECURITY_FORCECSP").val("");
484 $(".div_input_data_MAIN_SECURITY_FORCECSP").hide();
485 if (keysource != undefined) {
486 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",false);
488 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",true);
493 $("#input_data_MAIN_SECURITY_FORCECSP").on("change keyup", function(){
494 if ($(this).val() != "") {
495 console.log("We show add button");
496 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",false);
498 console.log("We hide add button");
499 $("#btn_MAIN_SECURITY_FORCECSP").prop("disabled",true);
security_prepare_head()
Prepare array with list of tabs.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
GetContentPolicySources()
Prepare array of sources for HTTP headers.
GetContentPolicyToArray($forceCSP)
Transform a Content Security Policy to an array.
GetContentPolicyDirectives()
Prepare array of directives for HTTP headers.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.