WIP: add more (manual) protobuf models, and a test that checks various taint-flow cases

Only some of the cases are currently working.
This commit is contained in:
Chris Smowton
2020-07-30 17:04:05 +01:00
parent 4ff325aa13
commit 19e1dacced
8 changed files with 292 additions and 12 deletions

View File

@@ -1,4 +1,12 @@
| proto.go:27:10:27:21 | reflectedXSS | proto.go:27:10:27:38 | call to GetDescription |
| proto.go:28:12:28:23 | reflectedXSS | proto.go:28:12:28:35 | call to GetAlerts |
| proto.go:30:35:30:46 | reflectedXSS | proto.go:30:2:30:47 | ... := ...[0] |
| proto.go:36:24:36:33 | serialized | proto.go:35:2:35:13 | definition of deserialized |
| proto.go:29:10:29:21 | reflectedXSS | proto.go:29:10:29:38 | call to GetDescription |
| proto.go:30:12:30:23 | reflectedXSS | proto.go:30:12:30:35 | call to GetAlerts |
| proto.go:32:35:32:46 | reflectedXSS | proto.go:32:2:32:47 | ... := ...[0] |
| proto.go:38:24:38:33 | serialized | proto.go:37:2:37:13 | definition of deserialized |
| testDeprecatedApi.go:24:33:24:37 | query | testDeprecatedApi.go:24:2:24:38 | ... := ...[0] |
| testDeprecatedApi.go:35:33:35:42 | queryClone | testDeprecatedApi.go:35:2:35:43 | ... := ...[0] |
| testDeprecatedApi.go:43:18:43:36 | untrustedSerialized | testDeprecatedApi.go:42:2:42:6 | definition of query |
| testDeprecatedApi.go:51:18:51:36 | untrustedSerialized | testDeprecatedApi.go:50:2:50:6 | definition of query |
| testDeprecatedApi.go:53:13:53:17 | query | testDeprecatedApi.go:53:13:53:34 | call to GetDescription |
| testDeprecatedApi.go:61:14:61:19 | query2 | testDeprecatedApi.go:60:2:60:7 | definition of query2 |
| testDeprecatedApi.go:61:22:61:27 | query1 | testDeprecatedApi.go:60:2:60:7 | definition of query2 |
| testDeprecatedApi.go:63:33:63:38 | query2 | testDeprecatedApi.go:63:2:63:39 | ... := ...[0] |

View File

@@ -0,0 +1,2 @@
| testDeprecatedApi.go:41:25:41:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:45:13:45:29 | selection of Description |
| testDeprecatedApi.go:49:25:49:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:53:13:53:34 | call to GetDescription |

View File

@@ -0,0 +1,27 @@
import go
class UntrustedFunction extends Function {
UntrustedFunction() { this.getName() = ["getUntrustedString", "getUntrustedBytes"] }
}
class UntrustedSource extends DataFlow::Node, UntrustedFlowSource::Range {
UntrustedSource() { this = any(UntrustedFunction f).getACall() }
}
class SinkFunction extends Function {
SinkFunction() { this.getName() = ["sinkString", "sinkBytes"] }
}
class TestConfig extends TaintTracking::Configuration {
TestConfig() { this = "testconfig" }
override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink = any(SinkFunction f).getACall().getAnArgument()
}
}
from TaintTracking::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source, sink

View File

@@ -0,0 +1,66 @@
package main
import (
"codeql-go-tests/protobuf/protos/query"
"github.com/golang/protobuf/proto"
)
func getUntrustedString() string {
return "trouble"
}
func getUntrustedBytes() []byte {
return []byte{}
}
func sinkString(_ string) {}
func sinkBytes(_ []byte) {}
func testMarshal() {
query := &query.Query{}
query.Description = getUntrustedString()
serialized, _ := proto.Marshal(query)
sinkBytes(serialized)
}
func testCloneThenMarshal() {
query := &query.Query{}
query.Description = getUntrustedString()
queryClone := proto.Clone(query)
serialized, _ := proto.Marshal(queryClone)
sinkBytes(serialized)
}
func testUnmarshalFieldAccess() {
untrustedSerialized := getUntrustedBytes()
query := &query.Query{}
proto.Unmarshal(untrustedSerialized, query)
sinkString(query.Description)
}
func testUnmarshalGetter() {
untrustedSerialized := getUntrustedBytes()
query := &query.Query{}
proto.Unmarshal(untrustedSerialized, query)
sinkString(query.GetDescription())
}
func testMergeThenMarshal() {
query1 := &query.Query{}
query1.Description = getUntrustedString()
query2 := &query.Query{}
proto.Merge(query2, query1)
serialized, _ := proto.Marshal(query2)
sinkBytes(serialized)
}

View File

@@ -1,10 +1,9 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/golang/protobuf/proto, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/golang/protobuf/proto (exports: Message; functions: Marshal,Unmarshal,ProtoPackageIsVersion4)
// Package proto is a stub of github.com/golang/protobuf/proto, generated by depstubber.
// Package proto is a stub of github.com/golang/protobuf/proto
package proto
import (
@@ -17,8 +16,14 @@ func Marshal(_ interface{}) ([]byte, error) {
type Message = protoiface.MessageV1
var ProtoPackageIsVersion4 bool = false
const ProtoPackageIsVersion4 bool = false
func Unmarshal(_ []byte, _ interface{}) error {
return nil
}
func Clone(_ Message) Message {
return nil
}
func Merge(_, _ Message) {}

View File

@@ -1,13 +1,14 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for google.golang.org/protobuf/internal/impl, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: google.golang.org/protobuf/internal/impl (exports: MessageState,Pointer; functions: )
// Package impl is a stub of google.golang.org/protobuf/internal/impl, generated by depstubber.
// Package impl is a stub of google.golang.org/protobuf/internal/impl.
package impl
import ()
import (
"google.golang.org/protobuf/reflect/protoreflect"
)
type MessageState struct {
NoUnkeyedLiterals interface{}
@@ -16,3 +17,116 @@ type MessageState struct {
}
type Pointer interface{}
type MessageInfo struct {
Exporter interface{}
}
func (*MessageInfo) MessageOf(_ interface{}) protoreflect.Message { return nil }
type EnumInfo struct{}
func (_ *EnumInfo) Descriptor() protoreflect.EnumDescriptor { return nil }
func (_ *EnumInfo) New(_ protoreflect.EnumNumber) protoreflect.Enum { return nil }
type DescBuilder struct {
GoPackagePath string
RawDescriptor []byte
NumEnums int
NumMessages int
NumExtensions int
NumServices int
}
type TypeBuilder struct {
File DescBuilder
GoTypes []interface{}
DependencyIndexes []int32
EnumInfos []EnumInfo
MessageInfos []MessageInfo
}
type BuilderOut struct {
File protoreflect.FileDescriptor
}
func (tb TypeBuilder) Build() BuilderOut {
return BuilderOut{nil}
}
func (ms *MessageState) LoadMessageInfo() *MessageInfo { return nil }
func (ms *MessageState) StoreMessageInfo(mi *MessageInfo) {}
func (ms *MessageState) Clear(_ protoreflect.FieldDescriptor) {}
func (ms *MessageState) Descriptor() protoreflect.MessageDescriptor { return nil }
func (ms *MessageState) Get(_ protoreflect.FieldDescriptor) protoreflect.Value {
return protoreflect.Value{}
}
func (ms *MessageState) GetUnknown() protoreflect.RawFields { return nil }
func (ms *MessageState) Has(_ protoreflect.FieldDescriptor) bool { return false }
func (ms *MessageState) Interface() protoreflect.ProtoMessage { return nil }
func (ms *MessageState) IsValid() bool { return false }
func (ms *MessageState) Mutable(_ protoreflect.FieldDescriptor) protoreflect.Value {
return protoreflect.Value{}
}
func (ms *MessageState) New() protoreflect.Message { return nil }
func (ms *MessageState) NewField(_ protoreflect.FieldDescriptor) protoreflect.Value {
return protoreflect.Value{}
}
func (ms *MessageState) ProtoMethods() *struct {
NoUnkeyedLiterals interface{}
Flags uint64
Size func(struct {
NoUnkeyedLiterals interface{}
Message protoreflect.Message
Flags byte
}) struct {
NoUnkeyedLiterals interface{}
Size int
}
Marshal func(struct {
NoUnkeyedLiterals interface{}
Message protoreflect.Message
Buf []byte
Flags byte
}) (struct {
NoUnkeyedLiterals interface{}
Buf []byte
}, error)
Unmarshal func(struct {
NoUnkeyedLiterals interface{}
Message protoreflect.Message
Buf []byte
Flags byte
Resolver interface {
FindExtensionByName(_ protoreflect.FullName) (protoreflect.ExtensionType, error)
FindExtensionByNumber(_ protoreflect.FullName, _ interface{}) (protoreflect.ExtensionType, error)
}
}) (struct {
NoUnkeyedLiterals interface{}
Flags byte
}, error)
Merge func(struct {
NoUnkeyedLiterals interface{}
Source protoreflect.Message
Destination protoreflect.Message
}) struct {
NoUnkeyedLiterals interface{}
Flags byte
}
CheckInitialized func(struct {
NoUnkeyedLiterals interface{}
Message protoreflect.Message
}) (struct {
NoUnkeyedLiterals interface{}
}, error)
} {
return nil
}
func (ms *MessageState) Range(_ func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {}
func (ms *MessageState) Set(_ protoreflect.FieldDescriptor, _ protoreflect.Value) {}
func (ms *MessageState) SetUnknown(_ protoreflect.RawFields) {}
func (ms *MessageState) Type() protoreflect.MessageType { return nil }
func (ms *MessageState) WhichOneof(_ protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
return nil
}

View File

@@ -0,0 +1,42 @@
// This is a simple stub for github.com/golang/protobuf/proto, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/golang/protobuf/proto (exports: Message; functions: Marshal,Unmarshal,ProtoPackageIsVersion4)
// Package proto is a stub of github.com/golang/protobuf/proto.
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoiface "google.golang.org/protobuf/runtime/protoiface"
)
func Marshal(_ interface{}) ([]byte, error) {
return nil, nil
}
type Message = protoreflect.ProtoMessage
var ProtoPackageIsVersion4 bool = false
func Unmarshal(_ []byte, _ interface{}) error {
return nil
}
type MarshalOptions struct {
AllowPartial bool
Deterministic bool
UseCachedSize bool
}
func (_ MarshalOptions) Marshal(_ Message) ([]byte, error) { return nil, nil }
func (_ MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) { return nil, nil }
func (_ MarshalOptions) MarshalState(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
return protoiface.MarshalOutput{nil}, nil
}
func Clone(_ Message) Message {
return nil
}
func Merge(_, _ Message) {}

View File

@@ -12,11 +12,11 @@ import (
type EnforceVersion uint
var MaxVersion int = 0
const MaxVersion int = 20
type MessageState = impl.MessageState
var MinVersion int = 0
const MinVersion int = 20
type Pointer = impl.Pointer
@@ -89,3 +89,19 @@ func (Export) MessageTypeOf(m message) interface{} {
func (Export) MessageStringOf(m interface{}) string {
return ""
}
func (Export) MessageStateOf(p Pointer) *MessageState {
return nil
}
func (Export) CompressGZIP(_ []byte) []byte {
return nil
}
type EnumInfo = impl.EnumInfo
type MessageInfo = impl.MessageInfo
type TypeBuilder = impl.TypeBuilder
type DescBuilder = impl.DescBuilder