Skip to content

Instantly share code, notes, and snippets.

@kevin-montrose
Created September 23, 2019 20:59
Show Gist options
  • Save kevin-montrose/8d5e50fab94fe0e77f3597468c627f61 to your computer and use it in GitHub Desktop.
Save kevin-montrose/8d5e50fab94fe0e77f3597468c627f61 to your computer and use it in GitHub Desktop.
Example SecurityCodeScan configuration file from Stack Overflow codebase
# This is based on https://github.com/security-code-scan/security-code-scan/blob/master/SecurityCodeScan/Config/Main.yml
# IMPORTANT: YML is very strict about indentation and white spaces
Version: 2.1
# Set to 'true' to see more warnings
AuditMode: false
# Allows to define custom anti CSRF attributes and conditions
CsrfProtection:
- Name: Stack Overflow Routing
AntiCsrfAttributes:
- Name: StackOverflow.Helpers.XSRFSafeAttribute
Class:
Name:
- StackOverflow.Controllers.StackOverflowController
Attributes:
Exclude:
- Name: StackOverflow.Helpers.InternalAPIControllerAttribute
Method:
Attributes:
Include:
- Name: StackOverflow.Helpers.StackRouteAttribute
Condition: { 1: { Value: 2 }, EnsureXSRFSafe: { Value: false } } # Post
- Name: StackOverflow.Helpers.StackRouteAttribute
Condition: { 1: { Value: 4 }, EnsureXSRFSafe: { Value: false } } # Put
- Name: StackOverflow.Helpers.StackRouteAttribute
Condition: { 1: { Value: 8 }, EnsureXSRFSafe: { Value: false } } # Delete
- Name: StackOverflow.Helpers.StackRouteAttribute
Condition: { 1: { Value: 32 }, EnsureXSRFSafe: { Value: false } } # Patch
Behavior:
# The section describes various types of API behavior:
# 1) Sinks - vulnerable API where untrusted input data can be injected.
# 2) Sanitizers - API that filters/encodes/escapes - in other words sanitizes the unsafe data and produces the safe output.
# 3) Validators - API that doesn't change the input data,
# but validates and it is safe to assume after the call that the input satisfies safety requirements.
# 4) Ignores - safe API that is known to return trusted output.
# 5) Pass-through - rules that describe how taint from input parameters is passed to output parameters.
# With the rules analysis is more accurate. All undocumented API by default returns Tainted if any parameter is tainted or Unknown taint otherwise.
# 6) Taint sources - API where tainted/unsafe data enters the program (like cookies, headers, etc.)
#
# The format to describe all these rules is:
# <<<
# [Unique ID]:
# Namespace: (Optional) [Namespace where the class is present]
# ClassName: [Class of the API]
# Name: (Optional) [Class member name. If not specified applies to all members of the class]
# Method: (If it describes a function. Required if child properties are provided, otherwise optional)
# ArgTypes: (Optional) [Function arguments signature. If not specified applies to all overloads]
# InjectableArguments: (Optional) [Warning ID, argument index and taint type this possible format:
# [SCS0018: [0: AbsolutePath, 1: AbsolutePath]] or
# [SCS0018: [0: AbsolutePath]] or
# [SCS0018: 0]
# Analyzer shows a warning if tainted/unsafe date is passed to the API.
# For example InjectableArguments: [HtmlEscaped: 0]
# Means the first argument must be HtmlEscaped to keep analyzer silent.]
# If: (Optional) (Precondition)
# Condition: (The condition to check, can be one liner like 'Condition: {1: {Value: 2}}')
# [Argument index]:
# Value: [Apply 'Then' part only if it equals to the value. Only strings and integers (even if it is an enum) are accepted.]
# Then:
# ['Returns' or Argument index]:
# Taint: (Optional) [Registered TaintType, see above or reserved taint type keyword] (If not specified 'Taint:' value from unconditional part is taken)
# TaintFromArguments: (Optional) [Argument index or comma separated list of indices] (Arguments to transfer taint from to specified output. If not specified 'TaintFromArguments:' value from uncoditional part is taken)
# ['Returns' or Argument index]:
# Taint: (Optional) [Single value or array of 'TaintTypes' (see the section above) to apply additionally to 'TaintFromArguments' or special keyword 'Safe'.
# Sanitizers may apply the value to mark it as sanitized.
# Taint sources may apply special keyword 'Tainted' to mark the value as untrusted.]
# TaintFromArguments: (Optional) [Single value or array of parameter indices that influence the taint of the output value.]
# Field: (If it describes a property or field. Required if child properties are provided, otherwise optional)
# Injectable: (Optional) [true or TaintType, similar to InjectableArguments, but for class member fields or setters.]
# <<<
#
# StackOverflowController Redirects
StackOverflowController.Redirect:
Namespace: StackOverflow.Controllers
ClassName: StackOverflowController
Name: Redirect
Method:
ArgTypes: "(System.String, System.Boolean, System.Boolean)"
Condition: {2: { Value: True } } # allowExternal: true
InjectableArguments: [SCS0027: 0]
StackOverflowController.RedirectPermanent:
Namespace: StackOverflow.Controllers
ClassName: StackOverflowController
Name: RedirectPermanent
Method:
ArgTypes: "(System.String, System.Boolean, System.Boolean)"
Condition: {2: { Value: True } } # allowExternal: true
InjectableArguments: [SCS0027: 0]
# StackExchangeController Redirects
StackExchangeController.Redirect:
Namespace: StackExchangeController.Website.Controllers
ClassName: StackExchangeController
Name: Redirect
Method:
ArgTypes: "(System.String, System.Boolean)"
Condition: {1: { Value: True } } # allowExternal: true
InjectableArguments: [SCS0027: 0]
StackExchangeController.RedirectPermanent:
Namespace: StackExchangeController.Website.Controllers
ClassName: StackExchangeController
Name: RedirectPermanent
Method:
ArgTypes: "(System.String, System.Boolean)"
Condition: {1: { Value: True } } # allowExternal: true
InjectableArguments: [SCS0027: 0]
# Sanitizes for redirect purposes
Site.Url:
Namespace: StackOverflow.Models
ClassName: Site
Name: Url
Method:
Returns:
Taint: Safe
TaintFromArguments: [0]
# Sanitizes for redirect purposes
Site.UrlRelative:
Namespace: StackOverflow
ClassName: CommonExtensionMethods
Name: UrlRelative
Method:
Returns:
Taint: Safe
TaintFromArguments: [1]
UrlUtil.AssertInNetwork:
Namespace: StackOverflow.Helpers
ClassName: UrlUtil
Name: AssertInNetwork
Method:
Returns:
Taint: Safe
TaintFromArguments: [0]
# Dapper
Dapper.SqlMapper_Execute:
Namespace: Dapper
ClassName: SqlMapper
Name: Execute
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_ExecuteAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: ExecuteAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_ExecuteReader:
Namespace: Dapper
ClassName: SqlMapper
Name: ExecuteReader
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_ExecuteReaderAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: ExecuteReaderAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
# also covers generic ExecuteScalar
Dapper.SqlMapper_ExecuteScalar:
Namespace: Dapper
ClassName: SqlMapper
Name: ExecuteScalar
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
# also covers generic ExecuteScalarAsync
Dapper.SqlMapper_ExecuteScalarAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: ExecuteScalarAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryWithMapper:
Namespace: Dapper
ClassName: SqlMapper
Name: Query
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Func, System.Object, System.Data.IDbTransaction, System.Boolean, System.String, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryWithMapperAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Func, System.Object, System.Data.IDbTransaction, System.Boolean, System.String, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
# also covers dynamic returning Query
Dapper.SqlMapper_Query:
Namespace: Dapper
ClassName: SqlMapper
Name: Query
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Boolean, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
# also covers dynamic returning QueryAsync
Dapper.SqlMapper_QueryAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryFirst:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryFirst
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryFirstAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryFirstAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryFirstOrDefault:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryFirstOrDefault
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryFirstOrDefaultAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryFirstOrDefaultAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryMultiple:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryMultiple
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QueryMultipleAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QueryMultipleAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QuerySingle:
Namespace: Dapper
ClassName: SqlMapper
Name: QuerySingle
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QuerySingleAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QuerySingleAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QuerySingleOrDefault:
Namespace: Dapper
ClassName: SqlMapper
Name: QuerySingleOrDefault
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.SqlMapper_QuerySingleOrDefaultAsync:
Namespace: Dapper
ClassName: SqlMapper
Name: QuerySingleOrDefaultAsync
Method:
ArgTypes: "(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?)"
InjectableArguments: [SCS0014: 1]
Dapper.CommandDefinition_Constructor:
Namespace: Dapper
ClassName: CommandDefinition
Name: .ctor
Method:
ArgTypes: "(System.String, System.Object, System.Data.IDbTransaction, System.Int32?, System.Data.CommandType?, Dapper.CommandFlags, System.Threading.CancellationToken)"
InjectableArguments: [SCS0014: 0]
# SqlBuilder
SqlBuilder.AddTemplate:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: AddTemplate
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.LeftJoin:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: LeftJoin
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Where:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Where
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.WhereOr:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: WhereOr
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.OrderBy:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: OrderBy
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Select:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Select
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Join:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Join
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.GroupBy:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: GroupBy
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Having:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Having
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Options:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Options
Method:
InjectableArguments: [SCS0014: 0]
SqlBuilder.Union:
Namespace: StackOverflow.Helpers.Dapper
ClassName: SqlBuilder
Name: Union
Method:
InjectableArguments: [SCS0014: 0]
# StackDbContext
StackDbContext.ExecuteAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: ExecuteAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.Execute:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: Execute
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.ExecuteReader:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: ExecuteReader
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.Query:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: Query
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryUnbuffered:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryUnbuffered
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryFirstAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryFirstAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryFirst:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryFirst
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryFirstOrDefaultAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryFirstOrDefaultAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryFirstOrDefault:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryFirstOrDefault
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QuerySingleAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QuerySingleAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QuerySingle:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QuerySingle
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QuerySingleOrDefaultAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QuerySingleOrDefaultAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QuerySingleOrDefault:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QuerySingleOrDefault
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryMultipleAsync:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryMultipleAsync
Method:
InjectableArguments: [SCS0014: 0]
StackDbContext.QueryMultiple:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: QueryMultiple
Method:
InjectableArguments: [SCS0014: 0]
# StackExchangeDBContext
StackExchangeDBContext.ExecuteAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: ExecuteAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.Execute:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: Execute
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.ExecuteReader:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: ExecuteReader
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.Query:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: Query
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryUnbuffered:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryUnbuffered
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryFirstAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryFirstAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryFirst:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryFirst
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryFirstOrDefaultAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryFirstOrDefaultAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryFirstOrDefault:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryFirstOrDefault
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QuerySingleAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QuerySingleAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QuerySingle:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QuerySingle
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QuerySingleOrDefaultAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QuerySingleOrDefaultAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QuerySingleOrDefault:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QuerySingleOrDefault
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryMultipleAsync:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryMultipleAsync
Method:
InjectableArguments: [SCS0014: 0]
StackExchangeDBContext.QueryMultiple:
Namespace: StackExchange.Website.Models
ClassName: StackExchangeDBContext
Name: QueryMultiple
Method:
InjectableArguments: [SCS0014: 0]
# Sanitizes SQL
DataEditorWorkset.Constructor:
Namespace: StackOverflow.Controllers
ClassName: DataEditorWorkset
Name: .ctor
Method:
ArgTypes: "(System.String, System.Int32?)"
Returns:
Taint: Safe
# Sanitizes the passed form, so doesn't taint
DataEditorWorkset.ParseFormIntoRow:
Namespace: StackOverflow.Controllers
ClassName: DataEditorWorkset
Name: ParseFormIntoRow
Method:
Returns:
Taint: Safe
# generated SQL is safe
HaproxyLogsQuery.ToString:
Namespace: StackOverflow.Controllers
ClassName: HaproxyLogsQuery
Name: ToString
Method:
Returns:
Taint: Safe
# generated SQL is safe
UsersController.BuildStatusClause:
Namespace: StackOverflow.Controllers
ClassName: UsersController
Name: BuildStatusClause
Method:
Returns:
Taint: Safe
# cleans a tag up to be SQL safe
SE.Tag.Sanitize:
Namespace: StackExchange.Website.Models
ClassName: Tag
Name: Sanitize
Method:
Returns:
Taint: Safe
# cleans a tag up to be SQL safe
SE.Tag.SanitizeUserTags:
Namespace: StackExchange.Website.Models
ClassName: Tag
Name: SanitizeUserTags
Method:
Returns:
Taint: Safe
# Inserts
StackDbContext.Insert:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: Insert
Method:
ArgTypes: "(System.String, dynamic)"
InjectableArguments: [SCS0014: 0]
StackDbContext.InsertWithIdentity:
Namespace: StackOverflow.Models
ClassName: StackDbContext
Name: InsertWithIdentity
Method:
ArgTypes: "(System.String, dynamic, System.Boolean, System.Boolean)"
InjectableArguments: [SCS0014: 0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment