Skip to Content
Nuova versione 12 disponibile 🎉
ObfuscatorPacchetto NuGetDifesa in profondità

Difesa in profondità: ogni strato in un’unica build

Una protezione solida non nasce da un singolo espediente: nasce dagli strati. Questo esempio attiva tutte le protezioni del pacchetto NuGet di Babel Obfuscator su un piccolo assembly, così puoi vedere la configurazione Ultimate completa in un solo file di progetto e adattarla alla tua applicazione.

Per usare questo esempio ti serve una licenza per sede di Babel Obfuscator (edizioni Ultimate, Server o Data Center). Il codice sorgente è disponibile su GitHub:

git clone https://github.com/babelfornet/defense-in-depth-nuget-example.git

L’applicazione è un piccolo controllo di abilitazione delle funzionalità (src/LicenseGate/FeatureGate.cs) che contiene proprio il genere di cose che ogni strato protegge (stringhe, pesi numerici, un array e logica con diramazioni):

internal static class FeatureGate { private static readonly int[] Weights = { 3, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; private static readonly string Pepper = "d3f3ns3-1n-d3pth-pepper"; public static GateReport Evaluate(string edition, int tokens, double budget) { bool allowed = edition is "PRO" or "ENTERPRISE" && tokens > 0 && budget >= 100.0; double score = 0.0; for (int i = 0; i < Weights.Length; i++) score += Weights[i] * (tokens + 1) * 0.5; return new GateReport(edition, allowed, Math.Round(score / budget, 4), Digest(edition, tokens)); } // Digest … }

Il progetto console LicenseGate sovrappone gli strati in Release:

<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <!-- Rename & restructure --> <FlattenNamespaces>true</FlattenNamespaces> <OverloadedRenaming>true</OverloadedRenaming> <VirtualFunctions>true</VirtualFunctions> <!-- Hide data --> <StringEncryption>stream</StringEncryption> <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption> <ResourceEncryption>true</ResourceEncryption> <!-- Obscure logic --> <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation> <ControlFlowIterations>3</ControlFlowIterations> <DynamicProxy>external=true;true</DynamicProxy> <!-- Detect & deter runtime attacks --> <TamperingDetection>true</TamperingDetection> <DebuggingProtection>true</DebuggingProtection> <SuppressIldasm>true</SuppressIldasm> <!-- Strip metadata --> <CleanAttributes>true</CleanAttributes> <SealClasses>true</SealClasses> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

Ogni proprietà aggiunge uno strato: la ridenominazione e l’appiattimento dei namespace nascondono l’intento; la cifratura di stringhe, valori e risorse nasconde i dati; il flusso di controllo e il proxy dinamico nascondono la logica; il rilevamento delle manomissioni e la protezione dal debug scoraggiano gli attacchi in fase di esecuzione; la pulizia dei metadati rimuove ciò che non serve all’applicazione in esecuzione. Poiché il pacchetto è una dipendenza usata solo per la build (PrivateAssets=all), nulla di tutto questo finisce nel grafo delle dipendenze dell’app, e i passi successivi dell’SDK lavorano sull’assembly già protetto.

La build dell’esempio in Release applica tutto quanto descritto sopra con un output del programma identico; apri il risultato in un decompilatore e confrontalo con la build Debug per vedere la differenza. L’esempio rispecchia le indicazioni di Migliorare la sicurezza del codice: parti da questa configurazione ed elimina gli strati che non ti servono.

Last updated on