Ridurre la superficie di attacco con Jekyll

Prima parte - Creazione di un sito di prova

23-02-2026

Caveat

Questo non è un articolo per “smanettoni”: se siete uno che “smonta e rimonta Wordpress” (sic), ma avete solo un’infarinatura dei principali linguaggi per la creazione di siti Web, lasciate perdere. Jekyll è un sistema estremamente potente, ma tutt’altro che intuitivo. Per capire di cosa stiamo parlando, dovete conoscere almeno HTML, CSS e Markdown. Inoltre, è richiesta una minima conoscenza di Liquid e YAML, ma questa potete acquisirla anche in corso d’opera. Utile, ma non indispensabile, è la conoscenza dei principii basilari della SEO (p.es. i microdata).

Cos’è Jekyll

I creatori di Jekyll lo presentano così:

Jekyll is a static site generator. You give it text written in your favorite markup language and it uses layouts to create a static website. You can tweak how you want the site URLs to look, what data gets displayed on the site, and more.

Jekyll vi premette di creare siti anche complessi senza accollarvi il fastidio e il rischio di gestire una base-dati.

I siti istituzionali sono costituti da pagine che vengono aggiornate molto raramente. Malgrado ciò, la maggior parte dei siti istituzionali è basata su CMS open-source con utilizzo intensivo di plugin di autori sconosciuti. Questa immotivata estensione della superficie di attacco può essere evitata con l’adozione di Jekyll.

Lati positivi di Jekyll

Jekyll produce siti costituiti da pagine HTML statiche.
Non è vulnerabile alla SQL injection, perché non fa uso di database relazionali.
Non è vulnerabile alla privilege escalation, perché non definisce un proprio insieme di utenti, dato che il codice delle pagine è modificato in remoto.
Non è vulnerabile al cross-site scripting perché non prevede il passaggio di parametri che possano essere intercettati e modificati dall’utente.

Inoltre, Jekyll vi mette al riparo dal rischio di affidarsi a un Webmaster cialtrone, che non è poca cosa.

L’elenco dei siti realizzati con Jekyll è piuttosto vasto e comprende, fra gli altri, il sito Developers Italia del Dipartimento per la Trasformazione Digitale e questo stesso sito.

Installazione di Jekyll

Le istruzioni sono sul sito ufficiale: https://jekyllrb.com/docs; ne riportiamo di seguito i punti principali.

Installazione ambiente di sviluppo Ruby

Jekyll è basato su Ruby (nessuno è perfetto), quindi è necessario che sul vostro server di sviluppo sia installato l’ambiente di sviluppo Ruby. Questa operazione è estremamente facile e rapida su Windows, MacOS, Ubuntu e buona parte delle distribuzioni di Linux.

A meno di casi paricolari, la presenza di Ruby non è necessaria sul server di esercizio, dove potete copiare solo i file statici genrati dal sistema di sviluppo.

Creazione dello scheletro del sito

Un sito Jekyll deve avere una struttura definita e alcuni file e directory di base. Questo “scheletro” viene creato con il comando:

jekyll new <tacun>

che crea i file e le sotto-directory opportune nella cartella tacun. Il comportamento di default di questo comando è aggiungere nella directory alcuni plugin standard per la gestione del sito (p.es. SEO), ma siccome noi siamo bravi, ne faremo a meno e gli faremo installare una versione minimale del sistema, aggiungendo il parametro –blank:

jekyll new <tacun> --blank

La struttura della directory sarà quindi:

./<tacun>
    |_ .jekyll-metadata
    |_ _data
    |_ _drafts
    |_ _includes
    |_ _layouts
    |       default.html
    |_ _posts
    |_ _sass
    |       main.scss
    |_  assets
    _config.yml
    index.md

Struttura dei file di Jekyll

File / directory Descrizione
_config.yml Memorizza i dati di configurazione. Molte di queste opzioni possono essere specificate tramite l’eseguibile da riga di comando, ma è più semplice definirle qui così non devi ricordarle ogni volta.
_drafts Le bozze sono articoli non pubblicati. Il formato di questi file non include la data: titolo.MARKUP. Vedi come lavorare con le bozze.
_includes Sono frammenti riutilizzabili (partial) che possono essere combinati nei layout e nei post per facilitare il riuso. Il tag Liquid {% include file.ext %} può essere usato per includere il file _includes/file.ext.
_layouts Sono i template che racchiudono i post. I layout vengono scelti per ogni singolo post nel front matter, descritto nella sezione successiva. Il tag Liquid {{ content }} viene usato per inserire il contenuto nella pagina web.
_posts Il contenuto dinamico del sito, per così dire. La convenzione di denominazione di questi file è importante e deve seguire il formato: ANNO-MESE-GIORNO-titolo.MARKUP. I permalink possono essere personalizzati per ogni post, ma la data e il linguaggio di markup sono determinati esclusivamente dal nome del file.
_data Qui vanno inseriti dati del sito ben strutturati. Il motore Jekyll carica automaticamente tutti i file di dati (nei formati .yml, .yaml, .json, .csv o .tsv) presenti in questa directory, rendendoli accessibili tramite site.data. Ad esempio, se esiste il file members.yml, il suo contenuto sarà accessibile tramite site.data.members.
_sass Qui si trovano i partial Sass che possono essere importati nel file main.scss, che verrà poi elaborato in un unico foglio di stile main.css contenente gli stili usati dal sito.
_site Qui viene posizionato (per impostazione predefinita) il sito generato una volta che Jekyll ha completato la trasformazione. È consigliabile aggiungere questa directory al file .gitignore.
.jekyll-metadata Aiuta Jekyll a tenere traccia dei file che non sono stati modificati dall’ultima generazione del sito e di quelli che dovranno essere rigenerati alla prossima build. Questo file non viene incluso nel sito generato. È consigliabile aggiungerlo al file .gitignore.
index.html oppure index.md e altri file HTML/Markdown Se il file contiene una sezione di front matter, verrà trasformato da Jekyll. Lo stesso vale per qualsiasi file .html, .markdown, .md o .textile presente nella directory principale del sito o in directory non elencate sopra.
Altri file/cartelle Ogni altra directory o file non elencato sopra — come le cartelle css, images, i file favicon.ico, ecc. — verrà copiato così com’è nel sito generato. Esistono già molti siti che usano Jekyll, se sei curioso di vedere come sono organizzati.

A questo punto, andate nella root del sito e date il comando:

jekyll s[erve]

Se non avete fatto errori, l’output del sistema sarà:

Configuration file: /usr/local/src/tacun/_config.yml
            Source: /usr/local/src/tacun
       Destination: /usr/local/src/tacun/_site
 Incremental build: disabled. Enable with --incremental
      Generating... 
                    done in 0.115 seconds.
 Auto-regeneration: enabled for '/usr/local/src/tacun'
    Server address: http://127.0.0.1:4000/
  Server running... press ctrl-c to stop.```

Aprendo con un browser la URL:

http://localhost:4000

Dovreste vedere la pagina di default di Jekykll:

Prima configurazione del sito

Il primo passo per la configurazione del sito è l’aggiornamento del file _config.yml, che abbiamo visto comparire nell’output di avvio:

Configuration file: /usr/local/src/tacun/_config.yml
            Source: /usr/local/src/tacun

Il contenuto del file, alla creazione del sistema, è:

url:     "" # the base hostname & protocol for your site, e.g. http://example.com
baseurl: "" # the subpath of your site, e.g. /blog
title:   "" # the name of your site, e.g. ACME Corp.

Oltre a definire questi valori, dovermo aggiungere degli altri parametri per modificare il comportamento standard del sistema. Jekyll gestisce diversi tipi di variabili standard, ma per il momento, ci interesseremo solo di quelle che riguardano le singole pagine e il sito stesso:

destination:    "www/"          
lang:           "it-IT"
title:          "Tacun Srls"
url:            "https://tacun.it"     

La variabile destination definisce il nome della directory in cui Jekyll salverà le pagine statiche del sito. Il valore di default è _site, ma io preferisco usare www.
lang, come vedremo fra poco, definisce la lingua del sito.
title è il titolo di default delle pagine.
url è la URL di pubblicazione del sito.

Possiamo verificare se il sistema è configurato correttamente eseguendo il comando:

jekyll build

che genera le pagine del sito, ma senza pubblicarle come il comando serve. Un comando ls sulla directory di output mostrerà i file:

% ls -R1 www
total 8
drwxr-xr-x  3 root  root   96 Mar  8 09:41 assets
-rw-r--r--  1 root  root  392 Mar  8 09:43 index.html

www/assets:
total 0
drwxr-xr-x  4 root  root  128 Mar  8 09:41 css

www/assets/css:
total 16
-rw-r--r--  1 root  root  237 Mar  8 09:43 main.css
-rw-r--r--  1 root  root  458 Mar  8 09:43 main.css.map

Creazione delle pagine

Jekyll ha letto il file index.md:

---
layout: default
title: "Happy Jekylling!"
---

## You're ready to go!

Start developing your Jekyll website.

e lo ha convertito nella pagina Web index.html:

<!DOCTYPE html>
<html lang="it-IT">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <title>Happy Jekylling! - </title>
    <link rel="stylesheet" href="/assets/css/main.css">
  </head>
  <body>
    <h2 id="youre-ready-to-go">You’re ready to go!</h2>

<p>Start developing your Jekyll website.</p>

  </body>
</html>

Il testo fra all’inizio del file index.md è l’intestazione YAML della pagina.

---
layout: default
title: "Happy Jekylling!"
---

Le variabili: layout e title nell’intestazione di index.md sono page variables e definiscono le caratteristiche e il contenuto della pagina. Nello specifico, layout definisce il modello HTML da utilizzare per la generazione della pagina Web mentre la variabile title definisce il titolo della pagina.

Layout

Il layout default.html si trova nella cartella _layout e ha questa struttura:

<!DOCTYPE html>
<html lang="{{ site.lang | default: "en-US" }}">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <title>{{ page.title }} - {{ site.title }}</title>
    <link rel="stylesheet" href="{{ "/assets/css/main.css" | relative_url }}">
  </head>
  <body>
    {{ content}}
  </body>
</html> 

Le espressioni fra parentesi graffe sono istruzioni in linguaggio Liquid e permettono di inserire del contenuto variabile all’interno della pagina. L’istruzione:

{{ site.lang | default: "en-US" }}

legge la site variable lang e, se non la trova, utilizza al suo posto il valore predefinito en-US.
L’istruzione:

{{ page.title }} - {{ site.title }}

inserisce all’interno del TITLE il titolo della pagina seguito dal titolo del sito:

<title>Happy Jekylling!</title>

L’istruzione:

{{ content }}

inserisce nella struttura HTML il contenuto della pagina sorgente index.md, convertendolo da Markdown ad HTML:

<h2 id="youre-ready-to-go">You're ready to go!</h2>
<p>Start developing your Jekyll website.</p>

Include

In un sito Web, alcuni elementi sono presenti in tutte le pagine; altri, appaiono solo in alcune. Per esempio, in tutte le pagine dei post di questo sito è presente un elemento HEAD:

<head>
    <meta charset="utf-8" />
    <title>Ridurre la superficie di attacco con Jekyll | Tacun Srls</title>
    <meta     name="viewport"        content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
    <meta     name="keyword"         content="blog, cms, jekyll, sicurezza, tecnica, software, web" />
    <meta     name="thumbnail"       content="/assets/img/blog/logo-jekyll.png" />
    <meta     name="description"     content="" />
    <meta property="fb:app_id"       content="" />
    <meta property="og:description"  content="" />
    <meta property="og:image"        content="/assets/img/blog/logo-jekyll.png" />
    <meta property="og:image:width"  content="900" />
    <meta property="og:title"        content="Ridurre la superficie di attacco con Jekyll" />
    <meta property="og:type"         content="website" />
    <meta property="og:url"          content="/blog/2026/02/23/ridurre-superficie-attacco-con-jekyll.html" />
    <link      rel="canonical"       href="/blog/2026/02/23/ridurre-superficie-attacco-con-jekyll.html">
    <link      rel="preconnect"      href="https://fonts.gstatic.com" >
    <link      rel="stylesheet"      href="/assets/css/screen.css">
    <link      rel=icon              href="/assets/img/favicon.ico" type="image/x-icon" >
</head>

Il codice HTML di questo elemento è definito una sola volta nel file:

_indludes/header.html

ed è incluso in tutti i layout delle pagine del sito, con l’istruzione:

{%- include header.html -%}

Allo stesso modo, l’elemento DIV.overlay che consente di visualizzare gli ingrandimenti delle immagini che compaiono nel testo degli articoli, è incluso solo nel layout dei post con l’istruzione:

{%- include overlay.html -%}

Questo meccanismo, indubbiamente ostico all’inizio, permette di creare siti complessi che sono allo stesso tempo facili da manutenere.

Qualcosa di più complesso..

Nella seconda parte di questo articolo vedremo come Jekyll permetta di emulare in maniera sicura molte delle funzioni che sono disponibili nei CMS che utilizzano delle basi di dati:

  • multilingua
  • categorie
  • post
  • automazioni server-side in PHP.

A presto.

X