@@ -17,91 +17,113 @@ import csharp
1717import semmle.code.asp.WebConfig
1818import semmle.code.csharp.frameworks.system.Web
1919import semmle.code.csharp.frameworks.microsoft.AspNetCore
20- deprecated import experimental.dataflow.flowsources.AuthCookie
20+ import experimental.dataflow.flowsources.AuthCookie
2121
22- deprecated query predicate problems ( Expr secureSink , string message ) {
22+ predicate cookieAppendSecureByDefault ( ) {
23+ // default is set to `Always` or `SameAsRequest`
2324 (
24- exists ( Call c |
25- secureSink = c and
26- (
27- // default is not configured or is not set to `Always` or `SameAsRequest`
28- not (
29- getAValueForCookiePolicyProp ( "Secure" ) .getValue ( ) = "0" or
30- getAValueForCookiePolicyProp ( "Secure" ) .getValue ( ) = "1"
31- ) and
32- // there is no callback `OnAppendCookie` that sets `Secure` to true
33- not OnAppendCookieSecureTracking:: flowTo ( _) and
34- (
35- // `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
36- exists ( ObjectCreation oc |
37- oc = c and
38- oc .getType ( ) instanceof MicrosoftAspNetCoreHttpCookieOptions and
39- not isPropertySet ( oc , "Secure" ) and
40- exists ( DataFlow:: Node creation |
41- CookieOptionsTracking:: flow ( creation , _) and
42- creation .asExpr ( ) = oc
43- )
44- )
45- or
46- // IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
47- exists ( MethodCall mc , MicrosoftAspNetCoreHttpResponseCookies iResponse |
48- mc = c and
49- iResponse .getAppendMethod ( ) = mc .getTarget ( ) and
50- mc .getNumberOfArguments ( ) < 3
51- )
52- )
53- or
54- exists ( ObjectCreation oc |
55- oc = c and
56- oc .getType ( ) instanceof SystemWebHttpCookie and
57- // the property wasn't explicitly set, so a default value from config is used
58- not isPropertySet ( oc , "Secure" ) and
59- // the default in config is not set to `true`
60- // the `exists` below covers the `cs/web/requiressl-not-set`
61- not exists ( XmlElement element |
62- element instanceof FormsElement and
63- element .( FormsElement ) .isRequireSsl ( )
64- or
65- element instanceof HttpCookiesElement and
66- element .( HttpCookiesElement ) .isRequireSsl ( )
67- )
68- )
69- )
25+ getAValueForCookiePolicyProp ( "Secure" ) .getValue ( ) = "0" or
26+ getAValueForCookiePolicyProp ( "Secure" ) .getValue ( ) = "1"
27+ )
28+ or
29+ //callback `OnAppendCookie` that sets `Secure` to true
30+ OnAppendCookieSecureTracking:: flowTo ( _)
31+ }
32+
33+ predicate insecureCookieOptionsCreation ( Expr sink ) {
34+ // `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
35+ exists ( ObjectCreation oc |
36+ oc = sink and
37+ oc .getType ( ) instanceof MicrosoftAspNetCoreHttpCookieOptions and
38+ not isPropertySet ( oc , "Secure" ) and
39+ exists ( DataFlow:: Node creation |
40+ CookieOptionsTracking:: flow ( creation , _) and
41+ creation .asExpr ( ) = oc
7042 )
43+ )
44+ }
45+
46+ predicate insecureCookieAppend ( Expr sink ) {
47+ // IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
48+ exists ( MethodCall mc , MicrosoftAspNetCoreHttpResponseCookies iResponse |
49+ mc = sink and
50+ iResponse .getAppendMethod ( ) = mc .getTarget ( ) and
51+ mc .getNumberOfArguments ( ) < 3
52+ )
53+ }
54+
55+ predicate insecureCookieCreationFromConfig ( Expr sink ) {
56+ // `Secure` property in `System.Web.HttpCookie` wasn't set, so a default value from config is used
57+ exists ( ObjectCreation oc |
58+ oc = sink and
59+ oc .getType ( ) instanceof SystemWebHttpCookie and
60+ not isPropertySet ( oc , "Secure" ) and
61+ // the default in config is not set to `true`
62+ // the `exists` below covers the `cs/web/requiressl-not-set`
63+ not exists ( XmlElement element |
64+ element instanceof FormsElement and
65+ element .( FormsElement ) .isRequireSsl ( )
66+ or
67+ element instanceof HttpCookiesElement and
68+ element .( HttpCookiesElement ) .isRequireSsl ( )
69+ )
70+ )
71+ }
72+
73+ predicate insecureCookieCall ( Call c ) {
74+ not cookieAppendSecureByDefault ( ) and
75+ (
76+ insecureCookieOptionsCreation ( c )
7177 or
72- exists ( Assignment a , Expr val |
73- secureSink = a .getRValue ( ) and
74- (
75- exists ( ObjectCreation oc |
76- getAValueForProp ( oc , a , "Secure" ) = val and
77- val .getValue ( ) = "false" and
78- (
79- oc .getType ( ) instanceof SystemWebHttpCookie
80- or
81- oc .getType ( ) instanceof MicrosoftAspNetCoreHttpCookieOptions and
82- // there is no callback `OnAppendCookie` that sets `Secure` to true
83- not OnAppendCookieSecureTracking:: flowTo ( _) and
84- // the cookie option is passed to `Append`
85- exists ( DataFlow:: Node creation |
86- CookieOptionsTracking:: flow ( creation , _) and
87- creation .asExpr ( ) = oc
88- )
89- )
90- )
91- or
92- exists ( PropertyWrite pw |
93- (
94- pw .getProperty ( ) .getDeclaringType ( ) instanceof MicrosoftAspNetCoreHttpCookieBuilder or
95- pw .getProperty ( ) .getDeclaringType ( ) instanceof
96- MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
97- ) and
98- pw .getProperty ( ) .getName ( ) = "SecurePolicy" and
99- a .getLValue ( ) = pw and
100- DataFlow:: localExprFlow ( val , a .getRValue ( ) ) and
101- val .getValue ( ) = "2" // None
102- )
78+ insecureCookieAppend ( c )
79+ )
80+ or
81+ insecureCookieCreationFromConfig ( c )
82+ }
83+
84+ predicate insecureCookieCreationAssignment ( Assignment a , Expr val ) {
85+ exists ( ObjectCreation oc |
86+ getAValueForProp ( oc , a , "Secure" ) = val and
87+ val .getValue ( ) = "false" and
88+ (
89+ oc .getType ( ) instanceof SystemWebHttpCookie
90+ or
91+ oc .getType ( ) instanceof MicrosoftAspNetCoreHttpCookieOptions and
92+ // there is no callback `OnAppendCookie` that sets `Secure` to true
93+ not OnAppendCookieSecureTracking:: flowTo ( _) and
94+ // the cookie option is passed to `Append`
95+ exists ( DataFlow:: Node creation |
96+ CookieOptionsTracking:: flow ( creation , _) and
97+ creation .asExpr ( ) = oc
10398 )
10499 )
105- ) and
106- message = "Cookie attribute 'Secure' is not set to true."
100+ )
107101}
102+
103+ predicate insecureSecurePolicyAssignment ( Assignment a , Expr val ) {
104+ exists ( PropertyWrite pw |
105+ (
106+ pw .getProperty ( ) .getDeclaringType ( ) instanceof MicrosoftAspNetCoreHttpCookieBuilder or
107+ pw .getProperty ( ) .getDeclaringType ( ) instanceof
108+ MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
109+ ) and
110+ pw .getProperty ( ) .getName ( ) = "SecurePolicy" and
111+ a .getLValue ( ) = pw and
112+ DataFlow:: localExprFlow ( val , a .getRValue ( ) ) and
113+ val .getValue ( ) = "2" // None
114+ )
115+ }
116+
117+ from Expr secureSink
118+ where
119+ insecureCookieCall ( secureSink )
120+ or
121+ exists ( Assignment a |
122+ secureSink = a .getRValue ( ) and
123+ (
124+ insecureCookieCreationAssignment ( a , _)
125+ or
126+ insecureSecurePolicyAssignment ( a , _)
127+ )
128+ )
129+ select secureSink , "Cookie attribute 'Secure' is not set to true."
0 commit comments