Maison  >  Article  >  Opération et maintenance  >  Comment Codeql analyse le problème des cookies n'activant pas httponly

Comment Codeql analyse le problème des cookies n'activant pas httponly

PHPz
PHPzavant
2023-05-17 17:25:591255parcourir

Préface

Aujourd'hui, nous utilisons codeql pour analyser les problèmes de sécurité tels que "le cookie n'est pas activé http uniquement", approfondissant ainsi notre utilisation de codeql. Si cela fonctionne bien, vous pouvez envisager de corriger d'autres vulnérabilités dans Vulnerability-goapp.

Vous devez en outre télécharger codeql-go lors de l'analyse des programmes go

Instructions

Objets d'audit

Vulnérabilité-goapp : application Web golang vulnérable pour l'éducation.

Modification

Étant donné que tous les cookies de ce projet n'ont pas l'attribut http uniquement défini, nous devons d'abord les modifier avant la comparaison. Ce qui suit est une réécriture de la phrase originale : Modification de l'enregistrement : ajoutez l'option http uniquement à certains paramètres de cookies.

pkgadminadmin.go est modifié comme suit.
Comment Codeql analyse le problème des cookies nactivant pas httponly

pkgloginlogin.go est modifié comme suit.
Comment Codeql analyse le problème des cookies nactivant pas httponly

pkgregisterregister.go est modifié comme suit.
Comment Codeql analyse le problème des cookies nactivant pas httponly

N'oubliez pas de régénérer la base de données après modification (si vous devez écraser l'ancienne base de données, vous devez d'abord supprimer l'ancienne puis en générer une nouvelle.

Le but

est d'utiliser le script codeql pour trouver que httponly n'est pas défini et httponly est défini) Mais la valeur de httponly est fausse (généralement ce n'est pas le cas, mais ce n'est pas garanti

Déterminer la source et le puits

Définition du puits

Le puits est très simple). Lors de la définition des cookies, vous devez utiliser la méthode http.SetCookie. La valeur du cookie qui doit être définie est le deuxième paramètre de cette fonction, puis nous pouvons écrire une instruction de requête pour trouver un récepteur comme celui-ci

import go
from DataFlow::Node sink
where exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = sink
    )
select sink

After. en cours d'exécution, vous pouvez obtenir les résultats suivants. En cliquant sur n'importe quel élément, vous accéderez à l'exigence composée sous le segment de code
Comment Codeql analyse le problème des cookies nactivant pas httponly

Nous le convertissons en classe Sink, comme suit

private class Sink extends DataFlow::Node {
  Sink() {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this
    )
  }
}

Après cela, en définissant une variable. comme Sink, il fait référence à tous les extraits de code qui remplissent les conditions, par exemple :

import go

private class Sink extends DataFlow::Node {
  Sink() {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this
    )
  }
}

from Sink s
select s

Après l'exécution Le même résultat sera obtenu

Définition de la source

Ensuite, nous déterminons la source à en juger par les paramètres reçus par http. Méthode SetCookie, le deuxième paramètre réel est un pointeur vers la structure d'un Cookie
Comment Codeql analyse le problème des cookies nactivant pas httponlyComment Codeql analyse le problème des cookies nactivant pas httponly

Donc, nous devons d'abord trouver une telle structure. Nous pouvons d'abord lister toutes les structures du projet. codeql-go est le suivant


Comment Codeql analyse le problème des cookies nactivant pas httponlyDonc, notre script de requête est également

import go

from StructLit source
select source

Toutes les structures sont répertoriées comme prévu


Comment Codeql analyse le problème des cookies nactivant pas httponlyEnsuite, l'étape suivante consiste à éliminer les autres contenus non pertinents et à restreindre les types. la méthode hasQualifiedName, différents types dans Codeql-go. Ils ont tous la même méthode, définie comme suit, à quel package appartient l'objet et quel est son nom

Si vous n'êtes pas sûr, vous pouvez imprimer les champs pertinents. via getPackage et getName, par exemple

import go

from StructLit source
// where source.getType().hasQualifiedName("net/http", "Cookie")
select source.getType().getPackage(), source.getType().getName()
Comment Codeql analyse le problème des cookies nactivant pas httponlyLes résultats sont les suivants

Nous pouvons trouver la définition source, par exemple

import go

from StructLit source
where source.getType().hasQualifiedName("net/http", "Cookie")
select source

Comment Codeql analyse le problème des cookies nactivant pas httponly est également convertie en une sous-classe de DataFlow::Node
private class Source extends DataFlow::Node {
  Source() {
    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)
  }
}

TaintConfig.

Flux de données simpleComment Codeql analyse le problème des cookies nactivant pas httponly

Avec Source et Sink, définissez simplement TaintConfig. Tous les flux de données de la source vers le Sink peuvent être obtenus

import go

private class Source extends DataFlow::Node {
  Source() {
    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)
  }
}

private class Sink extends DataFlow::Node {
  Sink() {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this
    )
  }
}

class Configuration extends TaintTracking::Configuration {
  Configuration() { this = "HttpOnly" }

  override predicate isSource(DataFlow::Node source) { source instanceof Source }

  override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
}

from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select source, sink

Les résultats sont les suivants :

Élimination


Cependant, nous n'avons pas encore supprimé. la partie où httponly=true est défini, nous devons donc ajouter la qualification, qui est sur le point d'avoir l'attribut HttpOnly. Les flux de données qui sont vrais sont exclus des résultats Comment Codeql analyse le problème des cookies nactivant pas httponly

Nous pouvons utiliser TaintTracking::isSanitizer fourni par CodeQL pour filtrer. nœuds inoffensifs :

override predicate isSanitizer(DataFlow::Node node) {
    exists(Write w, Field f, DataFlow::Node rhs |
      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and
      w.writesField(node, f, rhs) and
      rhs.getBoolValue() = true
    )
  }

运行结果如下,但有一处地方需要注意。
Comment Codeql analyse le problème des cookies nactivant pas httponly红框中实际有对HttpOnly进行设置,但我们的脚本并不能识别这样的一个数据流。后面试了各种方法,最终找到一种解决方式,将isSanitizer修改成以下内容。

override predicate isSanitizer(DataFlow::Node node) {
    exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs |
      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and
      w.writesField(n, f, rhs) and
      rhs.getBoolValue() = true and
      node = n.getAPredecessor*()n
    )
  }

其中node=n.getAPredecessor*()是说node是n的前置数据流节点,数据可以在0个或多个步骤中从node流到n。

最终脚本

加上一些信息,模仿官方的示例,最终脚本如下。

/**
 * @name Cookie未设置httponly
 * @description Cookies包含一个HTTPOnly的设置选项,可以使此cookie不能被js读取,而只能用于HTTP请求。
 * @kind path-problem
 * @problem.severity error
 * @precision low
 * @id go/Cookie-not-set-httponly
 * @tags security
 */

import go
import DataFlow::PathGraph

private class Source extends DataFlow::Node {
  Source() {
    exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s)
  }
}

private class Sink extends DataFlow::Node {
  Sink() {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this
    )
  }
}

class Configuration extends TaintTracking::Configuration {
  Configuration() { this = "HttpOnly" }

  override predicate isSource(DataFlow::Node source) { source instanceof Source }

  override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }

  override predicate isSanitizer(DataFlow::Node node) {
    exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs |
      f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and
      w.writesField(n, f, rhs) and
      rhs.getBoolValue() = true and
      node = n.getAPredecessor*()
    )
  }
}

from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cookie-not-set-httponly in $@.", source.getNode(), "here"

最终筛选出存在问题的内容。
Comment Codeql analyse le problème des cookies nactivant pas httponly

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer