---
term: 'Sicurezza del livello dati vs. del livello applicativo'
seoTitle: 'Livello dati vs. livello applicativo: dove stanno le regole'
headline: 'Sicurezza del livello dati vs. del livello applicativo'
slug: sicurezza-dati-vs-applicazione
category: database
shortDefinition: 'La sicurezza del livello applicativo è una guardia nel codice; quella del livello dati è una guardia sui dati stessi: servono entrambe.'
relatedTerms:
  - row-level-security
  - access-control-lists-acl
  - class-level-permissions-clp
  - data-encryption-at-rest-transit
  - tenant-isolation
contrastsWith:
  - row-level-security
aboutTerms:
  - 'Data-Layer Security'
  - 'Application-Layer Security'
faq:
  - question: 'Qual è la differenza tra la sicurezza del livello applicativo e quella del livello dati?'
    answer: 'Il livello applicativo mette in sicurezza il comportamento: autenticazione, gestione delle sessioni, validazione degli input e i controlli di logica di business scritti nel codice. Il livello dati mette in sicurezza l''informazione archiviata in sé: crittografia, policy di accesso, regole a livello di riga e audit, che tengono qualunque client o percorso di codice tocchi i dati. Sono livelli distinti – alcuni glossari li confondono, ed è esattamente così che nascono le falle.'
  - question: 'La sicurezza applicativa basta se il database sta dietro di essa?'
    answer: 'No – ed è il consenso di ogni trattazione seria del tema. Tutto ciò che raggiunge il database senza passare per la logica applicativa aggira ogni regola scritta lì: client SQL di amministrazione, strumenti di BI e di analytics, job in background, migrazioni, un secondo servizio che condivide il database. Le regole del livello applicativo proteggono una porta; il livello dati protegge la stanza.'
  - question: 'Dove va applicata l''autorizzazione: nel codice applicativo o nel database?'
    answer: 'A strati, secondo il tipo di regola. Le regole di business ricche di contesto ("i manager approvano le fatture sotto il proprio limite") appartengono al codice applicativo, vicino al workflow. Le regole strutturali ("ciascuno vede solo le proprie righe", "i tenant non si incrociano mai") appartengono al livello dati – policy o ACL che non si possono dimenticare endpoint per endpoint. Mai lato client. La risposta matura è una questione di collocazione, non di fedeltà.'
  - question: 'Che cos''è l''IDOR e quale livello lo previene?'
    answer: 'Insecure Direct Object Reference – recuperare un oggetto per ID senza verificare che il chiamante possa accedervi, la classe di vulnerabilità delle API in testa agli elenchi OWASP. La correzione immediata è un controllo di proprietà nel livello applicativo, su ogni endpoint; la correzione strutturale è l''applicazione delle regole nel livello dati, dove il controllo mancante si risolve in un rifiuto, perché è la riga stessa a negare l''accesso non autorizzato.'
  - question: 'Che cos''è la difesa in profondità?'
    answer: 'Il principio per cui nessun controllo deve essere l''unico baluardo: più barriere sovrapposte, perché un cedimento in un livello venga intercettato dal successivo. Applicato qui: si valida e si autorizza nell''applicazione, e si fa comunque rispettare l''accesso nel livello dati. I livelli non sono ridondanti; cedono in modo diverso, ed è proprio questo il punto.'
  - question: 'I dati vanno cifrati nel livello applicativo o in quello del database?'
    answer: 'Secondo il modello di minaccia, spesso in entrambi. La crittografia a riposo a livello di database protegge dischi rubati e backup, ma resta trasparente per qualsiasi applicazione compromessa. La crittografia nel livello applicativo tiene le chiavi del tutto fuori dal database, proteggendo da una compromissione lato database al prezzo della ricercabilità. La crittografia in transito è il minimo indispensabile a ogni salto.'
  - question: 'Quali sono gli svantaggi di applicare la sicurezza nel database?'
    answer: 'Sono reali, e conviene gestirli invece di negarli: le policy sono invisibili nel codice applicativo, quindi fare il debug di "dove sono finite le mie righe?" richiede disciplina; la valutazione delle policy riga per riga ha un costo in prestazioni; il contesto del tenant portato dalla sessione interagisce in modo sottile con il pooling delle connessioni; e i workflow di business complessi si esprimono male come predicati di riga. Le regole strutturali prosperano lì; quelle di workflow no.'
  - question: 'Come cambiano le piattaforme BaaS il posto dove vive la sicurezza?'
    answer: 'Comprimono il livello intermedio fidato: i client parlano quasi direttamente con il servizio dati, quindi l''autorizzazione deve vivere in costrutti del livello dati – ACL per oggetto, permessi di classe, policy per riga – invece che in controlli scritti a mano nei controller. Non è una debolezza, è il modello: la piattaforma fa rispettare le regole dichiarate a ogni richiesta, e le funzioni lato server portano il resto della logica di business.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'OWASP Top 10 — Broken Access Control'
    url: 'https://owasp.org/Top10/A01_2021-Broken_Access_Control/'
  - name: 'OWASP API Security — Broken Object Level Authorization'
    url: 'https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/'
  - name: 'NIST glossary — defense in depth'
    url: 'https://csrc.nist.gov/glossary/term/defense_in_depth'
  - name: 'PostgreSQL Row Security Policies'
    url: 'https://www.postgresql.org/docs/current/ddl-rowsecurity.html'
cta:
  title: 'Una sicurezza che sopravvive al tuo prossimo refactoring'
  text: 'Back4app mette le regole strutturali dove non si possono dimenticare: ACL su ogni oggetto, permessi di classe su ogni schema, applicati lato server a ogni richiesta – mentre Cloud Code porta la logica di business al di sopra. Difesa in profondità, per impostazione predefinita.'
  linkText: 'Inizia gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-10-14'
translationKey: data-layer-vs-application-layer-security
---

**La sicurezza del livello applicativo è una guardia nel codice; quella del livello dati è una guardia sui dati stessi: servono entrambe.** Non sono sinonimi, anche se perfino alcuni glossari ben posizionati li confondono: il livello applicativo mette in sicurezza il *comportamento* (autenticazione, validazione, regole di business), il livello dati mette in sicurezza *l'informazione archiviata* (policy, ACL, crittografia) contro ogni percorso di accesso – compresi quelli che il codice non vede mai.

## Punti chiave

| Domanda | Risposta |
| --- | --- |
| Livello applicativo | Regole nel codice: authn, validazione, autorizzazione del workflow |
| Livello dati | Regole sui dati: policy, ACL, crittografia, audit – su ogni percorso di accesso |
| Il guasto classico | Un endpoint dimentica il controllo di proprietà – l'IDOR, n. 1 di OWASP |
| Il principio | Difesa in profondità: i livelli cedono in modo diverso, quindi conviene sovrapporli |
| La regola di collocazione | Le regole di workflow nel codice; quelle strutturali sui dati |

## Il bug che riassume il dibattito

Il controllo nel livello applicativo è corretto – finché qualcuno non dimentica di ripeterlo:

```javascript
// Endpoint uno: il controllo di proprietà, presente e corretto
app.get('/contracts/:id', async (req, res) => {
  const contract = await db.contracts.findById(req.params.id);
  if (contract.ownerId !== req.user.id) return res.status(403).end();
  res.json(contract);
});

// Endpoint due, tre sprint più tardi, in un altro file:
app.get('/contracts/:id/export', async (req, res) => {
  const contract = await db.contracts.findById(req.params.id);
  res.send(toPdf(contract));   // ← nessuno ha riscritto il controllo. IDOR in produzione.
});
```

L'applicazione delle regole nel livello dati inverte il guasto: la regola viaggia con la riga, quindi il controllo dimenticato non ha più nulla da dimenticare –

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Data-layer enforcement: the rule travels with the row, not the code path
const doc = await new Parse.Query('Contract').get(contractId); // someone else's row
doc.set('total', 0);
try {
  await doc.save(); // rejected by the object's ACL — server-side, every path
} catch (e) {
  console.log(e.code); // 101: object not found for update
}
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Data-layer enforcement: the rule travels with the row, not the code path
final doc = ParseObject('Contract')..objectId = contractId;
doc.set('total', 0);
final response = await doc.save();
if (!response.success) {
  print(response.error?.code); // rejected by the object's ACL, server-side
}
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Data-layer enforcement: the rule travels with the row, not the code path
var doc = Contract(objectId: contractId)
doc.total = 0
doc.save { result in
  if case .failure(let error) = result {
    print(error.code ?? .unknownError) // rejected by the object's ACL
  }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Data-layer enforcement: the rule travels with the row, not the code path
val doc = ParseObject.createWithoutData("Contract", contractId)
doc.put("total", 0)
doc.saveInBackground { e ->
  if (e != null) Log.d("Security", "blocked by ACL: ${e.code}") // server-side
}
```

## Difesa in profondità: stratificare la sicurezza attorno ai dati archiviati

```mermaid
flowchart TB
  accTitle: Difesa in profondità attorno ai dati archiviati
  accDescr: Le richieste attraversano le difese di rete, poi i controlli del livello applicativo come autenticazione, validazione e autorizzazione di business, e infine i controlli del livello dati – policy, ACL e crittografia – che coprono anche i percorsi che aggirano del tutto l'applicazione.
  N["Livello di rete<br/>TLS, firewall, gateway"] --> A["Livello applicativo<br/>authn · validazione · authz del workflow"]
  A --> D["Livello dati<br/>policy · ACL · crittografia · audit"]
  B["Percorsi di aggiramento:<br/>SQL di admin, strumenti di BI, job, secondi servizi"] -.-> D
```

La freccia tratteggiata è l'argomento: tutto ciò che salta l'applicazione arriva comunque al livello dati – ed è per questo che regole che vivono solo nei controller proteggono una sola porta di una stanza che ne ha molte. È la [difesa in profondità](https://csrc.nist.gov/glossary/term/defense_in_depth) applicata all'archiviazione: barriere sovrapposte che cedono in modo diverso.

## Livello dati vs. livello applicativo: chi fa cosa

| Funzione | Livello applicativo | Livello dati |
| --- | --- | --- |
| Autenticazione | Sessioni, token, flussi di accesso | Si fida dell'identità propagata |
| Validazione degli input | Prima e principale linea di difesa | Tipi e vincoli come rete di sicurezza |
| Autorizzazione del workflow | "Questo ruolo può fare questa azione ora?" | Adattamento scarso – da tenere fuori |
| Autorizzazione strutturale | Controlli di comodità | **Policy, ACL – il muro davvero applicato** |
| Crittografia | Nell'app, per separare le chiavi | A riposo e per campo |
| Audit | Eventi di business | Ogni accesso, ogni percorso |

Due righe portano tutto il dibattito. Le **regole di workflow** – catene di approvazione, macchine a stati, limiti – hanno bisogno di un contesto che solo il codice possiede; forzarle in predicati di riga produce una zuppa di policy impossibile da mantenere. Le **regole strutturali** – proprietà, appartenenza a un tenant, visibilità – sono esattamente ciò che le [policy per riga](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) e le ACL per oggetto fanno rispettare senza disciplina endpoint per endpoint. Ogni regola va collocata dove la sua modalità di guasto resta sopravvivibile.

## IDOR: il dibattito sui livelli, con un elenco di CVE

Il [guasto di controllo degli accessi in testa alla classifica](https://owasp.org/Top10/A01_2021-Broken_Access_Control/) – e [n. 1 nell'elenco specifico per le API](https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/) – è precisamente il controllo dimenticato nel codice qui sopra: utenti autenticati che recuperano oggetti per ID senza alcuna autorizzazione per oggetto. Le pagine di sicurezza catalogano la vulnerabilità; quelle di architettura catalogano i livelli; il nesso fra le due è la parte utile: **l'IDOR è l'aspetto che prende su larga scala una sicurezza applicata solo nell'app**, e le policy del livello dati ne sono la correzione strutturale, perché il controllo mancato si risolve in un rifiuto invece che in una porta aperta.

## Come il BaaS sposta il confine

Le piattaforme di Backend as a Service rendono architetturale la tesi di questo articolo: con i client che parlano (quasi) direttamente con il servizio dati, non esiste più un livello di controller scritti a mano a reggere i controlli – quindi l'autorizzazione *deve* vivere in costrutti del livello dati. Le ACL per oggetto portano la proprietà, i permessi di classe regolano le operazioni per schema, e la piattaforma fa rispettare entrambi a ogni richiesta, da qualunque superficie arrivi. Il livello applicativo non svanisce; si sposta in funzioni lato server che portano la validazione e le regole di workflow – la separazione in due livelli, imposta dalla progettazione invece che dalla disciplina.

## Casi d'uso tipici

- **SaaS multi-tenant.** L'appartenenza a un tenant è la regola strutturale canonica – applicata nel livello dati, testata in modo avversariale, mai affidata a clausole WHERE.
- **Record di proprietà degli utenti.** Messaggi, documenti, ordini: la proprietà è portata dalla riga tramite le ACL; il codice dell'app resta leggibile, i dati restano sigillati.
- **Accesso analitico e BI.** Il percorso di aggiramento reso sicuro: chi fa analisi interroga direttamente le repliche e vede solo ciò che le regole del livello dati consentono.
- **Prove di conformità.** I revisori preferiscono controlli dimostrabili al livello dei dati ai rimandi al codice applicativo.
- **Workflow di approvazione.** Il controesempio: le regole di business che dipendono dallo stato vivono nella logica applicativa – con le regole strutturali che tengono comunque al di sotto.

## Dove va ogni regola? Matrice decisionale

| Metterla nel codice applicativo quando… | Metterla sul livello dati quando… |
| --- | --- |
| La regola ha bisogno del contesto o dello stato del workflow | La regola riguarda proprietà, tenant o visibilità |
| Attraversa servizi ed effetti collaterali | Deve tenere su ogni percorso, aggiramenti compresi |
| Cambia con le iterazioni di prodotto | Il suo cedimento significa violazione, non bug |
| Contano errori ricchi e percorsi di UX | Fallire negando, in silenzio, è desiderabile |
| È una policy di business | È un invariante strutturale |

E la regola permanente sopra le due colonne: i livelli si combinano in AND, non in OR – conviene tenere i controlli del livello applicativo per chiarezza e UX, e lasciare che il livello dati renda sopravvivibile la loro assenza.

## Limiti e trade-off

- **Tutto nel codice applicativo:** logica duplicata da un endpoint all'altro, deriva fra microservizi e ogni percorso di aggiramento senza protezione – la fabbrica di IDOR.
- **Tutto nei dati:** regole invisibili che disorientano chi fa il debug, costi di valutazione per riga, sottigliezze di contesto con il pooling e logica di business contorta in predicati.
- **I due insieme costano coordinamento.** Due posti da aggiornare quando una regola cambia; conviene tenere le regole strutturali poche, stabili e documentate.
- **La collocazione della crittografia è un bivio reale.** Lato database è trasparente e interrogabile; lato applicazione separa le chiavi ma complica le query – si decide campo per campo, minaccia per minaccia.
- **Il confine stesso va verificato.** Chi detiene credenziali di aggiramento – ruoli di amministrazione, master key – sta fuori da ogni cerchio; quell'elenco è il perimetro effettivo.

## I due livelli su Back4app

Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. Consegna la conclusione di questo articolo come architettura predefinita: il livello dati porta le regole strutturali – ACL per oggetto, permessi di classe, campi protetti, applicati lato server a ogni richiesta – mentre i trigger di Cloud Code portano la parte del livello applicativo: validazione, arricchimento e controlli di workflow che girano prima che una scrittura vada a segno. Il bug del filtro dimenticato non ha alcun percorso per passare, e le regole di business mantengono un posto dove vivere.
