File tree Expand file tree Collapse file tree
test/experimental/Security/CWE-942 Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ /**
2+ * Provides classes for working with Cors connectors.
3+ */
4+
5+ import javascript
6+
7+ /** Provides classes modeling [cors package](https://npmjs.com/package/cors) */
8+ module Cors {
9+ class Cors extends DataFlow:: CallNode {
10+ /** Get an instanceof of `cors` */
11+ Cors ( ) { this = DataFlow:: moduleImport ( "cors" ) .getAnInvocation ( ) }
12+
13+ /** Get Cors configuration */
14+ DataFlow:: Node getCorsArgument ( ) { result = this .getArgument ( 0 ) }
15+
16+ /** Holds if cors is using default configuration */
17+ predicate isDefault ( ) { this .getNumArgument ( ) = 0 }
18+
19+ /** The value of origin */
20+ DataFlow:: Node getOrigin ( ) {
21+ result = this .getCorsArgument ( ) .getALocalSource ( ) .getAPropertyWrite ( "origin" ) .getRhs ( )
22+ }
23+ }
24+ }
Original file line number Diff line number Diff line change 55import javascript
66import semmle.javascript.frameworks.HTTP
77import semmle.javascript.frameworks.ExpressModules
8+ import semmle.javascript.frameworks.Cors
89private import semmle.javascript.dataflow.InferredTypes
910private import semmle.javascript.frameworks.ConnectExpressShared:: ConnectExpressShared
1011
@@ -1071,4 +1072,23 @@ module Express {
10711072
10721073 override predicate definitelyResumesDispatch ( ) { none ( ) }
10731074 }
1075+
1076+ class CorsConfiguration extends DataFlow:: MethodCallNode {
1077+ /** Get an `app.use` with a cors object as argument */
1078+ CorsConfiguration ( ) {
1079+ this = appCreation ( ) .getAMethodCall ( "use" ) and this .getArgument ( 0 ) instanceof Cors:: Cors
1080+ }
1081+
1082+ /** Get Cors */
1083+ private Cors:: Cors cors ( ) { result = this .getArgument ( 0 ) .( Cors:: Cors ) }
1084+
1085+ /** Get Cors configuration */
1086+ DataFlow:: Node getCorsArgument ( ) { result = cors ( ) .getCorsArgument ( ) }
1087+
1088+ /** Holds if cors is using default configuration */
1089+ predicate isDefault ( ) { cors ( ) .isDefault ( ) }
1090+
1091+ /** Get Cors origin value */
1092+ DataFlow:: Node getOrigin ( ) { result = cors ( ) .getOrigin ( ) }
1093+ }
10741094}
Original file line number Diff line number Diff line change @@ -44,4 +44,11 @@ module CorsPermissiveConfiguration {
4444 )
4545 }
4646 }
47+
48+ /**
49+ * The value of cors origin when initializing the application.
50+ */
51+ class ExpressCors extends Sink , DataFlow:: ValueNode {
52+ ExpressCors ( ) { exists ( Express:: CorsConfiguration config | this = config .getOrigin ( ) ) }
53+ }
4754}
File renamed without changes.
Original file line number Diff line number Diff line change 1+ const cors = require('cors');
2+ var express = require('express');
3+
4+ var https = require('https'),
5+ url = require('url');
6+
7+ var server = https.createServer(function () { });
8+
9+ server.on('request', function (req, res) {
10+ let user_origin = url.parse(req.url, true).query.origin;
11+
12+ // BAD: CORS too permissive, default value is *
13+ var app1 = express();
14+ app1.use(cors());
15+
16+ // GOOD: restrictive CORS
17+ var app2 = express();
18+ var corsOptions2 = {
19+ origin: ["https://example1.com", "https://example2.com"],
20+ };
21+ app2.use(cors(corsOptions2));
22+
23+ // BAD: CORS too permissive
24+ var app3 = express();
25+ var corsOption3 = {
26+ origin: '*'
27+ };
28+ app3.use(cors(corsOption3));
29+
30+ // BAD: CORS is controlled by user
31+ var app4 = express();
32+ var corsOption4 = {
33+ origin: user_origin
34+ };
35+ app4.use(cors(corsOption4));
36+ });
You can’t perform that action at this time.
0 commit comments