
Olá Habr!
No artigo, quero falar sobre a nossa experiência na criação de minhas consultas no Checkmarx SAST.
Quando você se familiariza com esse analisador, pode ter a impressão de que, além de procurar algoritmos fracos de criptografia / hash e um monte de falso positivo, ele não retorna mais nada. Mas, quando configurada corretamente, é uma ferramenta super poderosa que pode procurar bugs sérios.
Compreenderemos os meandros da linguagem de consulta Checkmarx SAST e escreveremos 2 consultas para procurar por injeções de SQL e referências diretas a objetos inseguras.
Entrada
Após uma longa pesquisa por guias ou artigos sobre o Checkmarx, ficou claro para mim que, além da documentação oficial, não havia informações úteis suficientes. E a documentação oficial não diz que tudo está se tornando muito claro e compreensível. Por exemplo, não encontrei práticas recomendadas, como organizar consultas de substituição corretamente, como escrever consultas "para manequins" etc. etc. Sim, há documentação sobre as funções da linguagem de consulta do CMx, mas veja como combinar essas funções em uma única consulta, a documentação não está escrita.
Talvez a falta de artigos e guias da comunidade Checkmarx esteja associada ao alto custo da ferramenta e, como resultado, a uma pequena audiência. Ou talvez apenas algumas pessoas se preocupem com o ajuste fino e usem a solução como está, pronta para uso.
Na minha experiência, vejo mais que o SAST é usado mais para cumprir formalidades relacionadas a vários requisitos por parte dos clientes do que para procurar bugs reais. Com essa abordagem, como resultado, temos, na melhor das hipóteses, um número relativamente pequeno de “vulnerabilidades” que quase automaticamente passam a ser chamadas de “não exploráveis” (porque elas estão em 99,9% dos casos).
Deve-se observar que o próprio Checkmarx está tentando atualizar suas consultas para fornecer o melhor resultado imediato. Porém, as consultas do CMx Query Language são adaptadas ao "caso geral". A pesquisa inicial de tokens é baseada no nome. Por exemplo, o CMx SAST assume que todas as consultas ao banco de dados terão a seguinte aparência: * createQuery * ou * createSQLQuery *. Mas se o desenvolvimento interno for usado para trabalhar com o banco de dados e o método para consultar o banco de dados for chamado de maneira diferente, por exemplo * driveMyQuery *, todos os métodos SQL serão ignorados. Por exemplo, nosso cliente usa ORM personalizado para banco de dados SQL. Nesse caso, as consultas CMx prontas para o uso ignoraram todas as injeções de SQL.
Abreviações e definições
CMx - Checkmarx SAST.
CMxQL - linguagem de consulta Checkmarx SAST
Token - uma string com um certo valor é o resultado do trabalho do analisador lexical (também chamado de tokenização)
Aplicativo de teste
Para escrever um artigo, esbocei um código Java, um pequeno aplicativo de teste. Este código é uma cópia aproximada de uma pequena parte do sistema real. Embora, em geral, o código do aplicativo de teste não seja muito diferente de qualquer outro código de back-end HTTP. As principais seções do código do aplicativo de teste serão visíveis nas capturas de tela.
O aplicativo de teste possui a seguinte estrutura
Classe
WebRouter para processar solicitações HTTP recebidas; 4 métodos para processar URLs dentro:
- / getTransaction - aceita o ID da transação como entrada e retorna as informações , identifica -o como uma sequência e passa-o para getTransactionInfo (transactionId) => getTransactionInfo (transactoinId) - torna o transactionId concatenado com a consulta SQL (ou seja, a injeção SQL é obtida);
- / getSecureTransaction - recebe o ID da transação na entrada e retorna as informações , identifica -o como uma string e passa-o getTransactionInfoSecured () => getTransactionInfoSecured (transactoinId) - primeiro lança o string transactionId para o tipo Long e depois o concatena na consulta SQL (neste caso a injeção não seja explorada);
- / getSettings - aceita userId e mailboxId como entrada - e emite as configurações da caixa de correio. Não verifica se o id da caixa de correio pertence ao usuário;
- / getSecureSettings - também aceita userId e mailboxId na entrada e exibe as configurações da caixa de correio. MAS verifica se o id da caixa de correio pertence ao usuário.
CMx: informações gerais e definições básicas
Antes de começar a desenvolver consultas
O desenvolvimento da consulta é realizado em um programa separado CxAuditor. No CxAuditor, você precisa digitalizar todo o código (criar projeto local), para o qual escreveremos consultas. Depois disso, você pode escrever e executar novas consultas. Com uma grande base de códigos, a verificação primária pode levar horas e gigabytes de memória. Depois disso, cada solicitação não será executada com rapidez suficiente. Isso é completamente inadequado para o desenvolvimento.
Portanto, você pode pegar um pequeno conjunto de arquivos do projeto, de preferência com um bug encontrado no código antes do tipo em que estamos escrevendo uma solicitação (ou colocar o bug com as mãos) e verificar apenas esse conjunto de arquivos. Não é necessário cumprir a estrutura de arquivos do projeto. Ou seja, se você tiver o pacote Java A e B e as classes no pacote B usarem as classes e os métodos do pacote A, poderá colocar tudo isso em um único diretório, e o CMx ainda entenderá os relacionamentos e criará cadeias de chamadas entre arquivos corretamente (bom ou quase sempre correto, embora os erros dificilmente estejam relacionados à estrutura de arquivos do projeto).
Definições básicas
Cxlist
O principal tipo de dados no CMx. O resultado de quase todas as funções do CMxQL será
CxList . Existem muitos elementos com certas propriedades. As propriedades que são mais úteis para o desenvolvimento serão consideradas abaixo.
resultado
O CMxQL possui um
resultado variável interno. O conjunto que contém a variável de
resultado , após a execução de toda a consulta, será exibido como resultado.
Ou seja, a operação final de qualquer consulta deve ser a sequência
result = WHATEVER , por exemplo:
result = All.FindByName("anyname");
elemento de fluxo e código
A maioria das funções do CMxQL pelo tipo de valores retornados são divididas em 2, aquelas que retornam "elementos de código" e aquelas que retornam o Flow. Nos dois casos, o resultado é um
CxList . Mas seu conteúdo será um pouco diferente para os elementos de fluxo e código.
- Elemento de código - token - por exemplo, uma variável, chamada de método, atribuição, etc;
- Fluxo - o relacionamento entre os tokens fornecidos.
Tudo e "sub" Tudo
Cada função do CMxQL pode ser executada no conjunto
Tudo (contém todos os tokens de todo o código digitalizado, já vimos um exemplo com
resultado ) ou no conjunto
CxList , que por sua vez foi obtido como resultado de algumas operações na consulta, por exemplo, na consulta:
CxList newList = CxList.New();
criará um conjunto vazio, que poderá ser preenchido com elementos usando o método
Add () e, em seguida, pesquisar pelos elementos do novo conjunto:
CxList newFind = newList.FindByName("narrowedScope");
Propriedades dos itens encontrados
Cada elemento do conjunto CxList possui várias propriedades. Ao analisar os resultados para escrever consultas, os mais úteis são:
- SourceFile - o nome do arquivo que contém esse elemento;
- Linha de Origem - número da linha com token;
- Nome da fonte - o nome do token. Equivalente ao token, ou seja, se a variável for chamada var1, então Nome da Fonte = var1;
- Tipo de origem - o tipo de token. Por exemplo, se for uma string, será StringLiteral, se o método for chamado, MethodInvokeExpr e muitos outros;
- Arquivo de destino
- Linha de destino;
- Nome do destino;
- Tipo de destino.
Origem e Destino serão diferentes se os elementos do conjunto de resultados forem Fluxo e vice-versa corresponderão se o resultado for elementos de código.
Comece a criar consultas
Todas as funções do CMxQL podem ser divididas em vários tipos. Aqui, na minha opinião, pode-se notar a principal desvantagem da documentação do CMxQL, todas as funções no dock são descritas simplesmente em ordem alfabética, enquanto seria muito mais conveniente estruturá-las de acordo com a funcionalidade e somente então alfabeticamente.
- Funções de pesquisa - quase todas as funções do CMxQL com o nome FindBy * e GetBy * ;
- As funções das operações em conjuntos são adição, subtração, interseção, iteração sobre elementos, etc.
- Funções de análise - Essas são basicamente as funções * InfluencedBy * * InfluencingOn * .
O princípio básico das consultas é a alternância desses tipos de funções. Primeiro, usando as funções de pesquisa, selecionamos apenas os tokens que nos interessam por determinadas propriedades. Usando operações em conjuntos, podemos combinar diferentes conjuntos com diferentes propriedades de token em um, ou vice-versa, subtrair o outro de um. Em seguida, usando as funções de análise, criamos o Code Flow e tentamos entender se as possíveis vulnerabilidades dependem dos parâmetros nos pontos de entrada.
A escolha do local a partir do qual iniciar a pesquisa e, em geral, todo o caminho de pesquisa, depende do código específico e, mais precisamente, até do "texto". Em alguns casos, é conveniente procurar consultas do usuário a partir do ponto de entrada; em alguns casos, é mais conveniente começar do "final" ou até do meio. Tudo depende do código específico e você precisa abordar individualmente cada repositório.
Exemplo: Pesquisar injeção SQL
Plano de pesquisa, entre parênteses, indiquei o nome dos conjuntos (variáveis na consulta):
- Definir exceções - tokens que podem ser lançados imediatamente fora dos escopos de pesquisa ( exclusionList );
- Determinar a localização das verificações de sanitização / segurança ( sanitização );
- Encontre todos os locais de baixo nível com execução de consulta no banco de dados ( runSuperSecureSQLQuery );
- Encontre todos os parâmetros dos métodos chamados runSuperSecureSQLQuery ( runSSSQParams );
- Encontre pontos de entrada (métodos pai e seus parâmetros) para os locais de execução da consulta no banco de dados ( entryPointsParameters );
- Localize as dependências dos parâmetros runSSSQParams em entryPoints , enquanto apenas os locais onde não há entrada de entrada de higienização .
Como resultado, obtemos métodos de baixo nível com consultas SQL, onde os parâmetros da consulta SQL:
- depende dos parâmetros do método;
- parâmetros são aceitos como strings;
- parâmetros são concatenados à solicitação.
Não verificaremos se podemos controlar esses parâmetros, como acreditamos que existe um mecanismo para mapear variáveis em uma consulta e existe uma conversão para um tipo numérico para números, e a concatenação de cadeias é sempre considerada perigosa. Mesmo se não houver controle sobre a linha agora, ela pode aparecer na nova versão.
SQLi: Etapa 1. Definindo exceções
Em exceções, você precisa adicionar as classes ou arquivos em que os nomes dos tokens podem corresponder aos que você procura, porque esses tokens levarão a entradas inválidas.
Por exemplo, um método para acessar um banco de dados é chamado
runSuperSecureSQLquery . Assumimos que o método
runSuperSecureSQLquery interno seja implementado com segurança. E nossa tarefa é encontrar lugares onde não é seguro usar o método em si. Para injeção de SQL, locais de concatenação de parâmetros controlados pelo usuário não serão locais seguros. E locais seguros para mapear parâmetros na estrutura ORM ou, por exemplo, para parâmetros numéricos, é uma conversão para o tipo correspondente. Não precisamos varrer todo o código "mais profundo" do que
runSuperSecureSQLquery , o que significa que é melhor excluí-lo para evitar descobertas inúteis.
Para procurar essas exceções, é conveniente usar as funções do CMxQL:
- FindByFileName () - encontrará o conjunto de todos os tokens em um arquivo específico;
- GetByClass () - encontrará o conjunto de todos os tokens na classe com o nome fornecido.
Para um aplicativo de teste, essa exceção é a classe
Session , que contém a implementação do método
runSuperSecureSQLquery .
Um exemplo de uma solicitação para excluir código na classe
Session (o método
GetByClass () verificará quais dos tokens passados para a entrada tem um tipo
CMx de
ClassDecl e emitirá muitos tokens dessa classe)
CxList exclusionList = All.GetByClass(All.FindByName("*Session*")); result = exclusionList;
Ou outra maneira é lançar código em todo o arquivo
Session.java :
CxList exclusionList = All.FindByFileName("*Session.java"); result = exclusionList;
O asterisco antes do nome é importante, porque o nome do arquivo inclui todo o caminho.
Agora, temos muitos tokens que podem ser subtraídos nas próximas etapas do escopo da pesquisa.
O resultado da pesquisa de tokens na classe
Session :

SQLi: Etapa 2. Determinando locais de higienização
Existem 2 métodos de API no aplicativo de teste (consulte uma breve descrição do aplicativo de teste). A diferença entre os dois métodos de API é que
getTransactionInfo () concatena o parâmetro transactionId na consulta SQL e
getTransactionInfoSecured () primeiro
converte transactionId em Long e depois o passa como uma string. A vulnerabilidade (concatenação de parâmetros) é incorporada nos dois métodos. Mas, graças à conversão para Long em
getTransactionInfoSecured () , o último método não é vulnerável à injeção, porque quando tentamos passar uma injeção (string), obtemos uma exceção Java.
Neste exemplo, consideraremos o elenco como Long como o local de saneamento. Para encontrar esses tokens:
CxList sanitization = All.FindByName("*Long*"); result = sanitization;
Resultado de exemplo:

O resultado incluiu tokens com os métodos YP do tipo
Long e
getValueAsLong , que
convertem internamente
o valor no tipo
Long . Você precisa revisar cuidadosamente o resultado para garantir que não haja nada extra.
SQLi: Etapa 3. Encontre todos os locais de baixo nível com execução de consulta no banco de dados
A consulta a seguir encontrará todos os locais usando o token runSuperSecureSQLQuery (usado para acessar o banco de dados):
result = All.FindByName("*runSuperSecureSQLQuery*")
Resultado da pesquisa pelo nome do token runSuperSecureSQLQuery:

Além disso, nos locais em que esse método é chamado (a classe
Billing ), somente os tokens de chamada de método (tipo
MethodInvokeExpr ) serão encontrados e, para o local da declaração do método (classe
Session ), todos os tokens serão encontrados - variáveis.
Filtramos apenas os tokens de chamada do método:
CxList runSuperSecureSQLQuery = All.FindByName("*runSuperSecureSQLQuery*").FindByType(typeof(MethodInvokeExpr)); result = runSuperSecureSQLQuery;
Resultado:

Como resultado, obtivemos 7 locais, 4 deles as chamadas necessárias para o método
runSuperSecureSQLQuery () (classes de
Faturamento e
Usuário ). 2 - chama o método interno runSuperSecureSQLQuery () dentro da classe
Session , e mais um é o método
add , que é um tipo de peculiaridade da pesquisa do CMxQL. Digamos apenas que eu não esperava que estivesse na lista =) Os tokens na classe
Session , como descobrimos na etapa 1, não são interessantes para nós, portanto, simplesmente os subtraímos do resultado:
CxList runSuperSecureSQLQuery = All.FindByName("*runSuperSecureSQLQuery*").FindByType(typeof(MethodInvokeExpr)); result = runSuperSecureSQLQuery - exclusionList;
Recebemos uma lista válida de chamadas para o método necessário:

Observe as
funções FindByType () e
typeof () na consulta anterior. Se quisermos pesquisar por tipo de CMx, isto é, pela propriedade
CxList “Source Type” - então usamos
typeof (Source Type) . Se queremos fazer uma pesquisa por tipo de dados, precisamos passar o parâmetro apenas como uma string. Por exemplo:
result = All.FindByType("String");
encontrará todos os tokens java com o tipo String.
SQLi: Etapa 4. Encontre todos os parâmetros dos métodos runSuperSecureSQLQuery chamados
Para procurar parâmetros de método, a função CMPQL
GetParameters () é usada :
CxList runSSSQParams = All.GetParameters(runSuperSecureSQLQuery); result = runSSSQParams;
Resultado:

SQLi: Etapa 5. Encontre pontos de entrada para locais de execução de consulta no banco de dados
Para fazer isso, primeiro obtemos os nomes dos métodos pai, dentro dos quais estão as chamadas para o banco de dados
runSuperSecureSQLQuery e, em seguida, obtemos seus parâmetros. Para procurar tokens pai, a função
GetAncOfType () do CMxQL é usada :
CxList entryPoints = runSuperSecureSQLQuery.GetAncOfType(typeof(MethodDecl)); result = entryPoints;
Nesta consulta, para o conjunto runSuperSecureSQLQuery, retorne todos os tokens pai do tipo MethodDecl - este é o método anterior na pilha de chamadas:

Para procurar parâmetros de método, também usamos
GetParameters () :
CxList entryPointsParameters = All.GetParameters(entryPoints).FindByType("String");
A consulta retornará os parâmetros de um subconjunto de
entryPoints com o tipo Java String:

SQLi: Etapa 6. Encontre as dependências dos parâmetros runSSSQParams em entryPointsParameters, enquanto apenas os locais onde não há entrada de higienização
Nesta etapa, usamos as funções de análise. As seguintes funções são usadas para analisar o código de fluxo:
- InfluencedBy ()
- InfluencedByAndNotSanitized ()
- InfluencingOn ()
- InfluencingOnAndNotSanitized ()
- NotInfluencedBy ()
- NotInfluencingOn ()
Para localizar o fluxo de parâmetros de solicitação
runSSSQParams, dependendo dos parâmetros do método pai
entryPointsParameters , e excluir tokens de
limpeza :
CxList dataInflOnTable = runSSSQParams.InfluencedByAndNotSanitized(entryPointsParameters, sanitization);
No entanto, não tenho certeza se as funções
* AndNotSanitized dentro fazem alguma mágica, e parece mais que o método simplesmente subtrai o conjunto higienizado de seu resultado. Ou seja, se você fizer:
CxList dataInflOnTable = runSSSQParams.InfluencedBy(entryPointsParameters) - sanitization;
acontece a mesma coisa. Embora talvez eu simplesmente não tenha encontrado uma opção quando ainda existem diferenças.
O resultado da consulta nos fornece um fluxo corretamente construído:

Obtive fluxo com possível injeção de SQL. Como pode ser visto na captura de tela, o Checkmarx retornou 3 Flow. O fluxo na captura de tela é o mais curto, inicia e termina em um arquivo e um método. O próximo fluxo já sai da classe Session. Preste atenção à origem / destino. E o último é outro método na classe Session. O fluxo dentro da
sessão terá a seguinte aparência:

Para selecionar um fluxo, o método
ReduceFlow (CxList.ReduceFlowType flowType) é usado , onde flowType pode ser:
- CxList.ReduceFlowType.ReduceBigFlow - selecione o Fluxo mais curto
- CxList.ReduceFlowType.ReduceSmallFlow - selecione o fluxo mais longo
SQLi: consulta final para encontrar injeção SQL
Exemplo 2: Pesquisando referências de objetos diretos inseguros
Nesta solicitação, procuraremos todos os locais onde o trabalho com objetos ocorre sem verificar o proprietário do objeto. Nesse caso, podem ser usados nomes diferentes de parâmetros HTTP para mailboxid (presumimos que seja herdado) e a verificação em si pode ocorrer em diferentes estágios: em algum lugar no ponto da API de entrada HTTP, em algum lugar antes da solicitação ao banco de dados e, às vezes em métodos intermediários.
Plano de pesquisa
- Definir exceções ( exclusionList );
- Identifique locais para verificações de autorização ( idorSanitizer );
- Encontre pontos de entrada - locais para processamento primário de solicitações HTTP ( webRemoteMethods );
- Somente por tokens de ponto de entrada para localizar o local de extração do parâmetro HTTP mailboxid ( mailboxidInit );
- Encontre todas as chamadas de webRemoteMethods para métodos e parâmetros de middleware dessas chamadas ( middlewareMethods );
- Encontre métodos de middleware que dependem do mailboxid ( apiPotentialIDOR );
- Encontre todos os locais onde os métodos de middleware estão definidos ( middlewareDecl );
- Passe por todo o apiPotentialIDOR e selecione apenas os middlewareDecl nos quais não há verificação do proprietário do objeto da caixa de correio .
IDOR: Etapa 1. Identificar exceções
Nesse caso, exclua todos os tokens em um arquivo específico:
CxList exclusionList = All.FindByFileName("*WebMethodContext.java"); result = exclusionList;
O WebMethodContext.java contém uma implementação de métodos como
getMailboxId e
getUserId , além da string "mailboxid". Como o nome dos tokens coincidirá com os que precisamos procurar por vulnerabilidades, esse arquivo emitirá descobertas falsas.
IDOR: Etapa 2. Localize as verificações de autorização
No aplicativo de teste, o método
validateMailbox () é usado para determinar se o objeto solicitado pertence ao usuário:
CxList idorSanitizer = All.FindByName("*validateMailbox*"); result = idorSanitizer;
Resultado:

IDOR: Etapa 3. Encontre pontos de entrada para solicitações personalizadas da API HTTP
Os manipuladores de solicitação HTTP têm uma anotação especial que facilita a localização. No meu caso, isso é "WebRemote"; a função
CMxQL FindByCustomAttribute () é usada para procurar anotações. Para
FindByCustomAttribute () , a função de pesquisa do token pai
GetAncOfType () retornará o método na anotação:
CxList webRemoteMethods = All.FindByCustomAttribute("WebRemote") .GetAncOfType(typeof(MethodDecl)); result = webRemoteMethods;
Resultado da solicitação:

IDOR: Etapa 4. Usando apenas tokens de ponto de entrada, localize os locais de extração HTTP para o parâmetro mailboxid
Para encontrar tokens relacionados ao processamento do parâmetro HTTP mailboxid:
CxList getMailboxId = All.FindByName("\"mailboxId\"") + All.FindByName("\"mid\"") + All.FindByName("\"boxid\""); result = getMailboxId;
nós adicionamos 3 conjuntos com 3 linhas diferentes, porque de acordo com a legenda, o nome do parâmetro HTTP pode diferir em diferentes partes do sistema.
A consulta encontrará todos os locais em que
mailboxid / mid / boxid é gravado como uma string (entre aspas duplas). Mas essa consulta retornará muitas descobertas, tk. essa sequência pode ser encontrada não apenas em locais onde os parâmetros HTTP são extraídos. Se continuarmos trabalhando com esse conjunto, obteremos um grande número de descobertas falsas.
Portanto, procuraremos apenas tokens de pontos de entrada (
webRemoteMethods ). Para localizar todos os tokens filhos, a função
CMBQL GetByAncs () é usada :
result = All.GetByAncs(webRemoteMethods);
A solicitação retornará todos os tokens pertencentes aos métodos anotados como
WebRemote . Já nesta fase, podemos filtrar os tokens dos métodos em que o proprietário do objeto é verificado. Portanto, reescrevemos a consulta anterior para procurar tokens filhos de maneira a selecionar apenas os tokens filhos dos métodos
WebRemote , onde não há verificação de segurança para o proprietário do objeto. Para fazer isso, use um loop com a condição:
Agora podemos fazer uma seleção mais precisa usando os parâmetros HTTP
mailboxid :
CxList getMailboxHTTPParams = entry_point_tokens.FindByName("\"mailboxid\"") + entry_point_tokens.FindByName("\"mid\"") + entry_point_tokens.FindByName("\"boxid\""); result = getMailboxHTTPParams;
Mas não estamos interessados nos locais onde os parâmetros HTTP são recuperados, mas nas variáveis às quais são atribuídos os valores dos parâmetros HTTP. Como é mais confiável procurar o Flow precisamente por tokens de variáveis.
A função
CMxQL FindByInitialization () encontrará os locais de inicialização da variável para os tokens fornecidos:
CxList mailboxidInit = entry_point_tokens.FindByInitialization(getMailboxHTTPParams); result = mailboxidInit;
Resultado:

IDOR: Etapa 5. Encontre todas as chamadas de webRemoteMethods para métodos e parâmetros de middleware dessas chamadas
Por middleware, quero dizer código mais profundo do que os métodos de processamento de solicitações da API HTTP, ou seja, mais profundo do que os pontos de entrada das solicitações do usuário. Por exemplo, para a captura de tela acima, estes são métodos da classe
User , chamadas para
user.getSettings () e
user.getSecureSettings () :
CxList middlewareMethods = All.FindByShortName("user").GetRightmostMember(); CxList middlewareMethodsParams = entry_point_tokens.GetParameters(middlewareMethods); result = middlewareMethodsParams;
Primeiro, selecionamos todos os tokens com o nome user e, em seguida, usando
GetRightmostMember (), selecionamos os tokens de chamada para o middleware.
GetRightmostMember () na cadeia de chamadas de método retornará a mais à direita. Em seguida, derivamos os parâmetros do método encontrado usando
GetParameters () .
Resultado:

IDOR: Etapa 6. Encontre métodos de middleware que dependem do mailboxid
A análise de fluxo usa os
métodos * InfluencedBy * e
* InfluncingOn * . A diferença entre eles é clara pelo nome.
Por exemplo:
All.InfluencedBy(getMailboxHTTPParams)
percorrerá o conjunto All e encontrará todos os tokens que dependem de
getMailboxHTTPParams .
O mesmo pode ser escrito de outra maneira:
getMailboxHTTPParams.InfluencingOn(All)
Para procurar tokens dependentes de
mailboxidInit :
CxList apiPotentialIDOR = entry_point_tokens.InfluencedByAndNotSanitized(mailboxidInit, idorSanitizer); result = apiPotentialIDOR;
Resultado:

IDOR: Etapa 7. Encontre todos os locais para definir métodos de middleware
Vamos encontrar as definições de todos os métodos intermediários que podem ser usados em locais onde as solicitações dos usuários são processadas. Para fazer isso, destacamos sua propriedade comum, por exemplo, em todos esses métodos, há a criação de um objeto
Request () , a criação de um objeto é do tipo CMx
ObjectCreateExpr :
CxList requests = (All - exclusionList).FindByType(typeof(ObjectCreateExpr)).FindByName("*Request*"); CxList middlewareDecl = requests.GetAncOfType(typeof(MethodDecl)); result = middlewareDecl;
(All - exclusionList) - você pode fazer essa subtração de conjuntos e, em seguida, chamar a função CMxQL desejada do resultado.
As solicitações agora contêm todos os tokens com o nome
Solicitação e o tipo correspondente à criação do objeto.
Em seguida, usando o familiar
GetAncOfType (), encontramos o token pai do tipo
MethodDecl .
Resultado:

IDOR: Etapa 8. Passe por todo o apiPotentialIDOR e selecione apenas o middlewareDecl no qual não há verificação do proprietário do objeto da caixa de correio
Na parte final da solicitação, determinaremos quais dos métodos de middleware são chamados diretamente dos métodos do ponto de entrada e não verificaremos a quem o
id da
caixa de correio pertence. Em seguida, combine o Flow para uma análise mais conveniente dos resultados.
Novos recursos que ainda não usamos:
GetCxListByPath () - essa função é necessária para iterar sobre o Flow, se não for usada, o CMx compactará o Flow no Code Element (no primeiro nó do flow)
Concatenar * () - um número de funções necessárias para combinar vários fluxos em um
FindByParameters () - encontre um método por um token de parâmetro específico
GetName () - retornará uma string com o nome do token, se houver mais de um elemento no CxList, retornará o primeiro. O método é usado apenas ao iterar sobre elementos de um conjunto.
A parte final da solicitação:
Resultado:
CocatenatePath , . Code Element Flow
IDOR: IDOR
Conclusão
Checkmarx , . , , , .. Flow ( ). , , «» .
false positive, :
- , ( ).
- , ( ). , «Privacy Violation», , , Web UI. , .. UI . TLS XSS .
- - , (, ). , XXE , , - , .
- false positive, , CMxQL FindBy/GetBy. , ( SQL).
- false positives, , , , , CMx, . , LDAP , . c LDAP- , , .
how-to «hello world» , Checkmarx.