Domanda

Parte della nostra applicazione Java deve eseguire JavaScript scritto da non sviluppatori.Questi non sviluppatori utilizzano JavaScript per la formattazione dei dati.(Principalmente logica semplice e concatenazione di stringhe).

La mia domanda è come posso impostare l'esecuzione di questi script per assicurarmi che gli errori di scripting non abbiano un impatto negativo importante sul resto dell'applicazione.

  • Necessità di proteggersi da cicli infiniti
  • Proteggiti dalla generazione di nuovi thread.
  • Limitare l'accesso ai servizi e all'ambiente
    • File system (esempio:Se uno sceneggiatore scontento decidesse di eliminare i file)
    • Database (la stessa cosa elimina i record del database)

Fondamentalmente devo impostare l'ambito JavaScript in modo che includa esattamente solo ciò di cui hanno bisogno e non altro.

È stato utile?

Soluzione

Per proteggersi da cicli infiniti, dovresti inserirlo in un processo separato in modo che possa essere ucciso.

Per evitare la creazione di thread, dovresti estendere SecurityManager (l'implementazione predefinita consente al codice non attendibile di accedere a gruppi di thread non root).

La sicurezza Java consente di impedire l'accesso al file system.

Per le restrizioni del database, potresti essere in grado di utilizzare la sicurezza utente SQL standard, ma è piuttosto debole.Altrimenti, devi fornire un'API che applichi le tue restrizioni.

Modificare:Dovrei sottolineare che la versione di Rhino fornita con JDK6 ha subito un lavoro di sicurezza, ma non include il compilatore.

Altri suggerimenti

Per proteggersi da cicli infiniti, è possibile osservare il conteggio delle istruzioni durante l'esecuzione dello script (funziona solo con script interpretati, non con quelli compilati).

C'è questo esempio nei JavaDocs di Rhino per impedire l'esecuzione di uno script per più di dieci secondi:

 protected void observeInstructionCount(Context cx, int instructionCount)
 {
     MyContext mcx = (MyContext)cx;
     long currentTime = System.currentTimeMillis();
     if (currentTime - mcx.startTime > 10*1000) {
         // More then 10 seconds from Context creation time:
         // it is time to stop the script.
         // Throw Error instance to ensure that script will never
         // get control back through catch or finally.
         throw new Error();
     }
 }

Per bloccare l'accesso alle classi e ai metodi Java, dai un'occhiata a...

http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

Mi sono appena imbattuto in questo post del blog che sembra essere utile per il sandboxing di più o meno qualsiasi cosa (non solo Rhino):

http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

Se stai cercando solo funzioni JavaScript pure, ecco una soluzione basata sulla libreria Rhino incorporata JDK senza importare librerie di terze parti:

  1. Scopri il nome della classe di fabbrica del motore di script JavaScript tramite ScriptEngineManager#getEngineFactories
  2. Carica la classe factory del motore di script in un nuovo caricatore di classi, in cui JavaMembers o altre classi correlate verranno ignorate.
  3. Chiama #getScriptEngine sul factory del motore di script caricato ed eval script sul motore di script restituito.

Se lo script specificato contiene script Java, il caricatore di classi tenterà di caricare JavaMembers o altre classi e attiverà le eccezioni di classe non trovata.In questo modo, gli script dannosi verranno ignorati senza essere eseguiti.

Per ulteriori dettagli leggere i file ConfigJSParser.java e ConfigJSClassLoader.java:

https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config

Javascript è a thread singolo e non può accedere al filesystem, quindi non penso che tu debba preoccuparti di quelli.Non sono sicuro che esista un modo per impostare un timeout per proteggersi da loop infiniti, ma potresti sempre generare un thread (Java) che esegue lo script e quindi interrompere il thread dopo così tanto tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top