Domanda:
Variabili globali e sicurezza delle informazioni
user123574
2019-09-02 23:58:53 UTC
view on stackexchange narkive permalink

Ho l'impressione che sia una buona pratica di programmazione creare variabili in ambiti specifici (come l'ambito di una funzione) ed evitare l'ambito globale per rendere le cose più modulari e meglio organizzate. Tuttavia non sono sicuro che ci sia anche un problema di sicurezza.

Ecco un esempio di variabili globali in Bash che ha funzionato bene per me più di un anno:

  cat <<-EOF >> "$ HOME" /. profile set -x complete -r export war = "/ var / www / html" # Web Application Root; export dmp = "phpminiadmin" # Programma di gestione del database; export -f war war () {cd $ war /} EOFsource "$ HOME" /. profile 2> / dev / null  

Non ho mai avuto problemi con le variabili globali in Bash o JavaScript , molto probabilmente perché ho scritto solo piccoli script per uso personale su ambienti minimalisti.

Perché molti programmatori evitano di utilizzare variabili globali e ci sono esempi di violazioni della sicurezza causate dall'utilizzo di variabili globali?

* "Perché molti programmatori si astengono dall'usare variabili globali?" * - Perché è molto più facile capire e verificare piccoli frammenti di codice che non hanno effetti collaterali.Quando si utilizzano variabili globali, è necessario essere sempre consapevoli di quale parte del codice potrebbe cambiarla in che modo e quale sarà l'effetto - il che è davvero difficile con una base di codice più ampia e variabili globali più che banali senza un comportamento ovvio (cioè alcune variabili globalila variabile di debug potrebbe andare bene).Vedere anche [Global Variables Are Bad] (http://wiki.c2.com/?GlobalVariablesAreBad).
Anche problemi di threading, altrimenti si verificano problemi di concorrenza
Le variabili globali sono più comuni di quanto pensi.I campi statici Java sono effettivamente globali e ampiamente utilizzati.Vanno bene per le costanti o le cose appena assegnate durante l'inizializzazione.I problemi vengono con le variabili globali.
Un'idea più generale del motivo per cui gli sviluppatori odiano le variabili globali è perché possono causare "azioni a distanza" https://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)
Non c'è davvero niente di sbagliato nelle variabili globali se scrivi solo "piccoli" script.È quando si creano script o programmi di dimensioni medio-grandi che diventano un incubo.
In relazione all'ingegneria del software: [Perché Global State è così malvagio?] (Https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil) Alcuni dei problemi menzionati potrebbero ancheportare a problemi di sicurezza.
@whatsisname Anche con piccoli script può essere un problema con più sviluppatori.Se entrambi decidono di utilizzare lo stesso nome per una variabile globale, ma ha uno scopo diverso, si verificheranno problemi.
Penso che uno script di shell di 8 righe (dopo la generazione che ha ancora meno variabili e utilizza solo variabili mantenute dal sistema) senza concorrenza non sia il miglior esempio per discutere i concetti di ingegneria del software che esistono principalmente per rendere più comprensibile una base di codice modulare di grandi dimensioni, soprattutto non secontiene solo assegnazioni di variabili immutabili (costanti).Soprattutto perché fondamentalmente può essere sostituito da un alias a riga singola, in questo caso.
Come dici Javascript, è un caso speciale perché le variabili globali sono visibili e modificabili attraverso la console degli strumenti di sviluppo
Tangenzialmente, anche la tua citazione mancante nella definizione della funzione `war` è un antipattern di sicurezza.Vedi [Implicazioni sulla sicurezza del dimenticare di citare una variabile nelle shell bash / POSIX] (https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells) su [unix.se]
Dieci risposte:
Conor Mancone
2019-09-03 01:18:17 UTC
view on stackexchange narkive permalink

Boicotta i globali!

Sto rubando al commento di Steffen Ullrich, ma il problema principale con le variabili globali è che rendono difficile mantenere il codice ben organizzato e manutenibile. Il suo link va bene, ma non avrai problemi a trovare innumerevoli articoli sui problemi con le variabili globali online.

Quando usi le variabili globali, diventa facile perdere traccia di dove nel tuo programma la variabile viene modificata, specialmente se non hai un flusso lineare semplice. Di conseguenza le variabili globali possono funzionare perfettamente in piccoli script, ma possono causare enormi mal di testa quando un'applicazione inizia a scalare.

Il motivo principale per cui eviterei le globali è perché rendono il test automatico di unità / integrazione un incubo. Le piccole applicazioni possono sopravvivere senza test, ma cercare di gestire un'applicazione più grande senza buoni test è solo un incubo (credimi, ci ho provato nei miei giorni giovani e sciocchi).

Questo potrebbe lasciarti con il l'impressione che le variabili globali vadano bene in applicazioni molto piccole, ma poiché le applicazioni di solito crescono solo nel tempo e le cose che iniziano temporaneamente diventano permanenti, è davvero solo una cattiva idea usarle. Perché iniziare con il piede sbagliato, quando è così facile usare variabili con scope appropriato?

Sicurezza

L'uso di variabili globali non ha implicazioni dirette per la sicurezza, ma rendono più facile ritrovarsi con problemi di sicurezza:

Se un programmatore modifica una funzione nel file A ma non sa o dimentica che il valore per una certa variabile in quella funzione proviene dall'input dell'utente nel file B , potrebbe finire per fare cose insicure sull'input dell'utente senza adeguate guardie di sicurezza.

Variabili globali == morte

Non sono a conoscenza di violazioni avvenute specificatamente a causa di variabili globali, ma è facile sostenere che l'uso di variabili globali ha letteralmente ucciso persone, quindi penso sia ragionevole non usarli mai.

I commenti non sono per discussioni estese;questa conversazione è stata [spostata in chat] (https://chat.stackexchange.com/rooms/98286/discussion-on-answer-by-conor-mancone-global-variables-and-information-security).
Può anche valere la pena notare che molte lingue in realtà non forniscono servizi adeguati per rendere sicure le variabili globali, lasciando il carico al programmatore;in particolare, di solito non c'è un buon modo per limitare ciò che può effettivamente accedere e / o modificarli.Potrebbe anche valere la pena considerare pseudo-globali come i contesti e la maggior parte dei singleton, sebbene tendano ad essere almeno un po 'più sicuri.
Buon vecchio "Robert");Studenti DROP TABLE; - `` aka Bobby Tables
Conor, `Se un programmatore modifica una funzione nel file A ma non sa o dimentica che il valore per una certa variabile in quella funzione proviene dall'input dell'utente nel file B, potrebbe finire per fare cose insicure sull'input dell'utente senza un'adeguata sicurezzaguards.` si prega di considerare di modificare un po 'la frase / espandere in modo che sia più chiara;Non sono sicuro di non aver mai lavorato a un caso simile, quindi non so quale modifica abbia causato quale danno.
Benoit Esnard
2019-09-03 13:16:57 UTC
view on stackexchange narkive permalink

In alcuni ambienti di programmazione, non puoi fidarti dell'ambito globale poiché altre fonti potrebbero leggere / fare confusione con esso.

Ciò ha già portato ad alcune vulnerabilità critiche nella sicurezza prodotti sensibili, come un'esecuzione di codice in modalità remota nell'estensione del browser LastPass .

JavaScript dannoso su una pagina può rubare / fare confusione con tutto ciò che vuole anche se non è in una variabile globale.
@JosephSible Il javascript dannoso non può rubare le variabili locali in una chiusura perché non ha accesso a quella chiusura (che faceva parte di ciò che ha reso popolare IIFE)
@slebetman Non direttamente, ma può fare cose come modificare le variabili globali come `Array` o` document` per rubare cose indirettamente.
Artelius
2019-09-03 17:02:55 UTC
view on stackexchange narkive permalink

Possono fornire alle iniezioni di codice un accesso più facile a tutto

In PHP c'è il superglobale $ GLOBALS ; in Python c'è la funzione globals () , e in Javascript c'è l'oggetto window (o in Node, process ). Tutto ciò rende banale enumerare tutte le variabili globali.

Una volta fatto ciò, puoi sia aspirare le informazioni che contengono e modificarle in modo dannoso. Ad esempio, se i dati sensibili sono archiviati in un globale, un utente malintenzionato potrebbe facilmente estrarli. Se, ad esempio, l'URL di una connessione al database è archiviato in un globale, un utente malintenzionato potrebbe indirizzare l'URL per fare riferimento al server dell'attaccante, quindi la vittima tenterebbe di connettersi a quel server e inviare le credenziali.

Inoltre, se hai molti oggetti globali puoi chiamare i loro metodi con facilità.

Essi violano il "principio del privilegio minimo"

Questo principio dell'ingegneria della sicurezza fondamentalmente dice "non dare a qualcuno più accesso di quello di cui ha bisogno per svolgere il proprio lavoro". Ogni funzione e metodo può leggere e scrivere variabili globali anche se sono totalmente irrilevanti per il suo lavoro, il che significa che se quel pezzo di codice viene dirottato anche in qualche modo limitato, aprirà una superficie di attacco maggiore.

(Ovviamente, la maggior parte dei linguaggi di scripting ha regole di incapsulamento deboli che è anche una violazione di POLP, ma se gli oggetti sono fuori campo, è molto più difficile fargli qualcosa.)

un terreno fertile per codice difettoso

Per ragioni tra cui:

  • il programmatore dimentica che una delle variabili in una funzione è globale e quindi le vengono apportate modifiche persisterà quando la funzione termina,
  • la non ovvia sensibilità del programma all'ordine in cui vengono chiamate le funzioni
  • la facilità con cui possono verificarsi errori a cascata ( ad esempio, quando una funzione imposta un globale su null e successivamente un'altra va in crash)
  • le interazioni altamente complesse che possono verificarsi facilmente e su cui è difficile ragionare

Sono semplicemente disordinate

Se pensi a un'attività in cui ci sono documenti sparsi dappertutto, le cose non sono organizzate e archiviate in modo ordinato ma solo in giro, chi noterà se manca qualcosa? Se un dipendente commette una frode, nessuno individuerà la discrepanza perché le discrepanze sono ovunque. Se un paio di chiavi scompare, qualcuno presumerà che siano sepolti sotto qualcosa o che qualcuno abbia dovuto prenderle in prestito.

Ora potresti dire che è un'esagerazione, ma in tal caso dubito che tu abbia mai ha lavorato con un grande progetto software. I globali vanno bene se il tuo sito web è abbastanza piccolo da poter essere costruito in un paio di giorni (e sai cosa stai facendo). Possono risparmiare tempo per far funzionare qualcosa.

Ma non scalano.

Ciao, mi piace questa risposta in generale;Non ho detto che quello che hai scritto è un'esagerazione;la parte "grande progetto software" mi sembra ridondante e meglio eliminarla perché non c'è spiegazione a cosa intendi in generale o nello specifico.Grazie,
Ciao di nuovo, puoi leggere il mio messaggio di ricompensa, se lo desideri.Grazie,
@JohnDoea Non dimenticare che questo sito serve anche ad aiutare altre persone che _in futuro_ potrebbero avere fondamentalmente la stessa domanda, e potrebbero trarre vantaggio da parti diverse di una risposta.
Ciao, umilmente no;Non sono d'accordo solo con alcuni degli ultimi passaggi o con le sue frasi;oltre a quello che ho detto sulla definizione di un "grande" progetto;globali che di solito non vanno bene, potrebbero raramente andare bene non solo per la creazione di piccoli siti ma per "linguaggi di programmazione operativa" come Bash (inoltre, un costruttore di siti può lavorare lentamente per creare un piccolo sito, se esplora un nuovoCMS).Saluti.
Questa risposta sembra la migliore per affrontare la domanda specifica su "le variabili globali causano problemi di sicurezza".Penso che dovresti accettarlo.
LTPCGO
2019-09-03 05:20:59 UTC
view on stackexchange narkive permalink

Confronta le seguenti parti di codice:

1)

  /file.php: $ newconn = new PDO ('mysql : host = localhost; charset = utf8mb4; ',' username ',' password ');  

2)

  ../secrets.php: $ mysqlusername = 'nome utente'; $ mysqlpassword = 'password'; / file.php: require_once ('../ secrets.php'); $ newconn = new PDO ('mysql: host = localhost; charset = utf8mb4;', $ mysqlusername, $ mysqlpassword);  

3

  ../secrets.php: function pdoconn (i) {$ mysqlusername = ['username1', 'username2']; $ mysqlpassword = ["password1", "password2"]; $ conn = new PDO ('mysql: host = localhost; charset = utf8mb4;', $ mysqlusername [i], $ mysqlpassword [i]); return $ conn; } /file.php: require_once ('../ secrets.php'); $ newconn = pdoconn (0);  

L'esempio 1 è fuori discussione: una configurazione errata sui server di produzione potrebbe finire per mostrare parametri sensibili a parti non intenzionali.

Esempio 2 è migliore, ma quelle variabili sono disponibili in tutta l'applicazione e modificabili, il che potrebbe causare errori.

L'esempio 3 mantiene le cose molto organizzate e trasferibili.
Può essere modificato per usare le globali se ../ secrets.php invece era:

  ../secrets.php:$mysqlusername = 'username'; $ mysqlpassword = 'password'; function pdoconn () {$ conn = newPDO ('mysql: host = localhost; charset = utf8mb4;', $ GLOBALS ['mysqlusername'], $ GLOBALS ['mysqlpassword']); return $ conn;}  

E penso che questo dimostri perché un globale non ha senso il più delle volte in modo abbastanza succinto.


Riepilogo:

Per quanto riguarda le violazioni della sicurezza che utilizzano variabili globali (e perché ho scritto questi esempi in PHP), c'era (all'epoca) un cambiamento controverso in PHP 4.2.0 in cui register_globals era attivato spento. Non riesco a trovare alcun articolo ora, poiché questa modifica è stata apportata nel 2002, ma mi sembra di ricordare che all'epoca fosse responsabile di alcune violazioni. Copiando direttamente dal manuale, c'è un esempio molto chiaro di codice vulnerabile:

  <? Php // define $ authorized = true solo se l'utente è authenticatedif (authenticated_user ()) {$ authorized = true;} // Dato che non abbiamo prima inizializzato $ autorizzato come falso, questo potrebbe essere // definito tramite register_globals, come da GET auth.php? authorized = 1 // Quindi, chiunque può essere visto come autenticato! if ($ autorizzato) {include "/highly/sensitive/data.php";}?>  
Direi che anche il n. 3 è pessimo, perché la password è nel codice sorgente!Hai ancora gli stessi problemi con l'esposizione accidentale.Ottimo esempio alla fine però!
@Anders forse non è chiaro, dove devo tenere il file sullo stesso server, uso una funzione simile a questa al posto di avere solo una variabile con la password memorizzata in un file, poiché quando è inclusa è normalmente disponibile globalmente.Essenzialmente lo mantieni lo stesso di quello che penso tu stia suggerendo, ma invece di fare riferimento a una variabile quando è richiesto, invece chiami una funzione per restituire l'oggetto richiesto.
Il punto è che non dovresti affatto mantenere le password nel codice sorgente, anche se è in una funzione.
Sto dicendo che non è nel codice sorgente, ma si troverebbe in un file da qualche parte sul server che includi_once ().A meno che tu non stia parlando di non mantenere affatto la password sul server e invece di accedere alle credenziali tramite un'API, che sono d'accordo al 100% e mi propongo di fare in ogni situazione che possa essere fatta.
"L'esempio 1 mostra come una configurazione errata sui server di produzione potrebbe finire per mostrare valori di parametri sensibili a parti non intenzionali." Vuoi dire che entrambi i valori sarebbero visualizzati nelle stringhe di query?
@JohnDoea in alcuni linguaggi di scripting, se lo script fallisce su una certa riga, quella riga viene inviata all'utente stdout.Se la riga contiene una password, la password verrà inviata a stdout.
MechMK1
2019-09-03 13:47:16 UTC
view on stackexchange narkive permalink

Perché l'uso di variabili globali ti dà un sacco di problemi e non ha alcun vantaggio.

I valori globali rendono il tuo codice difficile da testare

Sebbene non direttamente correlato alla sicurezza, i test unitari sono vitali per lo sviluppo. E per eseguire correttamente un test unitario di qualcosa, è necessario essere in grado di controllare il contesto esatto in cui viene eseguito il codice. Guarda le due parti di codice:

With Globals

  public Money CalculateExpenses (int departmentId) {Department department = (from d in global_db .Departments dove d.Id = departmentId seleziona d) .Single (); return (da ex in department.Expenses selezionare ex) .Sum ();}  

Senza globali

  public Money CalculateExpenses (int departmentId, database database) {Department department = (da d in database.Departments dove d.Id = departmentId selezionare d) .Single (); return (da ex in department.Expenses seleziona ex) .Sum ();}  

Si potrebbe dire che il codice sembra quasi identico, tranne per la provenienza dei dati. Potresti anche pensare che il codice con Globals sia "più pulito", perché non devi passare il database ogni volta.

Fino a quando non dovrai scrivere uno unit test. Perché allora dovrai inserire una logica per non connetterti al database di produzione, ma piuttosto un database locale, magari specifico del test. Ora il codice non globale ha un aspetto molto migliore, perché puoi semplicemente passare il database che desideri utilizzare al codice.

In sintesi: il codice senza globali è più facile da testare .

Globali cambia comportamento se non cambi il codice

Se il tuo codice ha circa 200 righe di codice, l'uso di Globali non sembra poi così male. In effetti, potrebbe sembrare una cosa perfettamente valida da fare se riutilizzi lo stesso pezzo di codice ovunque (ad esempio qualche fonte di dati casuale, registrazione, ecc.)

Tuttavia, una volta che la base di codice cresce a sufficienza, l'introduzione delle variabili globali può essere assolutamente mortale. Perdi semplicemente il controllo sulla provenienza dei tuoi dati e su chi può accedervi.

Usiamo un esempio nella lingua preferita di tutti: PHP 5. Esempio di Eevee.

  @fopen ('http://example.com/not-existing-file', 'r');  

Cosa fa questo codice? Non lo sai, perché dipende dal comportamento globale. Se PHP è stato compilato con --disable-url-fopen-wrapper , non funzionerà. Lo stesso per la configurazione globale allow_url_fopen . Non sappiamo cosa farà.

@ all'inizio disabiliterà i messaggi di errore, a meno che scream.enabled non sia impostato nel campo globale Configurazione PHP. Inoltre non verrà stampato se il livello error_reporting globale non è impostato. La posizione esatta in cui verrà stampata, se viene stampata, dipenderà dal display_errors globale.

Quindi, come hai visto, il comportamento di una riga innocua dipende da 5 diverse variabili globali . Ora immagina questo scenario in una base di codice con un milione di righe e 100 programmatori diversi, tutti in team diversi, e vedrai rapidamente perché l'uso di Globals è abominevole e porta a tutti i tipi di problemi.

Immagina di andare a lavorare un giorno e il tuo codice si rompe improvvisamente, anche se non l'hai toccato. Questa è la magia di Globals.

Ci sono altri esempi del perché l'uso di Globals è cattivo, che può essere trovato nelle altre risposte.

Mister Amen
2019-09-03 13:03:07 UTC
view on stackexchange narkive permalink

Attacchi di overflow del buffer

Anche se abbastanza specifici per il linguaggio (vengono in mente C / C ++) e difficili da eseguire, sono un potenziale attacco.

Computerphile ha un ottimo video al riguardo, che consiglio vivamente, ma ecco una breve versione dei meccanismi di questi attacchi e di come interagisce con le variabili globali.

Si verifica un overflow del buffer quando i dati scritti in un buffer corrompono anche i valori dei dati negli indirizzi di memoria adiacenti al buffer di destinazione a causa di un controllo dei limiti insufficiente. Ciò può verificarsi quando si copiano i dati da un buffer a un altro senza prima verificare che i dati si adattino al buffer di destinazione. ( Wikipedia)

Nel caso delle variabili globali, il layout di memoria del tuo programma è abbastanza statico poiché (nella maggior parte delle lingue) avranno il loro segmento di memoria assegnato al programma inizio. Questo dà consistenza all'attaccante: è molto più facile prendere di mira la zona di memoria di un'area diversa quando si spara sempre dallo stesso punto (in caso di globali) rispetto a quando si è sempre in movimento tra i colpi.

Questo non è specifico per le variabili globali, ma contenere informazioni significative in tali strutture facilita (da non confondere con l'abilitazione!) questo tipo di attacchi.

Attenzione!

Sebbene le variabili globali potenzialmente presentino un leggero rischio per la sicurezza, se temi attacchi di buffer overflow, il tuo meccanismo di difesa di riferimento dovrebbe controllare la dimensione dell'input, non refactoring del codice per sbarazzarsi delle variabili globali.

Non vedo cosa abbia a che fare specificamente con le variabili globali.Puoi approfondire per favore?
Questi attacchi non sono causati direttamente dalle variabili globali di per sé, ma sono più facili da realizzare con le variabili globali, il cui slot di memoria viene assegnato all'avvio del programma, quindi quando le variabili sono più ristrette, rendendo gli slot di memoria assegnati meno prevedibili.Sono un nuovo collaboratore, quindi non so se dovrei incorporarlo nella risposta poiché varia in base alla lingua. Inoltre, non voglio dare a nessuno l'idea che il modo migliore per proteggere un'app da un attacco di overflow del buffer sia lo scoping variabile anziché la convalida della dimensione dell'input.
non c'è bisogno di riassumere le tue modifiche nel tuo post
Non hai sostenuto la connessione tra globali e BO.
Yakk
2019-09-03 22:56:53 UTC
view on stackexchange narkive permalink

Non ho mai avuto problemi con le variabili globali in Bash o JavaScript, molto probabilmente perché ho scritto solo piccoli script per uso personale su ambienti minimalisti.

Perché molti programmatori evitano di usare variabili globali e ci sono esempi di violazioni della sicurezza causate dall'uso di variabili globali?

In piccoli progetti le variabili globali vanno benissimo. La maggior parte dei loro problemi non si presentano. E la personalizzazione dell'ambiente Bash di cui sopra è davvero minuscola.

Le variabili globali iniziano a causare problemi mentre il tuo programma scala; il che può accadere in molti modi, ma la parte centrale del problema è la quantità di stato richiesta dalla comprensione di ogni parte di codice.

Immagina una base di codice di 10 milioni di righe . In esso ci sono 1 milione di variabili. Sono tutte globali.
In un dato pezzo di codice di 100 righe, potresti usare 20 variabili.
Ogni volta che chiami una funzione, non hai idea di quale di queste 20 variabili verrà modificata; quando la tua funzione viene avviata, non hai idea da dove provenga la variabile state.
Quindi, per capire cosa significano le tue 100 righe di codice, devi capire e tenere a mente tutti i 10 milioni di righe di codice, oppure una sorta di convenzione sulla provenienza dei dati, quali dati possono e non possono essere modificati quando chiami una funzione di supporto, ecc.

Al contrario, se il tuo codice è quasi interamente alimentato da argomenti di funzione, variabili locali e tipi restituiti, devi solo capire la tua funzione per capire cosa fa. Inoltre, se quella funzione chiama un'altra funzione, sai quali informazioni le stai passando e quali informazioni restituisce.
Potresti non sapere cosa fa con queste informazioni, ma sai cosa non fa .
Ad esempio, non può modificare intero x e ne sei certo, perché non hai passato x alla funzione, né le hai assegnato dal suo valore di ritorno!

Rendere il codice più facile da ragionare su localmente è un obiettivo molto importante. Vuoi essere in grado di leggere una funzione, sapere cosa sta facendo e identificare i bug.

Scrivere codice è molto più semplice e molto meno importante che creare codice chiaro e di facile ragionamento.
Quasi tutto il codice in un progetto ampio e persistente viene letto centinaia di volte più spesso di quanto non venga modificato e viene scritto e progettato una sola volta.
Da questa regola, rendiamo più facile ragionare a livello locale. raggiungere la regola di "evitare lo stato globale".

Variabile globale contro Super-oggetto

Le variabili globali che vengono lette / scritte sono un esempio di stato globale. Ma lo stesso può essere un superoggetto a cui ogni cosa nel progetto ha un puntatore a cui passare come primo argomento.

Un superoggetto ha ancora dei vantaggi rispetto alle variabili globali; le variabili globali spesso hanno meccanismi confusi su come vengono inizializzate e ripulite (ti sto guardando, C / C ++), e se hai un superoggetto con tutto il tuo stato "globale" puoi istanziare due versioni del tuo superoggetto ed eseguirli contemporaneamente nello stesso processo (questo tenderà a non funzionare, ma di solito è a causa di uno stato globale implicito che il sistema operativo ti impone).

Ogni variabile globale che leggi, invece di un parametro, significa che qualsiasi bit di codice , ovunque potrebbe modificarne il comportamento. Ogni variabile globale su cui scrivi significa che stai modificando il comportamento di un codice arbitrariamente lontano.

E non sono solo gli umani a trovare gli stati globali un dolore; se il tuo stato è locale, scrivere test imbriglia che "fingere" uno stato o ambiente globale diventa molto più semplice. Se c'è (diciamo) un oggetto "mouse" globale, scrivere un test unitario che crea un mouse falso che finge di fare un certo movimento diventa più difficile, potrebbe anche essere più difficile scrivere una macro che riproduce un movimento del mouse registrato in un codice, soprattutto se intendi farlo mentre l'interfaccia utente rimane sensibile all'effettivo essere umano che utilizza un mouse.

Sicurezza

La sicurezza è una funzione della comprensione di ciò che fa il tuo codice. Sicurezza, all'interno di un programma, significa "il tuo codice fa solo ciò che dovrebbe essere autorizzato a fare"; con le variabili globali, hai una capacità più debole di capire cosa fa il codice, quindi meno capacità di controllare ciò che fa.

Steve Sether
2019-09-05 05:31:28 UTC
view on stackexchange narkive permalink

Dal punto di vista della sicurezza, il problema con le variabili globali è che possono creare comportamenti imprevisti e interrompere la localizzazione. L'idea più generale alla base di questo si chiama "Azione a distanza", dove una parte di un programma può avere un effetto inaspettato su un'altra.

Poiché la localizzazione non funziona, invece di dover capire solo una parte del programma, tu e chiunque lavori con il programma ora dovete capire qualsiasi parte del programma che potrebbe coinvolgere la vostra variabile globale. Ciò aumenta notevolmente la complessità del progetto e, in generale, i progetti complessi hanno maggiori probabilità di essere bacati e quindi insicuri. Come disse una volta gli informatici Edsger Dijkstra "Il programmatore competente è pienamente consapevole delle dimensioni strettamente limitate del proprio cranio".

I programmi tendono a crescere con il tempo in termini di dimensioni e portata. Anche se il tuo semplice script, creato isolatamente ora fa solo una cosa senza modularità, potrebbe essere riutilizzato da qualche altra parte in futuro dove potresti aver dimenticato le brutte implicazioni delle variabili globali, o peggio, te ne sei andato e nessuno sa nemmeno che contiene variabili globali. Le variabili globali sono come lasciare buchi nel terreno, rastrelli rivolti nella direzione sbagliata pronti per essere calpestati o chiodi nel tuo vialetto.

Sono, per molti versi, in pericolo imminente e, sebbene a volte necessari, dovrebbero essere trattato come tale.

juhist
2019-09-03 23:05:13 UTC
view on stackexchange narkive permalink
Perché molti programmatori evitano di utilizzare variabili globali e ci sono esempi di violazioni della sicurezza causate dall'utilizzo di variabili globali?

Perché è più facile modificare codice che non utilizza variabili globali da eseguire in applicazioni non intenzionali , applicazioni che lo sviluppatore originale non aveva previsto. In realtà, se dipendi dallo stato globale, puoi avere al massimo uno di questi stati in un'applicazione senza un refactoring intensivo (che farebbe il refactoring dello stato globale).

Tali applicazioni non intenzionali potrebbero includere l'esecuzione del codice in ambienti multi-thread.

Tuttavia, ciò che molte persone non riescono a realizzare: malloc () è globale!

Lo stesso le persone che sostengono di non utilizzare le variabili globali usano sempre uno stato dell'allocatore globale.

Ciò significa che se una parte del tuo codice alloca molta memoria, malloc () richiede di più memoria dal sistema operativo, i blocchi di memoria si confondono con quelli allocati da altri pezzi del tuo codice, e quando lo stesso pezzo di codice libera tutta la memoria che stava usando, free () chiama non restituire la memoria al sistema operativo a causa della frammentazione. Il risultato finale è che il tuo programma finisce per utilizzare più memoria di quanto dovrebbe.

Quindi, proprio le persone che sostengono di non usare le variabili globali, stanno in realtà usando un allocatore con uno stato globale.

Mi chiedo perché nessuno degli standard delle principali organizzazioni di standardizzazione (C89 / C99 / C11 / C18 da ISO, POSIX da IEEE) abbia definito un allocatore che consente di avere più stati allocatori, cioè heap indipendenti.

Stai sollevando un punto valido con "malloc".Penso che quei linguaggi con "malloc", ad es.C o C ++, non sono comunque sicuri.Qualsiasi aritmetica del puntatore, che potrebbe sembrare genuina in superficie, potrebbe infatti contenere un bug e causare un comportamento indefinito nell'intero programma.Suppongo che le applicazioni di sandboxing come i browser utilizzino in effetti più heap, se non semplicemente a causa di più processi.
Dehbop
2019-09-04 02:28:14 UTC
view on stackexchange narkive permalink

Se quasi ogni linguaggio di programmazione può dichiarare una variabile a livello globale, accessibile solo nell'ambito del suo codice di implementazione, allora questo non è un problema. Non ci sono molte ragioni per usare variabili globali.

Tuttavia, non è così, motivo per cui quando mi sono ritrovato a scrivere i miei progetti in C & non in C ++, dove è naturalmente supportata come variabile statica alla clausola più esterna di una definizione di classe, ho dovuto accontentarmi delle variabili globali.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 4.0 con cui è distribuito.
Loading...