Newsgroup: it.comp.www.php
Titolo: Rendere 'sicuro' un sistema di moduli/plugins.

..ed eccomi di nuovo ;)
Stò realizzando (bhè sono ancora in fase di progettazione)
un'applicazione con un singolo core (scripts php), e un database per
ogni cliente.
Quindi, i codice che farà girare l'applicazione è uno per tutti, ma
per ogni utente che si registra creo un nuovo db e db user (o meglio,
creo un nuovo schema, visto che utilizzo postgres.. ah dimenticavo,
ambiente linux (debian attualmente)).
Fin qui niente di complicato, ma vorrei dare ad altri sviluppatori la
possibilità di creare moduli/plugin per estendere le funzionalità base
dell'applicazione, e quando un utente vuole attivare un certo modulo
aggiuntivo dovrà acquistarlo direttamente dallo sviluppatore
(logicamente creerò delle classi PHP apposta per gli sviluppatori,
farò il massimo perchè siano ben documentate, e lo sviluppatore
dovrebbe utilizzare solo quelle classi, a mò di API).
Questa è l'idea, ora vi spiego come pensavo di realizzarla:
Tutti i plugin saranno caricati su una cartella unica, e per ogni
utente controllo quali plugin ha attivato e nei vari script principali
richiamo le funzionalità dei plugin (pensavo di fare una cosa tipo il
sistema di hook_ che utilizza ad esempio Drupal).
Potrete capire che caricare script scritti da altri sul mio server
presenta non poche problematiche a livello di sicurezza, ed è per
questo che sono qui ;).
Qui trovate un'esempio di come ho pensato di fare: 
http://pastie.org/769409
(lo metto su pastie perchè google group formatta da schifo ;)
La mia domanda è: come faccio a fare in modo che il codice dentro i
plugin non faccia danni?
Nel senso, sicuramente controllerò personalmente il codice di ogni
plugin, ma qualcosa potrebbe sfuggirmi, e voglio evitare casini sia a
livello server, sia a livello utente.
Tipo, per far si che all'interno del plugin lo sviluppatore non possa
collegarsi al DB direttamente, ma debba usare le classi che fornirò,
ho pensato a una cosa del genere (che funziona): 
http://pastie.org/769428
In quel modo posso controllare i tipi di query, le informazioni
recuperate etc... (certo, è una delle misure di sicurezza per il db).
Ma come posso difendermi da alte cose?
Cioè, evitare che un plugin mi legga il contenuto delle cartelle e mi
cancelli file a caso, o robe del genere?
Con runkit o apd è possibile rinominare alcune funzioni, potrei quindi
rinominare la funzione unlink in pincopalla_unlink, e lo sviluppatore
non potrà più usarla (non sapendo il nome), ma non posso certo
rinominare tutte le funzioni pericolose (anche perchè, se uno vuole
fare dei danni praticamente tutte le funzioni sarebbero pericolose,
questo mi salverebbe al massimo da sviluppatori 'maldestri' in buona
fede, non da sviluppatori che hanno la volontà di fare danni).
Qualcuno mi ha accennato alle sandbox, ma non sò bene cosa sono e come
funzionano..
C'è un modo di far si che tutto quello che accade negli script dei
plugin sia 'limitato'?
Voi come gestireste la cosa?
Ho pensato anche di usare delle API, ma questo farebbe si che quando
chiamo il plugin faccio delle richieste HTTP (curl?), il plugin fà i
cavoli suoi (a questo punto magari su un altro server/virtual host), e
alla fine mi risponde con un output (xml, json, bho).
Però questo sistema avrebbe il problema che se il plugin ha bisogno di
recuperare altre informazioni oltre a quelle che gli passo nella
richiesta (nell'esempio degli articolo, mettiamo che debba sapere
anche qual'è l'ultimo articolo creato prima di quello attuale),
dovrebbe fare delle richieste API per recuperale... decuplicherei le
richieste al server, e ciò non mi piace (ma sarebbe senz'altro il
metodo più sicuro, perchè controllerei al 100% quel che accade nel mio
server)
Ogni suggerimento o idea sono ben accette!!

ma non posso certo rinominare tutte le funzioni pericolose
Perche' no? Il codice e' praticamente sempre lo stesso: le funzioni vanno
ad agire su file, memoria, database e altre due o tre cose. E quindi sono
cinque o sei i controlli che devi fare. Se vanno bene, prosegui chiamando
la funzione originale.
Non so se possa funzionare, non ho controllato.
Leonardo "per� ora ci do un occhio"
-- 
The cock doth craw, the day doth daw,
the channerin' worm doth chide:
gin we be mist oot o' oor place,
a sair pain we maun bide.

 la funzione originale.
Forse ho frainteso o non ho capito bene quello che intendi dire.. cioè
è possibile con runkit dire 'bom, da adesso in poi qualunque funzione
che cerca di eliminare un file che non è all'interno di una cartella
definita, bloccala'.
Mi faresti un'esempio?
Altra cosa, è possibile prima di chimare i vari hook_ modificare i
settaggi tramite ini_set, e far si che dopo invece non sia più
possibile?
Cioè, prima di chimare un hook con ini_set modifico alcuni parametri,
ma se all'interno del plugin uno usa ini_set dovrebbe fallire.
Certo, potrei anche rinominare la funzione ini_set prima di chiamare
gli hook, ma io intendo far si che il codice del plugin non abbia il
'permesso' di usare ini_set, o qualcosa del genere..
Come avrai capito sono un pò confuso sul da farsi e sopprattutto su
quale sia il metodo migliore di fare quel che devo fare ;)

esterno non s� il nuovo nome
...forse :-), ma se lo scopre?
Leonardo


 ...forse :-), ma se lo scopre?
Sono morto ;)
Mhà, forse mi conviene testare anche l'idea di utulizzare il sistema
API.
Faccio girare i plugin su lighttpd, proxandolo da apache (in modo da
non stressare troppo apache, evitando anche di dargli troppe
connessioni), e la configurazione di PHP su lighttpd la gestisco come
mi pare e piace.
Mi spaventa solo il fatto che se un suddetto plugin/modulo è un pò
complesso, ci mette un attimo a farmi 100 richieste avanti e indietro
tra apache e lighttpd (mettiamo che uno sviluppa un modulo simile a
Views per drupal, un massacro!)
O forse l'unica vera soluzione è che mi metta il cuore in pace e
controlli riga per riga il codice di ogni modulo (che però se il
progetto ha un minimo di successo e cominciano ad esserci un numero
decente di moduli, controllarne il codice ogni volta, anche per i vari
aggiornamenti, è impensabile secondo me)
Tu personalmente come la gestiresti la cosa?

Tu personalmente come la gestiresti la cosa?
Lighthttpd, e i vari plugin girano con moduli FastCGI usando sessioni
indipendenti da quelle dell'applicazione principale. Ogni modulo deve
essere costituito da un "manifest" che descrive a quali funzioni puo'
o vuole registrarsi (XML visto che fa fico) e una directory tutta sua
dove fa quel che vuole.
Se il plugin ha bisogno di fare per esempio una query, si connette al
plugin che fa le query e gli manda la query medesima... c'e' un certo
rallentamento, ma il sistema scala piuttosto benino.
In pratica, sostituisci le chiamate a funzione con chiamate di rete.
Il vantaggio rispetto a runkit e' che e' piu' portabile, e molto piu'
controllabile. Lo svantaggio e' che va un po' piu' piano, pero' credo
che si possa prevedere fin dall'inizio un sistema per "suddividere" i
plugin su piu' server.
Leonardo (ci dovrei pensare su a lungo :-) )


 
altra cosa sono i permessi agli utenti.....

 altra cosa sono i permessi agli utenti.....
Già, l'accesso alle folder, etc...
Usando le API (magari proprio su un altro server, in modo che sia
indipendente al 100%), avrei la certezza della sicurezza: gli
sviluppatori fanno quello che vogliono su un server da battaglia
(magari i plugin li hostano sui loro server, chissenefrega), e con le
api tutto lo gestisco a mo di richiesta.
Se la richiesta non và bene, non faccio niente, e bom.
Ma credo che rallenterebbe un sacco il tutto e triplicherebbe le
richieste http, banda, etc.