C#: Add ServiceStack support with CSV data model

This commit is contained in:
Tamas Vajk
2021-08-11 10:04:23 +02:00
parent 43ccc14162
commit 5014ef2337
20 changed files with 618 additions and 140 deletions

View File

@@ -1,2 +1,3 @@
Framework name,URL,Namespace prefixes
System,,System.* System
ServiceStack,https://servicestack.net/,ServiceStack.* ServiceStack
1 Framework name URL Namespace prefixes
2 System System.* System
3 ServiceStack https://servicestack.net/ ServiceStack.* ServiceStack

View File

@@ -88,6 +88,7 @@ private module Frameworks {
private import semmle.code.csharp.security.dataflow.flowsinks.Html
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.security.dataflow.XSSSinks
private import semmle.code.csharp.frameworks.ServiceStack
}
/**

View File

@@ -6,156 +6,300 @@
*/
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
/** A class representing a Service */
class ServiceClass extends Class {
ServiceClass() { this.getBaseClass+().getQualifiedName() = "ServiceStack.Service" }
private class ServiceClass extends Class {
ServiceClass() {
this.getBaseClass+().hasQualifiedName("ServiceStack", "Service") or
this.getABaseInterface+().hasQualifiedName("ServiceStack", "IService")
}
/** Get a method that handles incoming requests */
Method getARequestMethod() {
result = this.getAMethod(["Post", "Get", "Put", "Delete", "Any", "Option", "Head"])
exists(string name |
result = this.getAMethod(name) and
name.regexpMatch("(Get|Post|Put|Delete|Any|Option|Head|Patch)(Async|Json|Xml|Jsv|Csv|Html|Protobuf|Msgpack|Wire)?")
)
}
}
/** Top-level Request DTO types */
class RequestDTO extends Class {
RequestDTO() {
this.getABaseInterface().getQualifiedName() =
["ServiceStack.IReturn", "ServieStack.IReturnVoid"]
}
}
/** Top-level Response DTO types */
class ResponseDTO extends Class {
ResponseDTO() {
exists(RequestDTO req, ConstructedGeneric respInterface |
req.getABaseInterface() = respInterface and
respInterface.getUndecoratedName() = "IReturn" and
respInterface.getATypeArgument() = this
)
}
private class RequestDTO extends Class {
RequestDTO() { this.getABaseInterface+().hasQualifiedName("ServiceStack", "IReturn") }
}
/** Flow sources for the ServiceStack framework */
module Sources {
private import semmle.code.csharp.security.dataflow.flowsources.Remote
private import semmle.code.csharp.commons.Collections
/** Types involved in a RequestDTO. Recurse through props and collection types */
private predicate involvedInRequest(RefType c) {
c instanceof RequestDTO
or
exists(RefType parent, RefType propType | involvedInRequest(parent) |
(propType = parent.getAProperty().getType() or propType = parent.getAField().getType()) and
if propType instanceof CollectionType
then
c = propType.(ConstructedGeneric).getATypeArgument() or
c = propType.(ArrayType).getElementType()
else c = propType
)
}
/**
* Remote flow sources for ServiceStack
*
* Assumes all nested fields/properties on request DTOs are tainted, which is
* an overapproximation and may lead to FPs depending on how Service Stack app
* is configured.
* Remote flow sources for ServiceStack. Parameters of well-known `request` methods.
*/
class ServiceStackSource extends RemoteFlowSource {
private class ServiceStackSource extends RemoteFlowSource {
ServiceStackSource() {
// Parameters are sources. In practice only interesting when they are string/primitive typed.
exists(ServiceClass service |
service.getARequestMethod().getAParameter() = this.asParameter()
)
or
// Field/property accesses on RequestDTOs and request involved types
// involved types aren't necessarily only from requests so may lead to FPs...
exists(RefType reqType | involvedInRequest(reqType) |
reqType.getAProperty().getAnAccess() = this.asExpr() or
reqType.getAField().getAnAccess() = this.asExpr()
)
}
override string getSourceType() { result = "ServiceStack request DTO field" }
override string getSourceType() { result = "ServiceStack request parameter" }
}
}
/** Flow Sinks for the ServiceStack framework */
module Sinks {
private import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
/** RemoteFlow sinks for service stack */
class ServiceStackRemoteRequestParameter extends ExternalLocationSink {
ServiceStackRemoteRequestParameter() {
exists(MethodCall mc |
mc.getTarget().getQualifiedName() in [
"ServiceStack.IRestClient.Get", "ServiceStack.IRestClient.Put",
"ServiceStack.IRestClient.Post", "ServiceStack.IRestClient.Delete",
"ServiceStack.IRestClient.Patch", "ServiceStack.IRestClient.Send",
"ServiceStack.IRestClientAsync.GetAsync", "ServiceStack.IRestClientAsync.DeleteAsync",
"ServiceStack.IRestClientAsync.PutAsync", "ServiceStack.IRestClientAsync.PostAsync",
"ServiceStack.IRestClientAsync.PatchAsync",
"ServiceStack.IRestClientAsync.CustomMethodAsync"
] and
this.asExpr() = mc.getAnArgument()
)
}
private class ServiceStackRemoteSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// IRestClient
"ServiceStack;IRestClient;true;Send;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;IRestClient;true;Patch;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClient;true;Post;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClient;true;Put;(System.String,System.Object);;Argument[1];remote",
// IRestClientSync
"ServiceStack;IRestClientSync;true;CustomMethod;(System.String,ServiceStack.IReturnVoid);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;CustomMethod;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;CustomMethod;(System.String,ServiceStack.IReturn<TResponse>);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;Delete;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Delete;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Delete;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
// IRestGateway
"ServiceStack;IRestGateway;true;Delete;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Get;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Post;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Put;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Send;(ServiceStack.IReturn<T>);;Argument[0];remote",
// IOneWayClient
"ServiceStack;IOneWayClient;true;SendAllOneWay;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[1];remote",
"ServiceStack;IOneWayClient;true;SendOneWay;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IOneWayClient;true;SendOneWay;(System.Object);;Argument[0];remote",
// IServiceGateway
"ServiceStack;IServiceGateway;true;Publish;(System.Object);;Argument[0];remote",
"ServiceStack;IServiceGateway;true;PublishAll;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[0];remote",
"ServiceStack;IServiceGateway;true;Send;(System.Object);;Argument[0];remote",
"ServiceStack;IServiceGateway;true;SendAll;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[0];remote",
// IRestClientAsync
"ServiceStack;IRestClientAsync;true;CustomMethodAsync;(System.String,ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;CustomMethodAsync;(System.String,System.Object,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;CustomMethodAsync;(System.String,ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
// IRestGatewayAsync
"ServiceStack;IRestGatewayAsync;true;DeleteAsync;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;GetAsync;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;PostAsync;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;PutAsync;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;SendAsync;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
// IServiceGatewayAsync
"ServiceStack;IServiceGatewayAsync;true;PublishAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;PublishAllAsync;(System.Collections.Generic.IEnumerable<System.Object>,System.Threading.CancellationToken);;Element of Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;SendAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;SendAllAsync;(System.Collections.Generic.IEnumerable<System.Object>,System.Threading.CancellationToken);;Element of Argument[0];remote",
// ServiceClientBase
"ServiceStack;ServiceClientBase;true;Publish;(T);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Publish;(ServiceStack.Messaging.IMessage<T>);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Delete;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Get;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Patch;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Post;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Put;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(ServiceStack.IReturn);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;CustomMethod;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;CustomMethodAsync;(System.String,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytes;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytesAsync;(System.String,System.String,System.Object);;Argument[2];remote",
// ServiceClientBase
"ServiceStack;ServiceClientBase;true;Publish;(T);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Publish;(ServiceStack.Messaging.IMessage<T>);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Delete;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Get;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Patch;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Post;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Put;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(ServiceStack.IReturn);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;CustomMethod;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;CustomMethodAsync;(System.String,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytes;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytesAsync;(System.String,System.String,System.Object);;Argument[2];remote"
]
}
}
/** SQLi support for the ServiceStack framework */
module SQL {
private import semmle.code.csharp.security.dataflow.SqlInjectionQuery
/** SQLi sinks for ServiceStack */
class ServiceStackSink extends Sink {
ServiceStackSink() {
exists(MethodCall mc, Method m, int p |
(mc.getTarget() = m.getAnOverrider*() or mc.getTarget() = m.getAnImplementor*()) and
sqlSinkParam(m, p) and
mc.getArgument(p) = this.asExpr()
)
}
private class ServiceStackSqlSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// SqlExpression<T>
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeFrom;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeGroupBy;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeHaving;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOrderBy;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String,System.Boolean);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql",
// IUntypedSqlExpression
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeFrom;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeSelect;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql",
// OrmLiteReadApi
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Exists;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Dictionary;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;KeyValuePairs;(System.Data.IDbConnection,System.String,System.System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select;(System.Data.IDbConnection,System.Type,System.String,System.Object);;Argument[2];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SelectLazy;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SelectNonDefaults;(System.Data.IDbConnection,System.String,T);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Single;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Single;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Column;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Column;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
// OrmLiteReadExpressionsApi
"ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
// OrmLiteReadExpressionsApiAsync
"ServiceStack.OrmLite;OrmLiteReadExpressionsApiAsync;false;RowCountAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
// OrmLiteReadApiAsync
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;DictionaryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExistsAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync;(System.Data.IDbCommand,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectNonDefaultsAsync;(System.Data.IDbConnection,System.String,T,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
// Write API
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
// Redis API
"ServiceStack.Redis;IRedisClient;true;Custom;(System.Object[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecCachedLua;(System.String,System.Func<System.String,T>);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[],System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[],System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[],System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[],System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClient;true;LoadLuaScript;(System.String);;Argument[0];sql",
// IRedisClientAsync
"ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[],System.Threading.CancellationToken);;Element of Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecCachedLuaAsync;(System.String,System.Func<System.String,System.Threading.Tasks.ValueTask<T>>,System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[]);;Argument[0];sql",
"ServiceStack.Redis;IRedisClientAsync;true;LoadLuaScriptAsync;(System.String,System.Threading.CancellationToken);;Argument[0];sql"
]
}
}
private predicate sqlSinkParam(Method m, int p) {
exists(RefType cls | cls = m.getDeclaringType() |
// if using the typed query builder api, only need to worry about Unsafe variants
cls.getQualifiedName() =
["ServiceStack.OrmLite.SqlExpression", "ServiceStack.OrmLite.IUntypedSqlExpression"] and
m.getName().matches("Unsafe%") and
p = 0
or
// Read api - all string typed 1st params are potential sql sinks. They should be templates, not directly user controlled.
cls.getQualifiedName() =
[
"ServiceStack.OrmLite.OrmLiteReadApi", "ServiceStack.OrmLite.OrmLiteReadExpressionsApi",
"ServiceStack.OrmLite.OrmLiteReadApiAsync",
"ServiceStack.OrmLite.OrmLiteReadExpressionsApiAsync"
] and
m.getParameter(p).getType() instanceof StringType and
p = 1
or
// Write API - only 2 methods that take string
cls.getQualifiedName() =
["ServiceStack.OrmLite.OrmLiteWriteApi", "ServiceStack.OrmLite.OrmLiteWriteApiAsync"] and
m.getName() = ["ExecuteSql", "ExecuteSqlAsync"] and
p = 1
or
// NoSQL sinks in redis client. TODO should these be separate query?
cls.getQualifiedName() = "ServiceStack.Redis.IRedisClient" and
(
m.getName() = ["Custom", "LoadLuaScript"]
or
m.getName().matches("%Lua%") and not m.getName().matches("%Sha%")
) and
p = 0
// TODO
// ServiceStack.OrmLite.OrmLiteUtils.SqlColumn - what about other similar classes?
// couldn't find CustomSelect
// need to handle "PreCreateTable", "PostCreateTable", "PreDropTable", "PostDropTable"
)
private class ServiceStackXssSummaryModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"ServiceStack;HttpResult;false;HttpResult;(System.String,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.IO.Stream,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Byte[],System.String);;Argument[0];ReturnValue;taint"
]
}
}
@@ -166,14 +310,21 @@ module XSS {
/** XSS sinks for ServiceStack */
class XssSink extends Sink {
XssSink() {
exists(ServiceClass service, ReturnStmt r |
this.asExpr() = r.getExpr() and
r.getEnclosingCallable() = service.getARequestMethod()
)
or
exists(ObjectCreation oc |
oc.getType().hasQualifiedName("ServiceStack.HttpResult") and
this.asExpr() = oc.getArgument(0)
exists(ServiceClass service, Method m, Expr e |
service.getARequestMethod() = m and
this.asExpr() = e and
(
exists(ReturnStmt r |
e = r.getExpr() and
r.getEnclosingCallable() = m
)
or
e = m.getExpressionBody()
) and
(
e.getType() instanceof StringType or
e.getType().hasQualifiedName("ServiceStack", "HttpResult")
)
)
}
}

View File

@@ -5,7 +5,6 @@ private import semmle.code.csharp.frameworks.system.Data
private import semmle.code.csharp.frameworks.system.data.SqlClient
private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.NHibernate
private import semmle.code.csharp.frameworks.ServiceStack::SQL
private import semmle.code.csharp.frameworks.Dapper
private import semmle.code.csharp.dataflow.DataFlow4

View File

@@ -7,6 +7,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote
private import semmle.code.csharp.security.dataflow.flowsources.Local
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.security.Sanitizers
private import semmle.code.csharp.dataflow.ExternalFlow
/**
* A source specific to SQL injection vulnerabilities.
@@ -51,6 +52,11 @@ class SqlInjectionExprSink extends Sink {
SqlInjectionExprSink() { exists(SqlExpr s | this.getExpr() = s.getSql()) }
}
/** SQL sinks defined through CSV models. */
private class ExternalSqlInjectionExprSink extends Sink {
ExternalSqlInjectionExprSink() { sinkNode(this, "sql") }
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }
private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { }

View File

@@ -6,7 +6,7 @@ import csharp
private import Remote
private import semmle.code.csharp.commons.Loggers
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.ServiceStack::Sinks
private import semmle.code.csharp.dataflow.ExternalFlow
/**
* An external location sink.
@@ -17,6 +17,10 @@ private import semmle.code.csharp.frameworks.ServiceStack::Sinks
*/
abstract class ExternalLocationSink extends DataFlow::ExprNode { }
private class ExternalModelSink extends ExternalLocationSink {
ExternalModelSink() { sinkNode(this, "remote") }
}
/**
* An argument to a call to a method on a logger class.
*/

View File

@@ -12,7 +12,6 @@ private import semmle.code.csharp.frameworks.system.web.ui.WebControls
private import semmle.code.csharp.frameworks.WCF
private import semmle.code.csharp.frameworks.microsoft.Owin
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
private import semmle.code.csharp.frameworks.ServiceStack::Sources
/** A data flow source of remote user input. */
abstract class RemoteFlowSource extends DataFlow::Node {

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
namespace ServiceStackTest
{
}

View File

@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.ObjectPool;
using System.IO;
namespace ServiceStackTest
{
public class ResponseDto { }
public class ReqDto1 : IReturn<ResponseDto> { }
public class ReqDto2 : IReturnVoid { }
public class C
{
public async Task M()
{
var client = new JsonServiceClient("");
client.DeserializeFromStream<object>(new MemoryStream()); // not a sink
client.Get(new ReqDto1());
client.Get(new ReqDto2());
client.Get<ResponseDto>("relativeOrAbsoluteUrl"); // not a sink
client.Get<ResponseDto>(new object());
client.Get("relativeOrAbsoluteUrl"); // not a sink
client.Get(new object());
await client.GetAsync<ResponseDto>("relativeOrAbsoluteUrl"); // not a sink
await client.GetAsync<ResponseDto>(new object());
await client.GetAsync(new ReqDto1());
await client.GetAsync(new ReqDto2());
client.CustomMethod("GET", new ReqDto2());
client.CustomMethod<ResponseDto>("GET", "relativeOrAbsoluteUrl", new ReqDto1());
client.CustomMethod<ResponseDto>("GET", new ReqDto1());
client.CustomMethod<ResponseDto>("GET", new object());
client.CustomMethod("GET", "relativeOrAbsoluteUrl", new object());
client.CustomMethod("GET", (IReturnVoid)null);
await client.CustomMethodAsync("GET", new ReqDto2());
await client.CustomMethodAsync<ResponseDto>("GET", "relativeOrAbsoluteUrl", new ReqDto1());
await client.CustomMethodAsync<ResponseDto>("GET", new ReqDto1());
await client.CustomMethodAsync<ResponseDto>("GET", new object());
client.DownloadBytes("GET", "requestUri", new object());
await client.DownloadBytesAsync("GET", "relativeOrAbsoluteUrl", new object());
client.Head(new object());
client.Patch(new object());
client.Post(new object());
client.Put(new object());
client.Send<ResponseDto>(new object());
client.Publish(new ReqDto1());
client.SendOneWay(new object());
}
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Components.Forms;
using ServiceStack.OrmLite;
namespace ServiceStackTest
{
public class Table
{
public int Column { get; set; }
}
public class Sql
{
public static async Task M()
{
ServiceStack.OrmLite.SqlExpression<int> expr = null;
expr = expr.Select<Table>(t => t.Column); // ok
expr = expr
.UnsafeAnd("SQL")
.UnsafeFrom("SQL")
.UnsafeGroupBy("SQL")
.UnsafeHaving("SQL")
.UnsafeOr("SQL")
.UnsafeOrderBy("SQL")
.UnsafeSelect("SQL")
.UnsafeWhere("SQL");
var untyped = expr.GetUntypedSqlExpression();
untyped
.UnsafeAnd("SQL")
.UnsafeFrom("SQL")
.UnsafeOr("SQL")
.UnsafeSelect("SQL")
.UnsafeWhere("SQL")
.Where("SQL"); // safe
System.Data.IDbConnection conn = null;
var row = conn.SingleById<Table>(1); // ok
var rows = conn.Select<Table>(typeof(Table), "SQL", null);
rows = await conn.SelectAsync<Table>(typeof(Table), "SQL", null);
var count = conn.RowCount("SQL");
count = await conn.RowCountAsync("SQL");
conn.ExecuteSql("SQL", null);
await conn.ExecuteSqlAsync("SQL", null);
}
public static async Task Redis()
{
ServiceStack.Redis.IRedisClient client = null;
client.SetValue("key", "value"); // ok
var s = client.LoadLuaScript("script");
client.ExecLua("script", new[] { "" }, new[] { "" });
client.ExecLuaSha("SHA", new[] { "" }, new[] { "" }); // ok
client.Custom("command", "arg"); // false negative, params sinks doesn't work
ServiceStack.Redis.IRedisClientAsync asyncClient = null;
s = await asyncClient.LoadLuaScriptAsync("script");
asyncClient.ExecLuaAsync("script", new[] { "" }, new[] { "" });
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
namespace ServiceStackTest
{
public class XssServices : Service
{
public object Get(Request1 request)
{
return "<script>";
}
public object Post(Request1 request) => "<script>";
private void SomeMethod()
{
var s = new HttpResult("", ""); // not a sink
}
public object Delete(Request1 req) => req; // not a sink
public object Put(Request1 req) => new HttpResult("", "");
}
}

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
namespace ServiceStackTest
{
public class MyServices1 : Service
{
public object Get(string request) => throw null; // this might not be a remote source
public object Get(Request1 request) => throw null;
public object Get(Request2 request) => throw null;
public object Get(Request3 request) => throw null; // might be a remote source if routes are looked up with Routes.AddFromAssembly
public object Get(Request4 request)
{
Console.WriteLine(request.Nested.Prop1);
Console.WriteLine(request.Nested.Prop2[0].Prop1);
throw null;
}
public object Post(Request1 request) => throw null;
public Task<object> PostAsync(Request1 request) => throw null;
public object Method1(Request1 request) // Not a request method
{
Console.WriteLine(request.Field1);
throw null;
}
public object GetJson(Request1 request) => throw null;
}
public class MyServices2 : IService
{
public object Get(Request1 request) => throw null;
}
public class Request1 : IReturn<Response1>
{
public string Field1;
}
public class Response1
{
public string Result { get; set; }
}
[Route("/req2/{Prop1}")]
public class Request2
{
public string Prop1 { get; set; }
}
public class Request3
{
public string Prop1 { get; set; }
}
[Route("/req4")]
public class Request4 : IReturnVoid
{
public string Prop1 { get; set; }
public Nested Nested { get; set; }
}
public class Nested
{
public string Prop1 { get; set; }
public List<Element> Prop2 { get; set; }
}
public class Element
{
public string Prop1 { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
| SinksExternal.cs:24:24:24:36 | object creation of type ReqDto1 | SinksExternal.cs:24:24:24:36 | object creation of type ReqDto1 |
| SinksExternal.cs:25:24:25:36 | object creation of type ReqDto2 | SinksExternal.cs:25:24:25:36 | object creation of type ReqDto2 |
| SinksExternal.cs:27:37:27:48 | object creation of type Object | SinksExternal.cs:27:37:27:48 | object creation of type Object |
| SinksExternal.cs:29:24:29:35 | object creation of type Object | SinksExternal.cs:29:24:29:35 | object creation of type Object |
| SinksExternal.cs:32:48:32:59 | object creation of type Object | SinksExternal.cs:32:48:32:59 | object creation of type Object |
| SinksExternal.cs:33:35:33:47 | object creation of type ReqDto1 | SinksExternal.cs:33:35:33:47 | object creation of type ReqDto1 |
| SinksExternal.cs:34:35:34:47 | object creation of type ReqDto2 | SinksExternal.cs:34:35:34:47 | object creation of type ReqDto2 |
| SinksExternal.cs:37:40:37:52 | object creation of type ReqDto2 | SinksExternal.cs:37:40:37:52 | object creation of type ReqDto2 |
| SinksExternal.cs:38:78:38:90 | object creation of type ReqDto1 | SinksExternal.cs:38:78:38:90 | object creation of type ReqDto1 |
| SinksExternal.cs:39:53:39:65 | object creation of type ReqDto1 | SinksExternal.cs:39:53:39:65 | object creation of type ReqDto1 |
| SinksExternal.cs:40:53:40:64 | object creation of type Object | SinksExternal.cs:40:53:40:64 | object creation of type Object |
| SinksExternal.cs:41:65:41:76 | object creation of type Object | SinksExternal.cs:41:65:41:76 | object creation of type Object |
| SinksExternal.cs:42:40:42:56 | (...) ... | SinksExternal.cs:42:40:42:56 | (...) ... |
| SinksExternal.cs:43:51:43:63 | object creation of type ReqDto2 | SinksExternal.cs:43:51:43:63 | object creation of type ReqDto2 |
| SinksExternal.cs:44:89:44:101 | object creation of type ReqDto1 | SinksExternal.cs:44:89:44:101 | object creation of type ReqDto1 |
| SinksExternal.cs:45:64:45:76 | object creation of type ReqDto1 | SinksExternal.cs:45:64:45:76 | object creation of type ReqDto1 |
| SinksExternal.cs:46:64:46:75 | object creation of type Object | SinksExternal.cs:46:64:46:75 | object creation of type Object |
| SinksExternal.cs:48:55:48:66 | object creation of type Object | SinksExternal.cs:48:55:48:66 | object creation of type Object |
| SinksExternal.cs:49:77:49:88 | object creation of type Object | SinksExternal.cs:49:77:49:88 | object creation of type Object |
| SinksExternal.cs:51:25:51:36 | object creation of type Object | SinksExternal.cs:51:25:51:36 | object creation of type Object |
| SinksExternal.cs:52:26:52:37 | object creation of type Object | SinksExternal.cs:52:26:52:37 | object creation of type Object |
| SinksExternal.cs:53:25:53:36 | object creation of type Object | SinksExternal.cs:53:25:53:36 | object creation of type Object |
| SinksExternal.cs:54:24:54:35 | object creation of type Object | SinksExternal.cs:54:24:54:35 | object creation of type Object |
| SinksExternal.cs:56:38:56:49 | object creation of type Object | SinksExternal.cs:56:38:56:49 | object creation of type Object |
| SinksExternal.cs:57:28:57:40 | object creation of type ReqDto1 | SinksExternal.cs:57:28:57:40 | object creation of type ReqDto1 |
| SinksExternal.cs:58:31:58:42 | object creation of type Object | SinksExternal.cs:58:31:58:42 | object creation of type Object |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
from ExternalLocationSink sink
where
sink.getLocation().getFile().fromSource() and
not sink.getLocation().getFile().getAbsolutePath().matches("%/resources/stubs/%")
select sink, sink.getExpr()

View File

@@ -1 +1,3 @@
semmle-extractor-options: /nostdlib /noconfig --load-sources-from-project:../../../resources/stubs/ServiceStack/5.11.0/ServiceStack.csproj
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/ServiceStack/5.11.0/ServiceStack.csproj
semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/ServiceStack.OrmLite.SqlServer/5.11.0/ServiceStack.OrmLite.SqlServer.csproj

View File

@@ -0,0 +1,13 @@
| SinksXss.cs:11:36:11:42 | request | ServiceStack request parameter |
| SinksXss.cs:16:37:16:43 | request | ServiceStack request parameter |
| SinksXss.cs:23:39:23:41 | req | ServiceStack request parameter |
| SinksXss.cs:25:36:25:38 | req | ServiceStack request parameter |
| Sources.cs:11:34:11:40 | request | ServiceStack request parameter |
| Sources.cs:12:36:12:42 | request | ServiceStack request parameter |
| Sources.cs:13:36:13:42 | request | ServiceStack request parameter |
| Sources.cs:14:36:14:42 | request | ServiceStack request parameter |
| Sources.cs:15:36:15:42 | request | ServiceStack request parameter |
| Sources.cs:22:37:22:43 | request | ServiceStack request parameter |
| Sources.cs:23:48:23:54 | request | ServiceStack request parameter |
| Sources.cs:30:40:30:46 | request | ServiceStack request parameter |
| Sources.cs:35:36:35:42 | request | ServiceStack request parameter |

View File

@@ -0,0 +1,23 @@
| SinksSql.cs:25:28:25:32 | "SQL" | SinksSql.cs:25:28:25:32 | "SQL" |
| SinksSql.cs:26:29:26:33 | "SQL" | SinksSql.cs:26:29:26:33 | "SQL" |
| SinksSql.cs:27:32:27:36 | "SQL" | SinksSql.cs:27:32:27:36 | "SQL" |
| SinksSql.cs:28:31:28:35 | "SQL" | SinksSql.cs:28:31:28:35 | "SQL" |
| SinksSql.cs:29:27:29:31 | "SQL" | SinksSql.cs:29:27:29:31 | "SQL" |
| SinksSql.cs:30:32:30:36 | "SQL" | SinksSql.cs:30:32:30:36 | "SQL" |
| SinksSql.cs:31:31:31:35 | "SQL" | SinksSql.cs:31:31:31:35 | "SQL" |
| SinksSql.cs:32:30:32:34 | "SQL" | SinksSql.cs:32:30:32:34 | "SQL" |
| SinksSql.cs:37:28:37:32 | "SQL" | SinksSql.cs:37:28:37:32 | "SQL" |
| SinksSql.cs:38:29:38:33 | "SQL" | SinksSql.cs:38:29:38:33 | "SQL" |
| SinksSql.cs:39:27:39:31 | "SQL" | SinksSql.cs:39:27:39:31 | "SQL" |
| SinksSql.cs:40:31:40:35 | "SQL" | SinksSql.cs:40:31:40:35 | "SQL" |
| SinksSql.cs:41:30:41:34 | "SQL" | SinksSql.cs:41:30:41:34 | "SQL" |
| SinksSql.cs:48:58:48:62 | "SQL" | SinksSql.cs:48:58:48:62 | "SQL" |
| SinksSql.cs:49:65:49:69 | "SQL" | SinksSql.cs:49:65:49:69 | "SQL" |
| SinksSql.cs:51:39:51:43 | "SQL" | SinksSql.cs:51:39:51:43 | "SQL" |
| SinksSql.cs:52:46:52:50 | "SQL" | SinksSql.cs:52:46:52:50 | "SQL" |
| SinksSql.cs:54:29:54:33 | "SQL" | SinksSql.cs:54:29:54:33 | "SQL" |
| SinksSql.cs:55:40:55:44 | "SQL" | SinksSql.cs:55:40:55:44 | "SQL" |
| SinksSql.cs:64:42:64:49 | "script" | SinksSql.cs:64:42:64:49 | "script" |
| SinksSql.cs:65:28:65:35 | "script" | SinksSql.cs:65:28:65:35 | "script" |
| SinksSql.cs:70:54:70:61 | "script" | SinksSql.cs:70:54:70:61 | "script" |
| SinksSql.cs:71:38:71:45 | "script" | SinksSql.cs:71:38:71:45 | "script" |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.SqlInjectionQuery
from Sink sink
where
sink.getLocation().getFile().fromSource() and
not sink.getLocation().getFile().getAbsolutePath().matches("%/resources/stubs/%")
select sink, sink.getExpr()

View File

@@ -0,0 +1,3 @@
| SinksXss.cs:13:20:13:29 | "<script>" | SinksXss.cs:13:20:13:29 | "<script>" |
| SinksXss.cs:16:49:16:58 | "<script>" | SinksXss.cs:16:49:16:58 | "<script>" |
| SinksXss.cs:25:44:25:65 | object creation of type HttpResult | SinksXss.cs:25:44:25:65 | object creation of type HttpResult |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.XSSSinks
from Sink sink
where
sink.getLocation().getFile().fromSource() and
not sink.getLocation().getFile().getAbsolutePath().matches("%/resources/stubs/%")
select sink, sink.getExpr()