Estava utilizando um biblioteca chamada Xstream que manipula classes e transforma em XML, nela existe alguns conceitos de classes que é aconselhado bloquear para evitar que exista inserção de eventos por XML.
Minha duvida é a seguinte, se eu libera-se todas as classes mas pegasse essa classe (objeto principal) e isola-se em uma variável só o fato da variável estar ali mesmo se ser chamada ela pode ser inicializada?
//Exemplo
Objeto obj = xstream.fromXML(xml);
//Minha duvida é se eu o objeto recebido for qualquer classe e depois de o objeto da classe ser gerado pelo xstream já seria executado ou precisaria ser ativado em alguma segunda chamada.
//Lembrando que estou perguntando das classes nativas do java, porque classes criadas por 3 não existiria o modelo na biblioteca no projeto para serem criado.
if(obj.class == MinhaClasse.class){
//Só continua se for uma classe valida
}
oi?
vc pode dar um exemplo mais concreto?
Não descrevi como funciona a classe por ser muito conhecida, mas essa classe xstream cria um objeto do tipo Xstream onde esse objeto pede que você insira no objeto Xstream um objeto qualquer, esse objeto inserido no xstream sera percorrido, e lido e todos os objetos internos desse objeto tambem serão lido até que não haja mais objeto ou vire somente tipos primitivos.
Assim se crio um objeto que conteria alguns strings internos somente é lido os string internos do objeto criado .
Ex: MeuObjeto mo = new MeuObjeto();
Se o objeto mo possuir objetos como variavel, tipo um objeto pessoa que tenha um objeto do tipo casa como variavel interna.
Se mandasse o xstream ler o objeto pessoa, durante a execução o xstream leria tambem o objeto interno chamado casa na procura das versões mais primitivas para criar a versão xml correspondente a arvore de relação das classes
Até ai tudo bem porque fui eu que inseri a classe no xstream, porem a figura muda de proporção quando peço para o sxtream trabalhar inversamente.
Quando mando o Xtream ler um Xml e retornar as classes resultados o retorno do xstream é um objeto do tipo Object, minha duvida é se na hora que o xstream ler e gerar a variavel Object com uma classe desconhecida contida dentro da boblioteca nativa do java, por exemplo.
O a pessoa criou um xml uma classe tipo jframe e ja deixou as configurações internas da classe ativa para execultar, acredito que quando o xstream lê o texto para retornar o objeto ele cria o objeto, e depois insete os valores da variavel, se no xml existir uma classes de evento executavel so de criar essa classe com os valores internos dela ja setados ela seria capas de executar? Se sim quais classes da biblioteca nativa do java tem essa capacidade
Digamos que criei minhas classes com valores primitivos e outros valores de objeto,
cara eu ainda não entendi totalmente mas vc ja tentou fazer isso?
pq me parece o caso onde vc cria um xml e manda a biblioteca trabalhar, e ai descobre se funciona ou não
Na verdade, fosse uma classe que estou chamando que eu criei não tem problema disso acontecer porque é esperado.
Minha duvida é caso alguem altere o xml de entrada e coloque alguma função de evento como objeto mapiado xml, por isso estou perguntado se é possivel isso acontecer so de criar e inicializar alguma das classes nativas do java, porque não conheço nenhuma que faz isso, fiquei sabendo dessa brecha lendo sobre segurança do xtream.
Mas minha duvida não é se é possivel fazer isso quero sabe se nas classes nativas do java existe alguma classe que permitiria um tipo de inserção desses só de criar o objeto
O que você quer dizer com essa frase?
Posta o artigo que você leu.
Que tipo de inserção?
[quote=“staroski, post:7, topic:376164, full:true”]
O que você quer dizer com essa frase?
Após gerar um arquivo XML esse arquivo fica em um diretório no sistema, se de alguma forma esse arquivo for trocado por um terceiro, e meu programa tentar ler esse XML pela classe Xstream, a classe vai tentar a montar os objeto que originaram o XML, se esses objetos forem nativos do java ou seja classes da biblioteca nativa, uma pessoa ma intencionada poderia chamar objetos nativos já configurados, java.util.String, entre outros das bibliotecas nativa, lembrando que entre as bibliotecas nativas existem classes que servem para auto-executar.
Quando digo mapeia o objeto significa que a classe xtream percorre pelo objeto procurando as classes que estão definidas na biblioteca do projeto, que seriam as classes criadas especificamente para o projeto e a biblioteca nativa do java tipo java.IO, Java.util entre as outras,
poderia po exemplo cria uma xml mais ou menos assim
<model.JFrame>
true
//… configurações da janela salva
// … objeto display todos configurado montado pelo aplicativo usando apenas classes nativas
</model.JFrame>
O de cima seria mais ou menos um conseito de comando de injeção mas nesse caso é um objeto visual, acredito que exista classes objeto que poderiam ser geradas sem a necessidade de uma classe visual e que se auto executem apenas de serem criadas e setadas pelo xstream.
Quanto ao artigo esta Aqui
Quero sabe se algum classe so de ser aberta e configurada poderia se executar em paralelo aos processos do meu aplicativo, tipo um runnabler ou iframe.
Minha duvida surgiu quando percebi que esse processo de criar objetos sem validar o modelo do objeto poderia cria objetos auto executáveis que poderia conter comandos maliciosos, por isso queria saber as classes mais perigosas para sempre estar monitorando essas classes
Bem de qualquer jeito resolvi proteger de um jeito diferente:
Chamadas da leitura XML:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import modellist.convertClassInNull;
import modellist.convertObjectInNull;
public class xml {
public static String create(Object obj){
//Inicia o XML
XStream xstream = new XStream(new DomDriver());
xstream.addPermission(AnyTypePermission.ANY);
xstream.registerConverter(new convertClassInNull());
xstream.registerConverter(new convertObjectInNull());
//Configurações
//----------------------------------------------
String xml = xstream.toXML(obj);
return xml;
}
public static Object reader(String xml, Class modelName){
return reader(xml, modelName.getName());
}
public static Object reader(String xml, String modelName){
String verificator = xml;
while((int)verificator.charAt(0)!=(int)'<'){
if(verificator.length()<2){
return null;
}
verificator = verificator.substring(1);
}
//Remove o '<'
verificator = verificator.substring(1);
//garante que leu seja minuscula
verificator = verificator.toLowerCase();
modelName = modelName.toLowerCase();
//Evita que classes não desejadas sejam iniciadas esse metodo apenas protege a primeira chamada do xml
//passa por todas as letras do nome do modelo
for(int cont = 0; cont<modelName.length() ; cont++){
if((int)modelName.charAt(cont) != (int)verificator.charAt(cont)){
return null;
}
}
//Inicia o XML
XStream xstream = new XStream(new DomDriver());
xstream.addPermission(AnyTypePermission.ANY);
//XStream.alias("nome da classe", Casa.class); Essa linha melhora o que sera apresentado na classe
//deve ser inserida na hora de recuperar tambem
//Chama a função que modifica o tipo de leitura
xstream.registerConverter(new convertClassInNull()); //impede a chamada de classes abstratas do tipo class
xstream.registerConverter(new convertObjectInNull()); //impede a chamada de classes abstratas do tipo Object
//Configurações
//----------------------------------------------
Object o = xstream.fromXML(xml);
return o;
}
}
Para proteger das chamadas de classes internas eu crie 2 regras de restrição.
- Impede uso de classes genérica do tipo classe
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class convertClassInNull implements Converter {
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
writer.setValue("");
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
return null;
}
@Override
public boolean canConvert(Class type) {
return type.equals(Class.class);
}
}
- Impede classes genérica do tipo objeto
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.Date;
/**
*
-
@author rainer
*/
public class convertObjectInNull implements Converter {
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
writer.setValue("");
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
return null;
}
@Override
public boolean canConvert(Class type) {
return type.equals(Object.class);
}
}
Com a modificação somente podem ser utilizadas classes genéricas criadas pelo desenvolvedor do aplicativo e passadas por herança, qualquer tentativa de chamar uma classe que tenha um Objeto abstrato do tipo Objeto ou do tipo classe resultara em uma variável nula.
Ao conferir a classe do primeiro nível do XML tenho o controle de quais classes de objetos podem estar dentro dessa classe, optei por verificar a classe em String para evitar que um objeto de uma classe ainda não validada seja criado, assim somente objetos iniciais de classes aprovadas podem ser iniciados.
exemplo:
Language lang = (Language) xml.reader(txtXML, Language.class.getName());
Agora vamos la
Imagine que vc tem dados importantes nesse xml e, se forem alterados vc vai ter belos problemas ( imagine um booleano administrador
que pode transformar um usuario comum em um super-usuario, por exemplo ).
se isso é um problema para vc, se os dados são sensiveis, vc precisa de camadas extras de segurança. Ou seja, considere o objeto criado pelo XStream (ou qq outro tipo de deserializador) como um objeto contaminado
e efetue algum tipo de validação para considera-lo seguro.
Vc pode pensar em assinar digitalmente os dados ou xml também. O seu objeto pode ser envelopado em outro objeto que contem 2 atributos: o objeto em si e o hashCode ( provavelmente assinado )
o hashCode diz respeito aos valores dos atributos e é sua responsabilidade implementar
assinar um hashcode pode ser trivial.
digamos q um dado objeto tem hashcode 123. o seu sistema pode implementar uma senha secreta escondida 456. bastaria combinar os dois numeros “123” + “456” ( concatene os numeros como se fossem strings ) e calcular um hash assimetrico como o md5 ou sha1.
assim: se o hash é 123, o segredo é 456, vc tem 123456, e calculando o hash vc tem 987654
como só vc sabe esse secredo, vc pode a partir do hashcode do objeto verificar se ele ainda esta integro.
na realidade é mais complicado que isso.
Na API padrão você não vai encontrar classes que sejam executadas simplesmente por serem instanciadas, até porquê isso é uma máquina prática, o construtor de uma classe é responsável por somente inicializar o objeto, para executar algo você deveria ter um método específico.
algumas classes vc pode setar uma Factory que vai executar codigo externo no construtor. é o caso da classe Socket
mas isso é muito bem definido na documentação e o comportamento padrão é não ter essa factory.
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#setSocketImplFactory(java.net.SocketImplFactory)
Na verdade o xml guardaria valores temporarios e dados de programa e na seria utilizado para transferencia, como o dado não é algo como um tipo de transmissão de um servidor ou um valor estatico a validação se torna meio inutil nesse ponto.
Minha preocupação era proteger o aplicativo de vulnerabilidades com relação a injeção de codigos maliciosos, os arquivos nativos padrão ja seriam protegidos por verificação, ja os temporários não.
Minha preocupação com xstream era que ele cria o objeto e depois define o parametro, se o dado guardado no xml fosse uma especie de classe de injeção que foi passada para xml durante a execução as variaves internas do objeto que serviriam para inicializar o objeto poderiam ja estar setada para execução.
Eu imagino que internamente o xstream trabalhe assim, primeiro identifica qual classe de objeto a informação pertense, depois cria um objeto dessa classe, e na terceira etapa identifica os valores das variaveis internas no xml e em seguida insere esse valores no objeto o que seria similar a eu estar construindo um algoritmo desse no meu codigo fonte, como o proprio criador da biblioteca xstream alerta para a possibilidade desse tipo de injeção de objeto, fiquei curioso qual classe poderia ter um efeito de injeção por isso perguntei, se não me engano no java tem uma classe chamad Shell() que passa comando diretamente ao interpretador do Windows, vi algo do tipo enquanto pesquisava
vc pode olhar o codigo fonte também