Zum Ende der Metadaten springen
Zum Anfang der Metadaten

Sie zeigen eine alte Version dieser Seite an. Zeigen Sie die aktuelle Version an.

Unterschiede anzeigen Seitenhistorie anzeigen

« Vorherige Version anzeigen Version 3 Nächste Version anzeigen »

Dieser Artikel beschreibt, wie Implementierungen von DocumentDataProvidern gehärtet werden können, um die Anzeige beliebiger Dokumente im Dateisystem des verwendeten Applikationsservers zu unterbinden.

Hintergrund

Das serverseitige Laden von Dokumenten erfolgt im jadice web toolkit über kundenspezifische Implementierungen des DocumentDataProvider-Interfaces. Teil der Distribution des jadice web toolkits sind diverse Demoanwendungen, die Kunden als Vorlage für ihre eigene, integrierende Anwendung dienen können. Bestandteil der Demoanwendungen sind Beispiel-Implementierungen von DocumentDataProvidern, die von Kunden als Vorlage für eigene spezifische Implementierungen genutzt werden können. Einige dieser Beispiel-Implementierungen extrahieren den Identifikator des zu ladenden Dokuments aus einer URL, die vom Browser an den Server geschickt wird. Aufgrund einer unzureichenden Prüfung dieser URL in den betroffenen Beispielimplementierungen, kann der Browser durch die Übermittlung einer präparierten URL das Laden einer beliebigen Datei im Dateisystem des Servers anstoßen (vorausgesetzt der Benutzer des Applikationsservers besitzt Leseberechtigung auf diese Datei).

In manchen Anwendungsfällen wird eine clientseitige Javascript API exponiert, über die der Identifikator des zu ladenden Dokuments von einer anderen Browseranwendung gesetzt werden kann. Die zugehörige exponierte Funktion kann dann auch über die Browserkonsole aufgerufen werden, um eine präparierte URL an den Server zu übertragen.

Betroffene Implementierungen

Betroffen sind die folgenden Implementierungen aus dem Package "com.levigo.jadice.web.demo.common.server.dataprovider"

  • UrlDocumentDataProvider
  • UrlRelativeDataProvider

Falls eine kundenspezifische Implementierung auf einer dieser beiden Beispielimplementierungen aufbaut, sollte eine Anpassung gemäß des folgenden Abschnitts erfolgen. 

Lösung

Um das Laden von Dateien aus dem Dateisystem des Applikationsservers zu unterbinden, kann die übermittelte URL serverseitig geprüft werden. Falls das Format der URL nicht der Erwartung entspricht, wird der Ladevorgang abgebrochen.

Codestellen

Eine angepasste Implementierung für die Klasse UrlDocumentDataProvider könnte folgendermaßen aussehen:

 

...

public class UrlDocumentDataProvider extends SimpleDocumentDataProvider<UrlSource, UrlHandle> {

  ...

  protected Provider<InputStream, IOException> get(final String url) {
    return new Provider<InputStream, IOException>() {
      @Override
      public InputStream get() throws IOException {
        URL u = new URL(url);
        check(url);
        return u.openStream();
      }
    };
  }

  /**
   * Checks if the input is being abused by replacing the scheme.
   * 
   * @param url the url to be checked
   * @throws RuntimeException if the input was poisoned
   */
  protected void check(String url) {
    Pattern p = Pattern.compile("^\\w*:");
    Matcher m = p.matcher(url);
    if (m.find()) {
      if (!(url.startsWith("http") || url.startsWith("https") || url.startsWith("ftp"))) {
        throw new RuntimeException("Inputforgery: A poisoned request was received: " + url);
      }
    }
  }
}

 

Eine angepasste Implementierung für die Klasse UrlRelativeDocumentDataProvider könnte folgendermaßen aussehen:

...

public class UrlRelativeDataProvider extends SimpleDocumentDataProvider<RemoteIDSource, RemoteIDHandle> {

  ...

  protected Provider<InputStream, IOException> get(final String id) {
    return new Provider<InputStream, IOException>() {
      @Override
      public InputStream get() throws IOException {
        URL u;
        try {
          // Avoids poisioning the URI
          checkForInputPoisoning(id);

          u = baseURL.toURI().resolve(id).toURL();
          return u.openStream();
        } catch (URISyntaxException e) {
          throw new IOException(e);
        }
      }
    };
  }

  /**
   * Checks if the input is being abused by replacing the scheme.
   * 
   * @param input the input poisoned
   * @throws RuntimeException if the input was poisoned
   */
  private void checkForInputPoisoning(String input) throws RuntimeException {
    Pattern p = Pattern.compile("^\\w*:");
    Matcher m = p.matcher(input);
    if (m.find())
      throw new RuntimeException("Inputforgery: A poisoned request was received: " + input);
  }
}

Nach Stichwort filtern

Derzeit gibt es keine Elemente mit den ausgewählten Stichwörtern.

  • Keine Stichwörter