오늘은 codeql을 사용하여 "쿠키가 활성화되지 않았습니다 httponly"와 같은 보안 문제를 분석하여 codeql 사용을 심화시킵니다. 잘 작동한다면 Vulnerability-goapp의 다른 취약점을 수정하는 것을 고려할 수 있습니다.
Go 프로그램 분석 시 codeql-go를 추가로 다운로드해야 합니다
Vulnerability-goapp: 취약한 교육용 golang 웹 애플리케이션입니다.
이 프로젝트의 모든 쿠키에는 http 전용 속성이 설정되어 있지 않으므로 비교하기 전에 먼저 쿠키를 수정해야 합니다. 다음은 원래 문장을 다시 쓴 것입니다. 기록 수정: 일부 쿠키 설정에 http 전용 옵션을 추가합니다.
pkgadminadmin.go는 다음과 같이 수정됩니다.
pkgloginlogin.go가 다음과 같이 수정되었습니다.
pkgregisterregister.go가 다음과 같이 수정되었습니다.
수정 후 데이터베이스를 다시 생성해야 한다는 점을 기억하세요(이전 DATAbase를 덮어써야 하는 경우 먼저 이전 DATAbase를 삭제한 후 새 데이터베이스를 생성해야 합니다.
은 codeql 스크립트를 사용하여 찾는 것입니다. httponly가 설정되지 않고 httponly가 설정됨) 그러나 httponly의 값은 false입니다(일반적으로 그렇지 않지만 보장되지는 않습니다).
싱크는 매우 간단합니다. 쿠키를 설정할 때 http.SetCookie.method를 사용해야 하며, 설정해야 하는 쿠키 값이 이 함수의 두 번째 매개변수이며, 그런 다음 이와 같은 싱크를 찾는 쿼리문을 작성할 수 있습니다. 실행하면 다음과 같은 결과를 얻을 수 있습니다.
다음과 같이 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는 다음과 같습니다
쿼리 스크립트도
private class Sink extends DataFlow::Node { Sink() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this ) } }
입니다. 모든 구조는 예상대로 나열됩니다.
다음 단계는 관련 없는 콘텐츠를 제거하고 유형을 제한하는 것입니다. hasQualifiedName 메소드는 Codeql-go의 다양한 유형과 동일하며 다음과 같이 객체가 속한 패키지와 이름이 무엇인지 정의됩니다.
확실하지 않은 경우 관련 필드를 인쇄할 수 있습니다. 예를 들어 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
결과는 다음과 같습니다.
예를 들어
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 정의의 하위 클래스로 변환됩니다.
간단한 데이터 흐름
Source와 Sink로 간단하게 TaintConfig를 정의하면 됩니다. Source에서 Sink로의 모든 데이터 흐름을 얻을 수 있습니다.
import go from StructLit source where source.getType().hasQualifiedName("net/http", "Cookie") select source
결과는 다음과 같습니다.
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 ) }
运行结果如下,但有一处地方需要注意。
红框中实际有对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를 활성화하지 않는 쿠키 문제를 분석하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!