Skip to content

Commit 277f6c2

Browse files
Merge pull request #138 from advanced-security/jeongsoolee09/authn-queries-help
Add help files to Authentication/Authorization queries
2 parents 6d548c0 + 65c7695 commit 277f6c2

File tree

14 files changed

+208
-8
lines changed

14 files changed

+208
-8
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Default User is overwritten as privileged
2+
3+
Users that cannot be verified as authenticated are represented as `cds.User.default` internally. Setting this property to `cds.User.Privileged` may result in providing protected assets to unauthorized users.
4+
5+
## Recommendation
6+
7+
### Set up a development profile that uses non-production authentication
8+
9+
Overwriting `cds.User.default` as `cds.User.Privileged` for testing purposes is not recommended as such code may easily slip through production.
10+
11+
Instead, set up a development profile and opt in to use a non-production strategy such as `"basic"`, `"dummy"`, or `"mocked"` during its use. This can be done in the file `package.json` in the root folder of the CAP application:
12+
13+
``` json
14+
{
15+
"requires": {
16+
"[dev]": {
17+
"auth": "dummy"
18+
}
19+
}
20+
}
21+
```
22+
23+
Setting `"dummy"` as the development authentication strategy has the effect of disabling `@requires` and `@restrict` annotations of CDS definitions that provides authorization. The application during development then can be run and tested with the `--profile dev` option.
24+
25+
```shell
26+
cds serve --profile dev
27+
```
28+
29+
## Example
30+
31+
Setting `cds.User.default` to `cds.User.Privileged` may happen anywhere in the application. In the following example, the `server.js` file provides the top-level definition of a CAP application and overwrites the `default` user property with the `Privileged` class.
32+
33+
``` javascript
34+
const cds = require("@sap/cds");
35+
const app = require("express")();
36+
37+
/*
38+
* Antipattern: `cds.User.default` is overwritten to `cds.User.Privileged`
39+
*/
40+
cds.User.default = cdsUser.Privileged;
41+
42+
cds.serve("all").in(app);
43+
```
44+
45+
## References
46+
47+
- SAP CAPire Documentation: [cds.User.default](https://cap.cloud.sap/docs/node.js/authentication#default-user).
48+
- SAP CAPire Documentation: [cds.User.Privileged](https://cap.cloud.sap/docs/node.js/authentication#privileged-user).
49+
- SAP CAPire Documentation: [Authentication Strategies](https://cap.cloud.sap/docs/node.js/authentication#strategies).
50+
- Common Weakness Enumeration: [CWE-250](https://cwe.mitre.org/data/definitions/250.html).
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# CAP Definitions Exposed without Access Controls
2+
3+
Although using a production-level authentication strategy such as `jwt` ensures that all entities and services require the user to be authenticated, this does not guarantee any further authorization. Furthermore, the lack of required authentication or authorization may imply a gap in the design of the system.
4+
5+
## Recommendation
6+
7+
### Use CDS-based authorization
8+
9+
CDL provides two annotations to declare access controls `@requires` and `@restrict` with the latter providing more granularity than the former. For example, to check if a request is being made by an authenticated user to the CDL entity or service, annotate it with `@requires: 'authenticated-user'`. On the other hand, if it needs to be read only via a certain group of users where the user has level greater than 2, use `@restrict: { grant: 'READ', to: 'SomeUser', where: { $user.level > 2 } }` (note the leading `$`).
10+
11+
#### Check the original CDS entity it is derived from
12+
13+
CDS entities may be derived from other entities by means of selection and projection. Derived definitions inherit access control conditions and optionally override them. In order to accurately determine what authorization an entity requires, the access control of the parent entity should be transitively inspected.
14+
15+
### Enforce authorization with JavaScript
16+
17+
Access control may be enforced when a request handler for the relevant entity or service is registered. Both `cds.Service.before` and `cds.Service.on` may be used for enforcement. For example, to restrict writing to and updating an entity to a user satisfying certain requirements, either one of the below handler registrations may be used:
18+
19+
``` javascript
20+
/**
21+
* Before serving a request to access SomeEntity, check if the request is coming from a user
22+
* with SomeRole and level greater than 3.
23+
*/
24+
this.before(["WRITE", "UPDATE"], "SomeEntity", (req) => {
25+
(req.user.is("SomeRole") && req.user.attr.level > 3) || req.reject(403);
26+
});
27+
28+
/**
29+
* On request to access SomeEntity, check if the request is coming from a user
30+
* with SomeRole and level greater than 3.
31+
*/
32+
this.on(["WRITE", "UPDATE"], "SomeEntity", (req) => {
33+
if (req.user.is("SomeRole") && req.user.attr.level > 3) {
34+
/* Do something */
35+
} else req.reject(403);
36+
});
37+
```
38+
39+
## Examples
40+
41+
The following CDS definition and its JavaScript implementation imposes no authorization on `SomeEntity`. Note that the `OriginalEntity` from which `DerivedEntity` derives from does not control the access either.
42+
43+
### db/schema.cds
44+
45+
``` cap-cds
46+
namespace sample_namespace.sample_entities;
47+
48+
entity OriginalEntity {
49+
Attribute1 : String(100);
50+
Attribute2 : String(100)
51+
}
52+
```
53+
54+
### srv/service1.cds
55+
56+
``` cap-cds
57+
using { sample_namespace.sample_entities as db_schema } from '../db/schema';
58+
59+
service SomeService {
60+
entity DerivedEntity as projection on db_schema.OriginalEntity excluding { Attribute2 }
61+
}
62+
```
63+
64+
### srv/service1.js
65+
66+
``` javascript
67+
68+
const cds = require("@sap/cds");
69+
70+
module.exports = class Service1 extends cds.ApplicationService {
71+
init() {
72+
this.on("READ", "SomeService", (req) => { })
73+
}
74+
}
75+
```
76+
77+
## References
78+
79+
- SAP CAPire Documentation: [Authorization Enforcement](https://cap.cloud.sap/docs/node.js/authentication#enforcement).
80+
- SAP CAPire Documentation: [@restrict](https://cap.cloud.sap/docs/guides/security/authorization#restrict-annotation).
81+
- SAP CAPire Documentation:
82+
[@requires](https://cap.cloud.sap/docs/guides/security/authorization#requires).
83+
- SAP CAPire Documentation: [Protecting Certain Entries](https://cap.cloud.sap/docs/cds/common#protecting-certain-entries).
84+
- SAP CAPire Documentation: [Inheritance of Restrictions](https://cap.cloud.sap/docs/guides/security/authorization#inheritance-of-restrictions).
85+
- SAP CAPire Documentation: [Authentication Enforced in Production](https://cap.cloud.sap/docs/node.js/authentication#authentication-enforced-in-production).
86+
- Common Weakness Enumeration: [CWE-862](https://cwe.mitre.org/data/definitions/862.html).
87+
- Common Weakness Enumeration: [CWE-306](https://cwe.mitre.org/data/definitions/306.html).
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Non-Production Authentication Strategy Used without Profiles
2+
3+
Using a non-production authentication strategy without setting up a distinct profile for development may pose allow unintended authentication and/or authorization if the application is deployed into production.
4+
5+
## Recommendation
6+
7+
### Isolate the use of development-level strategies to a development profile
8+
9+
Use separate profiles for development and deployment and select one as needed. In this way, properties including authentication strategies can be substituted by changing a single command line option: `--profile`. For example, having the following section in the application's `package.json` states that the `"dummy"` authentication strategy must be used while `"xsuaa"`, a production-grade strategy, should be used when deployed:
10+
11+
``` json
12+
{
13+
"requires": {
14+
"[dev]": {
15+
"auth": "dummy"
16+
},
17+
"[deploy]": {
18+
"auth": "xsuaa"
19+
}
20+
}
21+
}
22+
```
23+
24+
The application can be now run in different modes depending on the `--profile` command line option:
25+
26+
``` shell
27+
$ cds serve --profile dev # Runs the application in development profile with strategy "dummy"
28+
$ cds serve --profile deploy # Runs the application in development profile with strategy "xsuaa"
29+
```
30+
31+
## Example
32+
33+
The following CAP application states that it uses `"basic"` authentication strategy along with mocked credentials. Using the pair of username and password, an attacker can gain access to certain assets by signing in to the application.
34+
35+
``` json
36+
{
37+
"cds": {
38+
"requires": {
39+
"auth": {
40+
"kind": "basic",
41+
"users": {
42+
"JohnDoe": {
43+
"password": "JohnDoesPassword",
44+
"roles": ["JohnDoesRole"],
45+
"attr": {}
46+
},
47+
"JaneDoe": {
48+
"password": "JaneDoesPassword",
49+
"roles": ["JaneDoesRole"],
50+
"attr": {}
51+
}
52+
}
53+
}
54+
}
55+
}
56+
}
57+
```
58+
59+
## References
60+
61+
- Common Weakness Enumeration: [CWE-288](https://cwe.mitre.org/data/definitions/288.html).
62+
- Common Weakness Enumeration: [CWE-798](https://cwe.mitre.org/data/definitions/798.html).
63+
- SAP CAPire Documentation: [Authentication Strategies](https://cap.cloud.sap/docs/node.js/authentication#strategies).
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/EntityExposedWithoutAuthn.ql
1+
bad-authn-authz/EntityExposedWithoutAuthn/EntityExposedWithoutAuthn.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/EntityExposedWithoutAuthn.ql
1+
bad-authn-authz/EntityExposedWithoutAuthn/EntityExposedWithoutAuthn.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/EntityExposedWithoutAuthn.ql
1+
bad-authn-authz/EntityExposedWithoutAuthn/EntityExposedWithoutAuthn.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/EntityExposedWithoutAuthn.ql
1+
bad-authn-authz/EntityExposedWithoutAuthn/EntityExposedWithoutAuthn.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/DefaultUserIsPrivileged.ql
1+
bad-authn-authz/DefaultUserIsPrivileged/DefaultUserIsPrivileged.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/NonProductionStrategyUsed.ql
1+
bad-authn-authz/NonProductionStrategyUsed/NonProductionStrategyUsed.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/NonProductionStrategyUsed.ql
1+
bad-authn-authz/NonProductionStrategyUsed/NonProductionStrategyUsed.ql
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bad-authn-authz/NonProductionStrategyUsed.ql
1+
bad-authn-authz/NonProductionStrategyUsed/NonProductionStrategyUsed.ql

0 commit comments

Comments
 (0)