>  기사  >  운영 및 유지보수  >  Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

PHPz
PHPz앞으로
2023-05-17 17:25:591272검색

머리말

오늘은 codeql을 사용하여 "쿠키가 활성화되지 않았습니다 httponly"와 같은 보안 문제를 분석하여 codeql 사용을 심화시킵니다. 잘 작동한다면 Vulnerability-goapp의 다른 취약점을 수정하는 것을 고려할 수 있습니다.

Go 프로그램 분석 시 codeql-go를 추가로 다운로드해야 합니다

Instructions

Audit object

Vulnerability-goapp: 취약한 교육용 golang 웹 애플리케이션입니다.

수정

이 프로젝트의 모든 쿠키에는 http 전용 속성이 설정되어 있지 않으므로 비교하기 전에 먼저 쿠키를 수정해야 합니다. 다음은 원래 문장을 다시 쓴 것입니다. 기록 수정: 일부 쿠키 설정에 http 전용 옵션을 추가합니다.

pkgadminadmin.go는 다음과 같이 수정됩니다.
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

pkgloginlogin.go가 다음과 같이 수정되었습니다.
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

pkgregisterregister.go가 다음과 같이 수정되었습니다.
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

수정 후 데이터베이스를 다시 생성해야 한다는 점을 기억하세요(이전 DATAbase를 덮어써야 하는 경우 먼저 이전 DATAbase를 삭제한 후 새 데이터베이스를 생성해야 합니다.

목적

은 codeql 스크립트를 사용하여 찾는 것입니다. httponly가 설정되지 않고 httponly가 설정됨) 그러나 httponly의 값은 false입니다(일반적으로 그렇지 않지만 보장되지는 않습니다).

소스 및 싱크 결정

싱크 정의

싱크는 매우 간단합니다. 쿠키를 설정할 때 http.SetCookie.method를 사용해야 하며, 설정해야 하는 쿠키 값이 이 함수의 두 번째 매개변수이며, 그런 다음 이와 같은 싱크를 찾는 쿼리문을 작성할 수 있습니다. 실행하면 다음과 같은 결과를 얻을 수 있습니다.


Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법다음과 같이 Sink 클래스로 변환합니다. Sink는 조건을 충족하는 모든 코드 조각을 나타냅니다. 예:

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

실행 후 동일한 결과를 얻습니다.

Source 정의

그런 다음 http에서 받은 매개변수를 통해 Source를 결정합니다. SetCookie 메소드에서 실제 두 번째 매개변수는 쿠키의 구조에 대한 포인터입니다.


먼저 해당 구조를 찾아야 합니다. codeql-go는 다음과 같습니다 Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

쿼리 스크립트도

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

입니다. 모든 구조는 예상대로 나열됩니다.
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

다음 단계는 관련 없는 콘텐츠를 제거하고 유형을 제한하는 것입니다. hasQualifiedName 메소드는 Codeql-go의 다양한 유형과 동일하며 다음과 같이 객체가 속한 패키지와 이름이 무엇인지 정의됩니다.


Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법 확실하지 않은 경우 관련 필드를 인쇄할 수 있습니다. 예를 들어 getPackage 및 getName을 통해

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

결과는 다음과 같습니다.


예를 들어 Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

import go

from StructLit source
select source

도 DataFlow::Node

import go

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

TaintConfig 정의의 하위 클래스로 변환됩니다.
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법간단한 데이터 흐름

Source와 Sink로 간단하게 TaintConfig를 정의하면 됩니다. Source에서 Sink로의 모든 데이터 흐름을 얻을 수 있습니다.

import go

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

결과는 다음과 같습니다. Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

Elimination

그러나 아직 제거되지 않았습니다. httponly=true가 설정된 부분이므로 HttpOnly 속성을 가지려는 제한을 추가해야 합니다. true인 데이터 스트림은 결과에서 제외됩니다.

CodeQL에서 제공하는 TaintTracking::isSanitizer를 사용하여 필터링할 수 있습니다. 무해한 노드:

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
    )
  }

运行结果如下,但有一处地方需要注意。
Codeql이 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"

最终筛选出存在问题的内容。
Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법

위 내용은 Codeql이 httponly를 활성화하지 않는 쿠키 문제를 분석하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제