Skip to content

Refine locations in the CDS file #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,58 @@ import advanced_security.javascript.frameworks.cap.CDS

abstract class CdlObject extends JsonObject {
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
exists(Location loc, JsonValue locValue |
loc = this.getLocation() and
locValue = this.getPropValue("$location") and
path =
any(File f |
f.getAbsolutePath()
.matches("%" + locValue.getPropValue("file").getStringValue() + ".json")
).getAbsolutePath().regexpReplaceAll("\\.json$", "") and
sl = locValue.getPropValue("line").getIntValue() and
sc = locValue.getPropValue("col").getIntValue() and
el = sl + 1 and
ec = 1
)
// If the cds.json file has a $location property, then use that,
// otherwise fall back to the cds.json file itself
if exists(this.getPropValue("$location"))
then
exists(Location loc, JsonValue locValue |
loc = this.getLocation() and
locValue = this.getPropValue("$location") and
path =
any(File f |
f.getAbsolutePath()
.matches("%" + locValue.getPropValue("file").getStringValue() + ".json")
).getAbsolutePath().regexpReplaceAll("\\.json$", "") and
if
not exists(locValue.getPropValue("line")) and
not exists(locValue.getPropValue("col"))
then
// We don't know where this entity starts, so mark the whole file
sl = 0 and
sc = 0 and
el = 0 and
ec = 0
else (
sl = locValue.getPropValue("line").getIntValue() and
(
if exists(locValue.getPropValue("col"))
then sc = locValue.getPropValue("col").getIntValue()
else
// We don't know where this entity starts, so mark the start of the line
sc = 0
) and
el = sl and
(
if exists(getObjectLocationName())
then
// Currently $locations does not provide an end location. However, we can
// automatically deduce the end location from the length of the name.
ec = sc + getObjectLocationName().length() - 1
else
// Mark a single character if we cannot predicate the length
ec = sc + 1
)
)
)
else super.getLocation().hasLocationInfo(path, sl, sc, el, ec)
}

/**
* The name of the object that should be highlighted as the location.
*
* This is used to deduce the length of the location.
*/
string getObjectLocationName() { none() }
}

private newtype CdlKind =
Expand All @@ -31,21 +69,26 @@ private newtype CdlKind =
CdlFunctionKind(string value) { value = "function" }

/**
* Any CDL element, including entities, event, actions, and more.
* A list of CDL definitions, which can include entities, events, actions and more.
*/
class CdlDefinition extends CdlObject {
CdlDefinition() { exists(JsonObject root | this = root.getPropValue("definitions")) }
class CdlDefinitions extends CdlObject {
CdlDefinitions() { exists(JsonObject root | this = root.getPropValue("definitions")) }

JsonObject getElement(string elementName) { result = this.getPropValue(elementName) }

JsonObject getAnElement() { result = this.getElement(_) }
}

/**
* A CDL definition element.
*/
abstract class CdlElement extends CdlObject {
CdlKind kind;
string name;

CdlElement() { exists(CdlDefinition definition | this = definition.getElement(name)) }
CdlElement() { exists(CdlDefinitions definitions | this = definitions.getElement(name)) }

override string getObjectLocationName() { result = getUnqualifiedName() }

/**
* Gets the name of this CDL element.
Expand Down Expand Up @@ -215,6 +258,8 @@ class CdlAttribute extends CdlObject {
exists(CdlElement entity | this = entity.getPropValue("elements").getPropValue(name))
}

override string getObjectLocationName() { result = getName() }

string getType() { result = this.getPropStringValue("type") }

int getLength() { result = this.getPropValue("length").(JsonPrimitiveValue).getIntValue() }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
| srv/service1.cds:3:9:4:1 | {\\n ... }\\n } | The CDS service `Service1` is exposed without any authentication. |
| srv/service1.cds:5:10:6:1 | {\\n ... }\\n } | The CDS entity `Service1.Service1Entity` is exposed without any authentication. |
| srv/service1.cds:8:10:9:1 | {\\n ... }\\n } | The CDS action `Service1.send1` is exposed without any authentication. |
| srv/service2.cds:3:9:4:1 | {\\n ... }\\n } | The CDS service `Service2` is exposed without any authentication. |
| srv/service2.cds:5:10:6:1 | {\\n ... }\\n } | The CDS entity `Service2.Service2Entity` is exposed without any authentication. |
| srv/service2.cds:8:10:9:1 | {\\n ... }\\n } | The CDS action `Service2.send2` is exposed without any authentication. |
| srv/service1.cds:3:9:3:16 | {\\n ... }\\n } | The CDS service `Service1` is exposed without any authentication. |
| srv/service1.cds:5:10:5:23 | {\\n ... }\\n } | The CDS entity `Service1.Service1Entity` is exposed without any authentication. |
| srv/service1.cds:8:10:8:14 | {\\n ... }\\n } | The CDS action `Service1.send1` is exposed without any authentication. |
| srv/service2.cds:3:9:3:16 | {\\n ... }\\n } | The CDS service `Service2` is exposed without any authentication. |
| srv/service2.cds:5:10:5:23 | {\\n ... }\\n } | The CDS entity `Service2.Service2Entity` is exposed without any authentication. |
| srv/service2.cds:8:10:8:14 | {\\n ... }\\n } | The CDS action `Service2.send2` is exposed without any authentication. |
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ nodes
edges
| sensitive-exposure.js:9:32:9:42 | Sample.name | sensitive-exposure.js:9:32:9:42 | Sample.name |
#select
| sensitive-exposure.js:9:32:9:42 | Sample.name | sensitive-exposure.js:9:32:9:42 | Sample.name | sensitive-exposure.js:9:32:9:42 | Sample.name | Log entry depends on the $@ field which is annotated as potentially sensitive. | sensitive-exposure.cds:4:5:5:1 | {\\n ... } | name |
| sensitive-exposure.js:9:32:9:42 | Sample.name | sensitive-exposure.js:9:32:9:42 | Sample.name | sensitive-exposure.js:9:32:9:42 | Sample.name | Log entry depends on the $@ field which is annotated as potentially sensitive. | sensitive-exposure.cds:4:5:4:8 | {\\n ... } | name |