Skip to content

Add models of the jakarta/javax.json package#6183

Merged
aschackmull merged 7 commits intogithub:mainfrom
smowton:smowton/feature/javax-json-models
Jul 19, 2021
Merged

Add models of the jakarta/javax.json package#6183
aschackmull merged 7 commits intogithub:mainfrom
smowton:smowton/feature/javax-json-models

Conversation

@smowton
Copy link
Copy Markdown
Contributor

@smowton smowton commented Jun 29, 2021

Notes:

  1. I've left the stream subpackage alone for now to come back to once we have lambda flow
  2. I've used whole-object taint rather than tracking Element, MapValue etc here on the understanding that the purpose of the package is to build an object then serialise or the inverse, rather than to use these as general-purpose data structures where flows involving access paths are more plausible.
  3. One possible shortcoming of that approach: JsonArray exposes a full immutable List interface; some reads through that interface against a deserialised object may not convey taint as a result.

@smowton smowton requested a review from a team as a code owner June 29, 2021 14:21
Copy link
Copy Markdown
Contributor

@Marcono1234 Marcono1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to cover jakarta.json.* as well now that the Eclipse Foundation has took over the project? See https://eclipse-ee4j.github.io/jsonp/

I have left some review comments regarding methods which might only exist for Jakarta JSON-P; feel free to ignore them if you don't want to cover JSON-P.
Though note that some of the comments might also apply to Java EE, but not to Java EE 7 documented on https://docs.oracle.com but to the newer versions, see https://javadoc.io/doc/javax.json/javax.json-api/latest/overview-summary.html

Should the class Json be modelled as well? It has multiple factory methods.

"javax.json;JsonArray;false;getJsonString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonArray;false;getString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonArray;false;getString;;;Argument[1];ReturnValue;value",
"javax.json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't that be value flow since getValueAs(Class) seems to return a view (without modifying the entries in any way)? (or is value flow only when it is the exact same reference?)
Though the overload getValueAs(Function) would only be taint flow then I guess.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be the exact same reference indeed

"javax.json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint",
"javax.json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonValue;false;toString;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this cover subtypes as well? (hopefully my understanding of the CSV model is correct)

Suggested change
"javax.json;JsonValue;false;toString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonValue;true;toString;;;Argument[-1];ReturnValue;taint",

"javax.json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint",
"javax.json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonValue;false;toString;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that also cover the following?

"javax.json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint",
"javax.json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonValue;false;toString;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should JsonStructure.getValue(String) be covered as well?

"javax.json;JsonArray;false;getString;;;Argument[1];ReturnValue;value",
"javax.json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonArrayBuilder;false;add;;;Argument[-1];ReturnValue;value",
"javax.json;JsonArrayBuilder;false;add;;;Argument[0];Argument[-1];taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might result in false positives since there are also overloads in the form add(index, ...) (which are in turn also not covered)

"javax.json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonArrayBuilder;false;add;;;Argument[-1];ReturnValue;value",
"javax.json;JsonArrayBuilder;false;add;;;Argument[0];Argument[-1];taint",
"javax.json;JsonArrayBuilder;false;addNull;;;Argument[-1];ReturnValue;value",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jakarta JSON-P also has the following methods JsonArrayBuilder methods:

  • addAll
  • remove(...)
  • set(...)
  • setNull(int)

"javax.json;JsonArrayBuilder;false;add;;;Argument[0];Argument[-1];taint",
"javax.json;JsonArrayBuilder;false;addNull;;;Argument[-1];ReturnValue;value",
"javax.json;JsonArrayBuilder;false;build;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonNumber;false;bigDecimalValue;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

@Marcono1234 Marcono1234 Jun 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't at least bigDecimalValue() value flow since there is (most likely) no precision loss?
(Or maybe I am misunderstanding the meaning of value)

Edit: Nevermind, see #6183 (comment)

"javax.json;JsonNumber;false;intValue;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonNumber;false;intValueExact;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonNumber;false;longValue;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonNumber;false;longValueExact;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also numberValue(); that one might be value flow?

"javax.json;JsonObjectBuilder;false;add;;;Argument[-1];ReturnValue;value",
"javax.json;JsonObjectBuilder;false;add;;;Argument[1];Argument[-1];taint",
"javax.json;JsonObjectBuilder;false;addNull;;;Argument[-1];ReturnValue;value",
"javax.json;JsonObjectBuilder;false;build;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are also the following JsonObjectBuilder methods:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smowton I think you missed JsonObjectBuilder.remove

"javax.json;JsonObjectBuilder;false;build;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonReader;false;read;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonReader;false;readArray;;;Argument[-1];ReturnValue;taint",
"javax.json;JsonReader;false;readObject;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also JsonReader.readValue()

@smowton
Copy link
Copy Markdown
Contributor Author

smowton commented Jun 30, 2021

Thanks @Marcono1234, I've improved this to cover the jakarta version of the package and to incorporate the missing functions you mention.

I'll edit the top comment with notes on taint strategy here and the uncovered subpackages

@smowton smowton changed the title Add models of the javax.json package Add models of the jakarta/javax.json package Jun 30, 2021
Copy link
Copy Markdown
Contributor

@Marcono1234 Marcono1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the changes. Usage of a set literal expression for supporting the different package names is a pretty neat idea!

Since you have covered some additional classes as well, would it make sense to cover JsonPointer, JsonMergePatch and JsonPatchBuilder from the same package as well?

Comment on lines +15 to +16
"Json;false;createDiff;;;Argument[0..1];ReturnValue;taint",
"Json;false;createMergeDiff;;;Argument[0..1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not completely sure whether argument 0 (source) is actually affecting taint. Did not have a look at the implementation or the RFC, but if I understand it correctly source can only affect whether JSON values are added or removed, but not which values they will have.
E.g.:

  • source has "a": 1, target does not have it → a is removed
  • source does not have a, target has "a": 1"a": 1 is added

In both cases source does not taint the patch.
But might be good to verify this, also for JSON arrays.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured the diff must represent the removal of the key somehow, and <script>alert('Oh no')</script> is a valid key, so we might be interested in this as a taint propagator

"Json;false;createObjectBuilder;(Map);;MapValue of Argument[0];ReturnValue;taint",
"Json;false;createPatch;;;Argument[0];ReturnValue;taint",
"Json;false;createReader;;;Argument[0];ReturnValue;taint",
"Json;false;createWriter;;;Argument[0];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case you decide to add JsonPatchBuilder it would be good to add Json.createPatchBuilder(JsonArray) as well.

"Json;false;createObjectBuilder;(Map);;MapValue of Argument[0];ReturnValue;taint",
"Json;false;createPatch;;;Argument[0];ReturnValue;taint",
"Json;false;createReader;;;Argument[0];ReturnValue;taint",
"Json;false;createWriter;;;Argument[0];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would probably be good to cover the createValue(...) methods as well.

@@ -0,0 +1,110 @@
/**
* Provides models for the `javax.json` package.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also have to adjust this:

Suggested change
* Provides models for the `javax.json` package.
* Provides models for the `javax.json` and `jakarta.json` packages.

@github-actions
Copy link
Copy Markdown
Contributor

⚠️ The head of this PR and the base branch were compared for differences in the framework coverage reports. The generated reports are available in the artifacts of this workflow run. The differences will be picked up by the nightly job after the PR gets merged. The following differences were found:

java

Generated file changes for java

  • Changes to framework-coverage-java.rst:
-    Java extensions,"``javax.*``, ``jakarta.*``",22,294,18,,,,,1,1,2
+    Java extensions,"``javax.*``, ``jakarta.*``",22,536,18,,,,,1,1,2
-    Totals,,84,2013,287,13,6,6,98,33,1,66
+    Totals,,84,2255,287,13,6,6,98,33,1,66
  • Changes to framework-coverage-java.csv:
+ jakarta.json,,,121,,,,,,,,,,,,,,,98,23
+ javax.json,,,121,,,,,,,,,,,,,,,98,23

@smowton
Copy link
Copy Markdown
Contributor Author

smowton commented Jul 12, 2021

@Marcono1234 all changes applied

Copy link
Copy Markdown
Contributor

@Marcono1234 Marcono1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for considering the feedback!

Do you think it would be worth considering methods for de- and encoding a JSON pointer string as well?

".json;JsonPatchBuilder;false;replace;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;test;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;test;;;Argument[-1];ReturnValue;value",
".json;JsonPointer;false;add;;;Argument[-1];ReturnValue;taint",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is add really transferring taint from the receiver JsonPointer?
If so should that then in the same way apply to the other methods (getValue, remove, replace)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add: yes, because the pointer could contain an injection string, which would be incorporated into the result as a new key. getValue, remove, replace: no, they do not incorporate text from the pointer into the result (replace requires that the key is already present)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification! Makes sense.

@smowton
Copy link
Copy Markdown
Contributor Author

smowton commented Jul 13, 2021

Done

@github-actions
Copy link
Copy Markdown
Contributor

⚠️ The head of this PR and the base branch were compared for differences in the framework coverage reports. The generated reports are available in the artifacts of this workflow run. The differences will be picked up by the nightly job after the PR gets merged. The following differences were found:

java

Generated file changes for java

  • Changes to framework-coverage-java.rst:
-    Java extensions,"``javax.*``, ``jakarta.*``",22,294,18,,,,,1,1,2
+    Java extensions,"``javax.*``, ``jakarta.*``",22,540,18,,,,,1,1,2
-    Totals,,84,2013,287,13,6,6,98,33,1,66
+    Totals,,84,2259,287,13,6,6,98,33,1,66
  • Changes to framework-coverage-java.csv:
+ jakarta.json,,,123,,,,,,,,,,,,,,,100,23
+ javax.json,,,123,,,,,,,,,,,,,,,100,23

@aschackmull aschackmull merged commit c32a75a into github:main Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants