Skip to content

Commit 748b12c

Browse files
committed
Remove redundant files and add cases
- `service3nocds.js` had a service that was named differently. Clarified the gist of the file using tags. - `service4.js` was identical to `service3nocds.js`, except for the `cds.serve` call. This is better suited for `server.js`. - Since `HandlerParameterOfExposedService` is no longer a `RemoteFlowSource`, we place another query for testing it only. - The case categorization is as follows: - `service1`: Exposed service with reads from properties and method calls, some of which are tainted and not tainted. - `service2`: Service that both receives data from service1 and service4 but does not propagate it further. - `service3`: Service without a CDS declaration, simulating extraction failure. Should be recognized as exposed, from overapproximation. Consists of identical property reads / method calls as those of `service1`. - `service4`: Service that is explicitly declared as internal only. Consists of identical property reads / method calls as those of `service1`, but is not a taint source from being unexposed.
1 parent de09d59 commit 748b12c

File tree

10 files changed

+186
-47
lines changed

10 files changed

+186
-47
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import javascript
2+
import advanced_security.javascript.frameworks.cap.RemoteFlowSources
3+
4+
from HandlerParameterOfExposedService handlerParameterOfExposedService
5+
select handlerParameterOfExposedService

javascript/frameworks/cap/test/models/cds/remoteflowsources/server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ const cds = require("@sap/cds");
22
const app = require("express")();
33

44
cds.serve("all").in(app);
5+
6+
cds.serve('./some-service').with((srv) => {
7+
srv.before('READ', 'Books', (req) => req.reply([])) // SAFE: Exposed service (fallback), but not a taint source
8+
})

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service1.js

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,65 @@ const cds = require("@sap/cds");
44
module.exports = class Service1 extends cds.ApplicationService {
55
init() {
66
this.on("send1", async (req) => {
7-
const { messageToPass } = req.data;
7+
const { messageToPass } = req.data; // UNSAFE: Taint source, Exposed service
8+
const Service2 = await cds.connect.to("service-2");
9+
Service2.send("send2", { messageToPass });
10+
});
11+
12+
this.on("send2", async (req) => {
13+
const [ messageToPass ] = req.params; // UNSAFE: Taint source, Exposed service
14+
const Service2 = await cds.connect.to("service-2");
15+
Service2.send("send2", { messageToPass });
16+
});
17+
18+
this.on("send3", async (req) => {
19+
const messageToPass = req.headers["user-agent"]; // UNSAFE: Taint source, Exposed service
20+
const Service2 = await cds.connect.to("service-2");
21+
Service2.send("send2", { messageToPass });
22+
});
23+
24+
this.on("send4", async (req) => {
25+
const messageToPass1 = req.http.req.query.someProp; // UNSAFE: Taint source, Exposed service
26+
const messageToPass2 = req.http.req.body.someProp; // UNSAFE: Taint source, Exposed service
27+
const messageToPass3 = req.http.req.params.someProp; // UNSAFE: Taint source, Exposed service
28+
const messageToPass4 = req.http.req.headers.someProp; // UNSAFE: Taint source, Exposed service
29+
const messageToPass5 = req.http.req.cookies.someProp; // UNSAFE: Taint source, Exposed service
30+
const messageToPass6 = req.http.req.originalUrl; // UNSAFE: Taint source, Exposed service
31+
const messageToPass7 = req.http.req.hostname; // UNSAFE: Taint source, Exposed service
32+
const messageToPass8 = req.http.req.get("someProp"); // UNSAFE: Taint source, Exposed service
33+
const messageToPass9 = req.http.req.is("someProp"); // UNSAFE: Taint source, Exposed service
34+
const messageToPass10 = req.http.req.header("someProp"); // UNSAFE: Taint source, Exposed service
35+
const messageToPass11 = req.http.req.param("someProp"); // UNSAFE: Taint source, Exposed service
36+
const Service2 = await cds.connect.to("service-2"); // UNSAFE: Taint source, Exposed service
37+
Service2.send("send2", { messageToPass1 });
38+
});
39+
40+
this.on("send5", async (req) => {
41+
const messageToPass = req.id; // UNSAFE: Taint source, Exposed service
42+
const Service2 = await cds.connect.to("service-2");
43+
Service2.send("send2", { messageToPass });
44+
});
45+
46+
this.on("send6", async (req) => {
47+
const messageToPass = req.locale; // SAFE: Not a taint source, Exposed service
48+
const Service2 = await cds.connect.to("service-2");
49+
Service2.send("send2", { messageToPass });
50+
});
51+
52+
this.on("send7", async (req) => {
53+
const messageToPass = req.tenant; // SAFE: Not a taint source, Exposed service
54+
const Service2 = await cds.connect.to("service-2");
55+
Service2.send("send2", { messageToPass });
56+
});
57+
58+
this.on("send8", async (req) => {
59+
const messageToPass = req.timestamp; // SAFE: Not a taint source, Exposed service
60+
const Service2 = await cds.connect.to("service-2");
61+
Service2.send("send2", { messageToPass });
62+
});
63+
64+
this.on("send9", async (req) => {
65+
const messageToPass = req.user; // SAFE: Not a taint source, Exposed service
866
const Service2 = await cds.connect.to("service-2");
967
Service2.send("send2", { messageToPass });
1068
});

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service2.cds

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
using { advanced_security.log_injection.sample_entities as db_schema } from '../db/schema';
22

3-
/* Uncomment the line below to make the service hidden */
4-
// @protocol: 'none'
53
service Service2 @(path: '/service-2') {
6-
/* Entity to send READ/GET about. */
74
entity Service2Entity as projection on db_schema.Entity2 excluding { Attribute4 }
85

9-
/* API to talk to Service2. */
106
action send2 (
117
messageToPass: String
128
) returns String;

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service2.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
const cds = require("@sap/cds");
22

33
module.exports = cds.service.impl(function () {
4-
/* Log upon receiving an "send2" event. */
54
this.on("send2", async (msg) => {
6-
const { messageToPass } = msg.data;
7-
/* Do something with the received data; customize below to individual needs. */
5+
const { messageToPass } = msg.data; // UNSAFE: Taint source, Exposed service
86
const doSomething = console.log;
97
doSomething(messageToPass);
108
});
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// This service unit test is a replica of requesthandler.js
2+
const cds = require("@sap/cds");
3+
class Service3 extends cds.ApplicationService {
4+
init() {
5+
this.on("send1", async (req) => {
6+
const { messageToPass } = req.data; // UNSAFE: Taint source, Exposed service (fallback)
7+
const Service2 = await cds.connect.to("service-2");
8+
Service2.send("send2", { messageToPass });
9+
});
10+
11+
this.on("send2", async (req) => {
12+
const [ messageToPass ] = req.params; // UNSAFE: Taint source, Exposed service (fallback)
13+
const Service2 = await cds.connect.to("service-2");
14+
Service2.send("send2", { messageToPass });
15+
});
16+
17+
this.on("send3", async (req) => {
18+
const messageToPass = req.headers["user-agent"]; // UNSAFE: Taint source, Exposed service (fallback)
19+
const Service2 = await cds.connect.to("service-2");
20+
Service2.send("send2", { messageToPass });
21+
});
22+
23+
this.on("send4", async (req) => {
24+
const messageToPass1 = req.http.req.query.someProp; // UNSAFE: Taint source, Exposed service (fallback)
25+
const messageToPass2 = req.http.req.body.someProp; // UNSAFE: Taint source, Exposed service (fallback)
26+
const messageToPass3 = req.http.req.params.someProp; // UNSAFE: Taint source, Exposed service (fallback)
27+
const messageToPass4 = req.http.req.headers.someProp; // UNSAFE: Taint source, Exposed service (fallback)
28+
const messageToPass5 = req.http.req.cookies.someProp; // UNSAFE: Taint source, Exposed service (fallback)
29+
const messageToPass6 = req.http.req.originalUrl; // UNSAFE: Taint source, Exposed service (fallback)
30+
const messageToPass7 = req.http.req.hostname; // UNSAFE: Taint source, Exposed service (fallback)
31+
const messageToPass8 = req.http.req.get("someProp"); // UNSAFE: Taint source, Exposed service (fallback)
32+
const messageToPass9 = req.http.req.is("someProp"); // UNSAFE: Taint source, Exposed service (fallback)
33+
const messageToPass10 = req.http.req.header("someProp"); // UNSAFE: Taint source, Exposed service (fallback)
34+
const messageToPass11 = req.http.req.param("someProp"); // UNSAFE: Taint source, Exposed service (fallback)
35+
const Service2 = await cds.connect.to("service-2"); // UNSAFE: Taint source, Exposed service (fallback)
36+
Service2.send("send2", { messageToPass1 });
37+
});
38+
39+
this.on("send5", async (req) => {
40+
const messageToPass = req.id; // UNSAFE: Taint source, Exposed service (fallback)
41+
const Service2 = await cds.connect.to("service-2");
42+
Service2.send("send2", { messageToPass });
43+
});
44+
45+
this.on("send6", async (req) => {
46+
const messageToPass = req.locale; // SAFE: Not a taint source, Exposed service (fallback)
47+
const Service2 = await cds.connect.to("service-2");
48+
Service2.send("send2", { messageToPass });
49+
});
50+
51+
this.on("send7", async (req) => {
52+
const messageToPass = req.tenant; // SAFE: Not a taint source, Exposed service (fallback)
53+
const Service2 = await cds.connect.to("service-2");
54+
Service2.send("send2", { messageToPass });
55+
});
56+
57+
this.on("send8", async (req) => {
58+
const messageToPass = req.timestamp; // SAFE: Not a taint source, Exposed service (fallback)
59+
const Service2 = await cds.connect.to("service-2");
60+
Service2.send("send2", { messageToPass });
61+
});
62+
63+
this.on("send9", async (req) => {
64+
const messageToPass = req.user; // SAFE: Not a taint source, Exposed service (fallback)
65+
const Service2 = await cds.connect.to("service-2");
66+
Service2.send("send2", { messageToPass });
67+
});
68+
69+
return super.init()
70+
}
71+
}

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service3nocds.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service4.cds

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
using { advanced_security.log_injection.sample_entities as db_schema } from '../db/schema';
22

3+
@protocol: 'none' // NOTE: This service is internal use only.
34
service Service4 @(path: '/service-4') {
4-
/* Entity to send READ/GET about. */
55
entity Service4Entity as projection on db_schema.Entity4 excluding { Attribute4 }
66

7-
/* API to talk to other services. */
87
action send4 (
98
messageToPass: String
109
) returns String;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const cds = require("@sap/cds");
2+
3+
module.exports = class Service5 extends cds.ApplicationService {
4+
init() {
5+
this.on("send1", async (req) => {
6+
const { messageToPass } = req.data; // SAFE: Unexposed service, not a taint source
7+
const Service2 = await cds.connect.to("service-2");
8+
Service2.send("send2", { messageToPass });
9+
});
10+
11+
this.on("send2", async (req) => {
12+
const [ messageToPass ] = req.params; // SAFE: Unexposed service, not a taint source
13+
const Service2 = await cds.connect.to("service-2");
14+
Service2.send("send2", { messageToPass });
15+
});
16+
17+
this.on("send3", async (req) => {
18+
const messageToPass = req.headers["user-agent"]; // SAFE: Unexposed service, not a taint source
19+
const Service2 = await cds.connect.to("service-2");
20+
Service2.send("send2", { messageToPass });
21+
});
22+
23+
this.on("send4", async (req) => {
24+
const messageToPass1 = req.http.req.query.someProp; // SAFE: Unexposed service, not a taint source
25+
const messageToPass2 = req.http.req.body.someProp; // SAFE: Unexposed service, not a taint source
26+
const messageToPass3 = req.http.req.params.someProp; // SAFE: Unexposed service, not a taint source
27+
const messageToPass4 = req.http.req.headers.someProp; // SAFE: Unexposed service, not a taint source
28+
const messageToPass5 = req.http.req.cookies.someProp; // SAFE: Unexposed service, not a taint source
29+
const messageToPass6 = req.http.req.originalUrl; // SAFE: Unexposed service, not a taint source
30+
const messageToPass7 = req.http.req.hostname; // SAFE: Unexposed service, not a taint source
31+
const messageToPass8 = req.http.req.get("someProp"); // SAFE: Unexposed service, not a taint source
32+
const messageToPass9 = req.http.req.is("someProp"); // SAFE: Unexposed service, not a taint source
33+
const messageToPass10 = req.http.req.header("someProp"); // SAFE: Unexposed service, not a taint source
34+
const messageToPass11 = req.http.req.param("someProp"); // SAFE: Unexposed service, not a taint source
35+
const Service2 = await cds.connect.to("service-2"); // SAFE: Unexposed service, not a taint source
36+
Service2.send("send2", { messageToPass1 });
37+
});
38+
39+
this.on("send5", async (req) => {
40+
const messageToPass = req.id; // SAFE: Unexposed service, not a taint source
41+
const Service2 = await cds.connect.to("service-2");
42+
Service2.send("send2", { messageToPass });
43+
});
44+
}
45+
};

javascript/frameworks/cap/test/models/cds/remoteflowsources/srv/service4withcds.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)