Sisällysluettelo

Johdanto

Finnassa on käytössä (tai 21.9.2021 tilanteen mukaan tulossa pian voimaan) Content Security Policy (CSP), jonka tarkoituksena on ehkäistä mahdollisten haavoittuvuuksien (esim. XSS) hyödyntämismahdollisuuksia. Tämän seurauksena mitä tahansa skriptiä ei sallita suoritettavaksi, vaan skriptien lisäämiseksi on noudatettava seuraavia ohjeita.

Omiin sivupohjiin on mahdollista lisätä JavaScriptiä esim. chat-upokkeita varten. Lisäyksiä ei kuitenkaan tehdä suoraan script-tagilla (lukuunottamatta erikoistapausta alempana), vaan pitää käyttää headScript- tai inlineScript-metodia, jotta skripti saa tarvittavan nonce-tiedon turvallista suorittamista varten. Skriptejä, joilla ei ole noncea, tai jotka eivät ole hyväksyttyjen listalla, ei hyväksytä suoritettavaksi.

nonce muuttuu jokaisella pyynnöllä, eli arvoa ei voi kirjoittaa suoraan sivun koodiin.


Content Security Policy -sääntöjen määrittäminen

Finnassa on oletuksena melko tiukat säännöt, jotka sallivat lähinnä sellaisten skriptien lataamisen, joissa script-tagissa on oikea nonce. CSP:n räätälöinnistä esim. chat-upokkeita varten on erillinen ohjesivu.

Näkymän sisäisen skriptin lisääminen

Skriptit tallennetaan näkymän themes/custom/js -hakemistoon. Niiden käyttämiseksi on suositeltavaa lisätä ne themes/custom/theme.config.php -tiedostoon tähän tapaan (tässä esimerkissä lisätty oma-hieno.js):

<?php
return [
    'extends' => 'finna2',
    'css' => [
        'custom.css',
        'settings.css'
    ],
    'js' => [
        'custom.js',
		'oma-hieno.js',
    ]
];

Huom! Älä tee tiedostoon muita muutoksia kuin lisäyksiä 'css' tai 'js' -kohtiin. theme.config.php:hen ei voi sisällyttää script-tageja tms., vaan vain linkkejä skripteihin yllämainitun ohjeen mukaisesti. Varmista muutosten toimivuus tallentamalla tiedosto (jätä se auki editoriin) ja käymällä näkymässä.

Tällöin skripti on aina käytettävissä ja otetaan mukaan skriptipakettiin, joka jaetaan muuttumattomana kaikilla sivuilla. Näin selaimen ei tarvitse ladata eri paketteja eri sivuilla, mikä hidastaisi näkymän toimintaa. Lisäksi tämä tapa varmistaa sen, että mahdolliset muutokset skriptissä tulevat heti voimaan. Selain pystyy silti tallentamaan skriptipaketin välimuistiin.

Ulkoisen skriptin lisääminen

Ulkoisen skriptin lisääminen näkymään globaalisti onnistuu vastaavasti kuin sisäisen skriptinkin lisäämällä skriptin osoite themes/custom/theme.config.php -tiedostoon tähän tapaan (tässä esimerkissä lisätty 'https://ninchat.com/customer/laurea/init-library.js'):

<?php
return [
    'extends' => 'finna2',
    'css' => [
        'custom.css',
        'settings.css'
    ],
    'js' => [
        'custom.js',
		'https://ninchat.com/customer/laurea/init-library.js',
    ]
];

Huom! Älä tee tiedostoon muita muutoksia kuin lisäyksiä 'css' tai 'js' -kohtiin. theme.config.php:hen ei voi sisällyttää script-tageja tms., vaan vain linkkejä skripteihin yllämainitun ohjeen mukaisesti. Varmista muutosten toimivuus tallentamalla tiedosto (jätä se auki editoriin) ja käymällä näkymässä.


Yksittäiselle phtml-sivulle ulkoisen skriptin lisääminen onnistuu headScript-metodilla. Esimerkki:

<?=$this->headScript()->setFile('https://olli-suutari-jkl.github.io/jyvaskyla.fi.kirjasto/js/libParent.js') ?>
<?=$this->headScript()->setFile('https://ninchat.com/customer/laurea/init-library.js') ?>

Jos script-tagille tarvitaan erityisiä attribuutteja, voi käyttää myös normaalia script-tagia, johon on lisätty nonce-attribuutti (käytettävissä 24.8.2021 alkaen):

<script id="isoftwidgetjsid" data-lan="en-EN" data-customer-id="HAMK-LIB-V1" src="https://isoft-webchatscripts-server.azurewebsites.net/botchatscripts/isoftwebchatwidgetv3.js" nonce="<?=$this->escapeHtmlAttr($this->cspNonce())?>"></script>
Jos skriptille tarvitaan erityisiä attribuutteja ja sitä tarvitaan näkymässä kaikkialla, voi sen latauksen lisätä tiedostoon content/Additions/general-post-head. Tämä tiedosto sisällytetään kaikkiin normaaleihin sivuihin.

Jos ladattava skripti lataa vielä muita skriptejä tai sisältöä, on varmistettava, että tarvittavat lähteet on sallittu myös CSP:n script-src tai connect-src -määrittelyssä. Selaimen virhekonsolista voi selvittää, mitä skriptejä ei saatu ladattua, jos toiminto ei toimi oikein.

Skriptin lisääminen sivulle

Skriptin lisääminen suoraan sivulle (ns. inline-skripti) on tehtävä inlineScript-metodilla, jotta se saa tarvittavan noncen. Esimerkki:

<?php
  $script = <<<JS
var elems = document.getElementsByClassName('faq_title');
var i;

for (i = 0; i < elems.length; i++) {
  elems[i].addEventListener('click', function() {
    this.classList.toggle('active');
  });
}  
JS;

  echo $this->inlineScript(\Laminas\View\Helper\HeadScript::SCRIPT, $script, 'SET');
?>

Tapahtumien (events) käsittely

Suoraan html-elementtien sisään lisättyjä tapahtumien käsittelijöitä (inline event handlers), esim. onclick, ei voi käyttää. Sen sijaan elementille on annettava id, ja käsittelijä yhdistettävä siihen scriptillä. Esimerkki:

<button id="omanappula" class="btn">Kokoelmat</button>
<?php
  $script = <<<JS
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('omanappula')
    .addEventListener('click', function showContent() {
      alert('Test');
    });
});
JS;

  echo $this->inlineScript(\Laminas\View\Helper\HeadScript::SCRIPT, $script, 'SET');
?>
  • No labels