feat: initial GoMicro modelling

This commit is contained in:
Mathew Payne
2023-06-29 18:27:58 +01:00
parent 3fed2798c8
commit 236e81da45

View File

@@ -0,0 +1,116 @@
import go
module GoMicro {
class GoMicroServerType extends Type {
GoMicroServerType() { this.hasQualifiedName("go-micro.dev/v4/server", "Server") }
}
/**
* A file that is generated by the protobuf compiler.
*/
class ProtocGeneratedFile extends File {
ProtocGeneratedFile() {
exists(string prefix, File f |
prefix = this.getBaseName().regexpCapture("^(.*)\\.pb(\\.micro)?\\.go$", 1) and
this.getParentContainer() = f.getParentContainer()
)
}
}
/**
* A type that is generated by the protobuf compiler.
*/
class ProtocMessageType extends Type {
ProtocMessageType() {
exists(TypeEntity te |
te.getType() = this and
te.getDeclaration().getLocation().getFile() instanceof ProtocGeneratedFile and
exists(MethodDecl md |
md.getName() = "ProtoMessage" and
this = md.getReceiverDecl().getTypeExpr().getAChild().(TypeName).getType()
)
)
}
override string getName() { result = this.getUnderlyingType().getName() }
}
/**
* Server internal
*/
class ServiceInterfaceType extends InterfaceType {
NamedType namedType;
ServiceInterfaceType() {
exists(TypeEntity te |
te.getType() = namedType and
namedType.getUnderlyingType() = this and
te.getDeclaration().getLocation().getFile() instanceof ProtocGeneratedFile
)
}
/**
* Gets the name of the interface.
*/
override string getName() { result = namedType.getName() }
/**
* Gets the named type on top of this interface type.
*/
NamedType getNamedType() { result = namedType }
}
/**
* A service server type.
*/
class ServiceServerType extends NamedType {
ServiceServerType() {
exists(ServiceInterfaceType i, TypeEntity te |
this.implements(i) and
this.getName().regexpMatch("(?i).*Handler") and
te.getType() = this and
te.getDeclaration().getLocation().getFile() instanceof ProtocGeneratedFile
)
}
}
/**
* A service register handler.
*/
class ServiceRegisterHandler extends Function {
ServiceRegisterHandler() {
exists(ServiceServerType c, GoMicroServerType s |
this.getName().regexpMatch("(?i)register" + c.getName()) and
this.getParameterType(0) = s and
this.getDeclaration().getLocation().getFile() instanceof ProtocGeneratedFile
)
}
}
/**
* A service handler.
*/
class ServiceHandler extends Method {
ServiceHandler() {
exists(DataFlow::CallNode call, Type handlerType, ServiceInterfaceType i |
call.getTarget() instanceof ServiceRegisterHandler and
call.getArgument(1).getType() = handlerType and
this = handlerType.getMethod(_) and
this.implements(i.getNamedType().getMethod(_))
)
}
}
/**
* Remote / Untrusted requests coming to the service handler.
*/
class Request extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode {
Request() {
exists(FuncDef c, ServiceHandler handler | handler.getFuncDecl() = c |
this.asParameter().isParameterOf(c, 1) and
handler.getParameterType(0).hasQualifiedName("context", "Context") and
this.getType().(PointerType).getBaseType() instanceof ProtocMessageType
)
}
}
}