SORU
20 Mart 2010, CUMARTESİ


Nasıl sadece "meşru" kullanır setAccessible sınırlamak için?

Daha fazla java.lang.reflect.AccessibleObject.setAccessible, Daha şaşırttı gücü hakkında öğrendim ne olduğumu. Bu soruya cevabım (Using reflection to change static final File.separatorChar for unit testing) uyarlanmıştır.

import java.lang.reflect.*;

public class EverythingIsTrue {
   static void setFinalStatic(Field field, Object newValue) throws Exception {
      field.setAccessible(true);

      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, newValue);
   }
   public static void main(String args[]) throws Exception {      
      setFinalStatic(Boolean.class.getField("FALSE"), true);

      System.out.format("Everything is %s", false); // "Everything is true"
   }
}

Gerçekten çok çirkin şeyler yapabilirsiniz:

public class UltimateAnswerToEverything {
   static Integer[] ultimateAnswer() {
      Integer[] ret = new Integer[256];
      java.util.Arrays.fill(ret, 42);
      return ret;
   }   
   public static void main(String args[]) throws Exception {
      EverythingIsTrue.setFinalStatic(
         Class.forName("java.lang.Integer$IntegerCache")
            .getDeclaredField("cache"),
         ultimateAnswer()
      );
      System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42"
   }
}

Muhtemelen API tasarımcılar nasıl abusable setAccessible olabileceğinin farkında, ama meşru kullanır olduğunu sağlamak için kabul etti olmalıdır. Bu yüzden benim sorular şunlardır:

  • setAccessibleiçin gerçekten meşru kullanım alanları nelerdir?
    • Java ilk etapta bu gereksinim için tasarlanmış olabilir mi?
    • Bu tasarım olumsuz sonuçlarını (varsa) ne olurdu?
  • Meşru kullanımlar için setAccessible kısıtlayabilir misiniz?
    • Sadece SecurityManager?
      • Nasıl çalışır? /Kara, parçalı yapı, vb beyaz?
      • Uygulamalarınızda yapılandırmak için ortak mı?
    • Derslerimi setAccessiblegeçirmez SecurityManager yapılandırma ne olursa olsun yazabilirim?
      • Ya yapılandırmasını yönetir kim insafına mıyım?

Daha önemli soru şu sanırım: BU KONUDA ENDİŞELENMENİZE GEREK var MI???

Derslerimi hiçbiri ne-so-ever uygulanabilir mahremiyetinizi. Singleton deseni (kenara yararları konusunda şüpheler koyarak) şimdi imkansız zorlamak için. Haritayı benim yukarıda parçacıkları gibi, hatta nasıl Java temel eserlerin bazı temel varsayımlar bile garanti altına alınmasına bulunur.

BU SORUNLAR GERÇEK DEĞİL Mİ???


Tamam, ben sadece teyit: setAccessible sayesinde dizeleri JavaDEĞİLdeğişmez.

import java.lang.reflect.*;

public class MutableStrings {
   static void mutate(String s) throws Exception {
      Field value = String.class.getDeclaredField("value");
      value.setAccessible(true);
      value.set(s, s.toUpperCase().toCharArray());
   }   
   public static void main(String args[]) throws Exception {
      final String s = "Hello world!";
      System.out.println(s); // "Hello world!"
      mutate(s);
      System.out.println(s); // "HELLO WORLD!"
   }
}

Bu BÜYÜK bir endişe kaynağı olduğunu düşünen bir tek ben miyim?

CEVAP
22 Mart 2010, PAZARTESİ


BU KONUDA ENDİŞELENMENİZE GEREK VAR MI???

Bu tamamen ne tür bir mimarlık için yazdığını bağlıdır.

Eğer yazılım bir bileşeni dünyadaki insanlar için foo.jar adı dağıtmak istiyorsanız, onların elinde zaten tamamen sensin. Senin içindeki sınıf tanımlarında değişiklik olabilir .jar (mühendislik veya doğrudan ters bayt kodu manipülasyon yoluyla). Kendi JVM, vb kod çalıştırabilir. Bu durumda endişe size bir yararı olmaz.

Sadece HTTP üzerinden insanlar ve sistemleri arayüzü ile web uygulaması yazıyorsunuz ve uygulama sunucusu varsa, aynı zamanda bir endişe değil. Emin sizin şirkette adam kodlayıcıları singleton deseni keser, ama eğer gerçekten istiyorsan sadece kod oluşturabilir.

Gelecekteki işinizi Sun Microsystems'ın/Oracle kod yazma ve çekirdek ya da diğer Java güvenilir bileşenleri için kod yazma ile görevli iseniz, bilmeniz gereken bir şey var. Endişe, ancak, sadece saçlarını kaybetmek yapacaktır. Herhangi bir durumda muhtemelen iç belgeleri ile birlikte Secure Coding Guidelines okuma yaparlar.

Eğer Java uygulamaları yazmak için gidiyoruz eğer, güvenlik çerçevesinin farkında olması gereken bir şeydir. İmzasız uygulamaları setAccessible aramak için çalışıyorum, bir SecurityException neden olur.

setAccessible geleneksel bütünlüğünü kontrol eder dolaşan tek şey değil. Non-API, çekirdek bir Java sınıf güneş denilen bir yer var.mısc.Güvensiz doğrudan bellek erişim dahil olmak üzere, istediği her işte çok fazla bir şey yapamam. Yerel kod (JNI) kontrolü de gidebilir.

Korumalı bir ortamda (örneğin Java, JavaFX), her sınıf izinleri bir dizi var ve Güvensiz, setAccessible ve tanımlama yerel uygulamalar için erişim SecurityManager tarafından kontrol edilir.

"Java erişim değiştiricileri bir güvenlik mekanizması amacında değildir."

Çok fazla Java kodu çalıştırılıyor bağlıdır. Java dersleri çekirdek sanal zorlamak için bir güvenlik mekanizması olarak erişim değiştiricileri kullanın.

SetAccessible için gerçekten meşru kullanım alanları nelerdir?

Java temel dersleri güvenlik nedeniyle gizli kalmak access şeyler için kolay bir yol olarak kullanabilirsiniz. Örnek olarak, Java Seri hale getirme çerçeve nesneleri kaldırmada özel nesne kurucular çağırmak için kullanır. Birisi Sistemi bahsetti.setErr, ve iyi bir örnek olurdu, ama yöntemleri setOut/setErr/setİn sınıf Sistemi son alanın değerini ayarlamak için yerel kod kullanımı ilginçtir.

Başka bir açık yasal kullanım nesneleri içi içine peek gereken çerçeveler (dayanıklılık, web çerçeveleri, enjeksiyon).

Hata benim görüşüme göre, onlar normalde aynı JVM sürecinde kaçma, ama JVM diğer araçlar (JPDA) kullanarak yerine arabirim olarak bu kategoriye girer, yok.

Java ilk etapta bu gereksinim için tasarlanmış olabilir mi?

İyi cevap için çok derin bir soru. Evet düşünüyorum, ama tercih olmayabilir başka bir mekanizma(lar) eklemek gerekir.

Meşru kullanımlar için setAccessible kısıtlayabilir misiniz?

Uygulayabilirsiniz düz ileri OOTB en kısıtlama SecurityManager ve setAccessible sadece kod bazı kaynaklardan gelen izin ver. Bu Java zaten bunu yapıyor - JAVA_HOME gelen standart Java sınıfları foo.com imzasız uygulama sınıfları setAccessible yapmaları yasak iken setAccessible yapmak için izin verilir. Bir ya da fazla ya da daha önce değil, bu izin bir ikili olduğunu ifade etti. Diğerleri izin vermeme ederken bazı alanları/yöntemleri değiştirmek için setAccessible izin vermek için belirgin bir yolu yoktur. Sen elinden SecurityManager kullanarak, ancak, tamamen belirli paketleri başvuran sınıfları, veya yansıma olmadan izin vermemek.

Derslerimi setAccessible geçirmez SecurityManager yapılandırma ne olursa olsun yazabilirim? ... Ya da yapılandırmasını yönetir kim insafına mıyım?

Sana kesinlikle.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ash100HD

    Ash100HD

    29 EKİM 2011
  • Justin Schenck

    Justin Schen

    24 Kasım 2006
  • WOSU Public Media

    WOSU Public

    23 AĞUSTOS 2007