diff --git a/classes/AccountService.class b/classes/AccountService.class new file mode 100644 index 00000000000..0fe62ff2359 Binary files /dev/null and b/classes/AccountService.class differ diff --git a/classes/AccountServiceImpl.class b/classes/AccountServiceImpl.class new file mode 100644 index 00000000000..a60941b4c3f Binary files /dev/null and b/classes/AccountServiceImpl.class differ diff --git a/classes/Action.class b/classes/Action.class new file mode 100644 index 00000000000..af8e196f4a2 Binary files /dev/null and b/classes/Action.class differ diff --git a/classes/Cat.class b/classes/Cat.class new file mode 100644 index 00000000000..09ecfdc26e5 Binary files /dev/null and b/classes/Cat.class differ diff --git a/classes/CustomeRemoteInvocationSerializingExporter.class b/classes/CustomeRemoteInvocationSerializingExporter.class new file mode 100644 index 00000000000..fe7ae8ebfbc Binary files /dev/null and b/classes/CustomeRemoteInvocationSerializingExporter.class differ diff --git a/classes/DomesticNumber.class b/classes/DomesticNumber.class new file mode 100644 index 00000000000..cec0c740ad3 Binary files /dev/null and b/classes/DomesticNumber.class differ diff --git a/classes/Employee.class b/classes/Employee.class new file mode 100644 index 00000000000..5a04c366355 Binary files /dev/null and b/classes/Employee.class differ diff --git a/classes/InternationalNumber.class b/classes/InternationalNumber.class new file mode 100644 index 00000000000..35ad8fd1513 Binary files /dev/null and b/classes/InternationalNumber.class differ diff --git a/classes/JacksonTest.class b/classes/JacksonTest.class new file mode 100644 index 00000000000..30b9e312a6b Binary files /dev/null and b/classes/JacksonTest.class differ diff --git a/classes/NonConstantTimeCheckOnSignature.class b/classes/NonConstantTimeCheckOnSignature.class new file mode 100644 index 00000000000..d41938a2195 Binary files /dev/null and b/classes/NonConstantTimeCheckOnSignature.class differ diff --git a/classes/NonConstantTimeCryptoComparison.class b/classes/NonConstantTimeCryptoComparison.class new file mode 100644 index 00000000000..257181b811b Binary files /dev/null and b/classes/NonConstantTimeCryptoComparison.class differ diff --git a/classes/NotAConfiguration.class b/classes/NotAConfiguration.class new file mode 100644 index 00000000000..0ac4fd34fcc Binary files /dev/null and b/classes/NotAConfiguration.class differ diff --git a/classes/NotConstantTimeCryptoComparison.class b/classes/NotConstantTimeCryptoComparison.class new file mode 100644 index 00000000000..99d530b5628 Binary files /dev/null and b/classes/NotConstantTimeCryptoComparison.class differ diff --git a/classes/Person.class b/classes/Person.class new file mode 100644 index 00000000000..4609ee559a6 Binary files /dev/null and b/classes/Person.class differ diff --git a/classes/PhoneNumber.class b/classes/PhoneNumber.class new file mode 100644 index 00000000000..02576fc5122 Binary files /dev/null and b/classes/PhoneNumber.class differ diff --git a/classes/SaferCatDeserialization.class b/classes/SaferCatDeserialization.class new file mode 100644 index 00000000000..ac151701bde Binary files /dev/null and b/classes/SaferCatDeserialization.class differ diff --git a/classes/SaferPersonDeserialization.class b/classes/SaferPersonDeserialization.class new file mode 100644 index 00000000000..961f0d1a56f Binary files /dev/null and b/classes/SaferPersonDeserialization.class differ diff --git a/classes/Security/CWE/CWE-502/UnsafeDeserialization.md b/classes/Security/CWE/CWE-502/UnsafeDeserialization.md new file mode 100644 index 00000000000..e89e444d48d --- /dev/null +++ b/classes/Security/CWE/CWE-502/UnsafeDeserialization.md @@ -0,0 +1,50 @@ +# Deserialization of user-controlled data +Deserializing untrusted data using any deserialization framework that allows the construction of arbitrary serializable objects is easily exploitable and in many cases allows an attacker to execute arbitrary code. Even before a deserialized object is returned to the caller of a deserialization method a lot of code may have been executed, including static initializers, constructors, and finalizers. Automatic deserialization of fields means that an attacker may craft a nested combination of objects on which the executed initialization code may have unforeseen effects, such as the execution of arbitrary code. + +There are many different serialization frameworks. This query currently supports Kryo, XmlDecoder, XStream, SnakeYaml, Jackson and Java IO serialization through `ObjectInputStream`/`ObjectOutputStream`. + + +## Recommendation +Avoid deserialization of untrusted data if at all possible. If the architecture permits it then use other formats instead of serialized objects, for example JSON or XML. However, these formats should not be deserialized into complex objects because this provides further opportunities for attack. For example, XML-based deserialization attacks are possible through libraries such as XStream and XmlDecoder. Alternatively, a tightly controlled whitelist can limit the vulnerability of code, but be aware of the existence of so-called Bypass Gadgets, which can circumvent such protection measures. + + +## Example +The following example calls `readObject` directly on an `ObjectInputStream` that is constructed from untrusted data, and is therefore inherently unsafe. + + +```java +public MyObject { + public int field; + MyObject(int field) { + this.field = field; + } +} + +public MyObject deserialize(Socket sock) { + try(ObjectInputStream in = new ObjectInputStream(sock.getInputStream())) { + return (MyObject)in.readObject(); // unsafe + } +} + +``` +Rewriting the communication protocol to only rely on reading primitive types from the input stream removes the vulnerability. + + +```java +public MyObject deserialize(Socket sock) { + try(DataInputStream in = new DataInputStream(sock.getInputStream())) { + return new MyObject(in.readInt()); + } +} + +``` + +## References +* OWASP vulnerability description: [Deserialization of untrusted data](https://www.owasp.org/index.php/Deserialization_of_untrusted_data). +* OWASP guidance on deserializing objects: [Deserialization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html). +* Talks by Chris Frohoff & Gabriel Lawrence: [ AppSecCali 2015: Marshalling Pickles - how deserializing objects will ruin your day](http://frohoff.github.io/appseccali-marshalling-pickles/), [OWASP SD: Deserialize My Shorts: Or How I Learned to Start Worrying and Hate Java Object Deserialization](http://frohoff.github.io/owaspsd-deserialize-my-shorts/). +* Alvaro Muñoz & Christian Schneider, RSAConference 2016: [Serial Killer: Silently Pwning Your Java Endpoints](https://speakerdeck.com/pwntester/serial-killer-silently-pwning-your-java-endpoints). +* SnakeYaml documentation on deserialization: [SnakeYaml deserialization](https://bitbucket.org/asomov/snakeyaml/wiki/Documentation#markdown-header-loading-yaml). +* Research by Moritz Bechler: [Java Unmarshaller Security - Turning your data into code execution](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true) +* Blog posts by the developer of Jackson libraries: [On Jackson CVEs: Don’t Panic — Here is what you need to know](https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062) [Jackson 2.10: Safe Default Typing](https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba) +* Common Weakness Enumeration: [CWE-502](https://cwe.mitre.org/data/definitions/502.html). diff --git a/classes/SpringBootTestApplication.class b/classes/SpringBootTestApplication.class new file mode 100644 index 00000000000..ccf9717c0e5 Binary files /dev/null and b/classes/SpringBootTestApplication.class differ diff --git a/classes/SpringBootTestConfiguration.class b/classes/SpringBootTestConfiguration.class new file mode 100644 index 00000000000..e221e77d8ec Binary files /dev/null and b/classes/SpringBootTestConfiguration.class differ diff --git a/classes/SpringExporterUnsafeDeserialization.class b/classes/SpringExporterUnsafeDeserialization.class new file mode 100644 index 00000000000..10b403c2e1e Binary files /dev/null and b/classes/SpringExporterUnsafeDeserialization.class differ diff --git a/classes/Tag.class b/classes/Tag.class new file mode 100644 index 00000000000..0f827a6f3ea Binary files /dev/null and b/classes/Tag.class differ diff --git a/classes/Task.class b/classes/Task.class new file mode 100644 index 00000000000..1f99093ea83 Binary files /dev/null and b/classes/Task.class differ diff --git a/classes/UnsafeCatDeserialization.class b/classes/UnsafeCatDeserialization.class new file mode 100644 index 00000000000..3f005cf825d Binary files /dev/null and b/classes/UnsafeCatDeserialization.class differ diff --git a/classes/UnsafeObjectAllocation.class b/classes/UnsafeObjectAllocation.class new file mode 100644 index 00000000000..d29771e9978 Binary files /dev/null and b/classes/UnsafeObjectAllocation.class differ diff --git a/classes/UnsafePersonDeserialization.class b/classes/UnsafePersonDeserialization.class new file mode 100644 index 00000000000..45facc06626 Binary files /dev/null and b/classes/UnsafePersonDeserialization.class differ diff --git a/classes/com/fasterxml/jackson/annotation/JsonTypeInfo$Id.class b/classes/com/fasterxml/jackson/annotation/JsonTypeInfo$Id.class new file mode 100644 index 00000000000..aeba1e930dd Binary files /dev/null and b/classes/com/fasterxml/jackson/annotation/JsonTypeInfo$Id.class differ diff --git a/classes/com/fasterxml/jackson/annotation/JsonTypeInfo.class b/classes/com/fasterxml/jackson/annotation/JsonTypeInfo.class new file mode 100644 index 00000000000..a1b63a00bc3 Binary files /dev/null and b/classes/com/fasterxml/jackson/annotation/JsonTypeInfo.class differ diff --git a/classes/com/fasterxml/jackson/core/JsonFactory.class b/classes/com/fasterxml/jackson/core/JsonFactory.class new file mode 100644 index 00000000000..dc691839648 Binary files /dev/null and b/classes/com/fasterxml/jackson/core/JsonFactory.class differ diff --git a/classes/com/fasterxml/jackson/core/JsonGenerator.class b/classes/com/fasterxml/jackson/core/JsonGenerator.class new file mode 100644 index 00000000000..68c93c4ff11 Binary files /dev/null and b/classes/com/fasterxml/jackson/core/JsonGenerator.class differ diff --git a/classes/com/fasterxml/jackson/core/JsonParser.class b/classes/com/fasterxml/jackson/core/JsonParser.class new file mode 100644 index 00000000000..65e1477cb9f Binary files /dev/null and b/classes/com/fasterxml/jackson/core/JsonParser.class differ diff --git a/classes/com/fasterxml/jackson/core/TreeNode.class b/classes/com/fasterxml/jackson/core/TreeNode.class new file mode 100644 index 00000000000..0a529cc0431 Binary files /dev/null and b/classes/com/fasterxml/jackson/core/TreeNode.class differ diff --git a/classes/com/fasterxml/jackson/databind/JsonNode.class b/classes/com/fasterxml/jackson/databind/JsonNode.class new file mode 100644 index 00000000000..87fd5451f0a Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/JsonNode.class differ diff --git a/classes/com/fasterxml/jackson/databind/MappingIterator.class b/classes/com/fasterxml/jackson/databind/MappingIterator.class new file mode 100644 index 00000000000..d7dbf382e3c Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/MappingIterator.class differ diff --git a/classes/com/fasterxml/jackson/databind/ObjectMapper.class b/classes/com/fasterxml/jackson/databind/ObjectMapper.class new file mode 100644 index 00000000000..ff17b199796 Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/ObjectMapper.class differ diff --git a/classes/com/fasterxml/jackson/databind/ObjectReader.class b/classes/com/fasterxml/jackson/databind/ObjectReader.class new file mode 100644 index 00000000000..8a6e53b99ca Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/ObjectReader.class differ diff --git a/classes/com/fasterxml/jackson/databind/cfg/MapperBuilder.class b/classes/com/fasterxml/jackson/databind/cfg/MapperBuilder.class new file mode 100644 index 00000000000..0a3b2bd3522 Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/cfg/MapperBuilder.class differ diff --git a/classes/com/fasterxml/jackson/databind/json/JsonMapper$Builder.class b/classes/com/fasterxml/jackson/databind/json/JsonMapper$Builder.class new file mode 100644 index 00000000000..410ded1affd Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/json/JsonMapper$Builder.class differ diff --git a/classes/com/fasterxml/jackson/databind/json/JsonMapper.class b/classes/com/fasterxml/jackson/databind/json/JsonMapper.class new file mode 100644 index 00000000000..aa8f7382a51 Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/json/JsonMapper.class differ diff --git a/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator$Builder.class b/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator$Builder.class new file mode 100644 index 00000000000..08ccc7553af Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator$Builder.class differ diff --git a/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.class b/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.class new file mode 100644 index 00000000000..06869a46509 Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.class differ diff --git a/classes/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.class b/classes/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.class new file mode 100644 index 00000000000..1164dd8e03e Binary files /dev/null and b/classes/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.class differ diff --git a/classes/com/google/common/primitives/Ints.class b/classes/com/google/common/primitives/Ints.class new file mode 100644 index 00000000000..66bafaacc2d Binary files /dev/null and b/classes/com/google/common/primitives/Ints.class differ diff --git a/classes/com/google/common/primitives/Shorts.class b/classes/com/google/common/primitives/Shorts.class new file mode 100644 index 00000000000..81079ca1b3f Binary files /dev/null and b/classes/com/google/common/primitives/Shorts.class differ diff --git a/classes/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.md b/classes/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.md new file mode 100644 index 00000000000..051cd9ff149 --- /dev/null +++ b/classes/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.md @@ -0,0 +1,75 @@ +# Unsafe deserialization in a remotely callable method. +Java RMI uses the default Java serialization mechanism (in other words, `ObjectInputStream`) to pass parameters in remote method invocations. This mechanism is known to be unsafe when deserializing untrusted data. If a registered remote object has a method that accepts a complex object, an attacker can take advantage of the unsafe deserialization mechanism. In the worst case, it results in remote code execution. + + +## Recommendation +Use only strings and primitive types in parameters of remote objects. + +Set a filter for incoming serialized data by wrapping remote objects using either `UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter)` or `UnicastRemoteObject.exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter)` methods. Those methods accept an `ObjectInputFilter` that decides which classes are allowed for deserialization. The filter should allow deserializing only safe classes. + +It is also possible to set a process-wide deserialization filter. The filter can be set by with `ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter)` method, or by setting system or security property `jdk.serialFilter`. Make sure that you use the latest Java versions that include JEP 290. Please note that the query is not sensitive to this mitigation. + +If switching to the latest Java versions is not possible, consider using other implementations of remote procedure calls. For example, HTTP API with JSON. Make sure that the underlying deserialization mechanism is properly configured so that deserialization attacks are not possible. + + +## Example +The following code registers a remote object with a vulnerable method that accepts a complex object: + + +```java +public class Server { + public void bindRemoteObject(Registry registry) throws Exception { + registry.bind("unsafe", new RemoteObjectImpl()); + } +} + +interface RemoteObject extends Remote { + void action(Object obj) throws RemoteException; +} + +class RemoteObjectImpl implements RemoteObject { + // ... +} +``` +The next example registers a safe remote object whose methods use only primitive types and strings: + + +```java +public class Server { + public void bindRemoteObject(Registry registry) throws Exception { + registry.bind("safe", new RemoteObjectImpl()); + } +} + +interface RemoteObject extends Remote { + void calculate(int a, double b) throws RemoteException; + void save(String s) throws RemoteException; +} + +class RemoteObjectImpl implements RemoteObject { + // ... +} +``` +The next example shows how to set a deserilization filter for a remote object: + + +```java +public void bindRemoteObject(Registry registry, int port) throws Exception { + ObjectInputFilter filter = info -> { + if (info.serialClass().getCanonicalName().startsWith("com.safe.package.")) { + return ObjectInputFilter.Status.ALLOWED; + } + return ObjectInputFilter.Status.REJECTED; + }; + registry.bind("safer", UnicastRemoteObject.exportObject(new RemoteObjectImpl(), port, filter)); +} + +``` + +## References +* Oracle: [Remote Method Invocation (RMI)](https://www.oracle.com/java/technologies/javase/remote-method-invocation-home.html). +* ITNEXT: [Java RMI for pentesters part two - reconnaissance & attack against non-JMX registries](https://itnext.io/java-rmi-for-pentesters-part-two-reconnaissance-attack-against-non-jmx-registries-187a6561314d). +* MOGWAI LABS: [Attacking Java RMI services after JEP 290](https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290) +* OWASP: [Deserialization of untrusted data](https://www.owasp.org/index.php/Deserialization_of_untrusted_data). +* OpenJDK: [JEP 290: Filter Incoming Serialization Data](https://openjdk.java.net/jeps/290) +* Common Weakness Enumeration: [CWE-502](https://cwe.mitre.org/data/definitions/502.html). diff --git a/classes/org/apache/commons/lang3/math/NumberUtils.class b/classes/org/apache/commons/lang3/math/NumberUtils.class new file mode 100644 index 00000000000..0b882b6664b Binary files /dev/null and b/classes/org/apache/commons/lang3/math/NumberUtils.class differ diff --git a/classes/org/springframework/boot/SpringBootConfiguration.class b/classes/org/springframework/boot/SpringBootConfiguration.class new file mode 100644 index 00000000000..487e44f43cc Binary files /dev/null and b/classes/org/springframework/boot/SpringBootConfiguration.class differ diff --git a/classes/org/springframework/boot/autoconfigure/SpringBootApplication.class b/classes/org/springframework/boot/autoconfigure/SpringBootApplication.class new file mode 100644 index 00000000000..8b340da4cef Binary files /dev/null and b/classes/org/springframework/boot/autoconfigure/SpringBootApplication.class differ diff --git a/classes/org/springframework/context/annotation/Bean.class b/classes/org/springframework/context/annotation/Bean.class new file mode 100644 index 00000000000..11d8cbe57c0 Binary files /dev/null and b/classes/org/springframework/context/annotation/Bean.class differ diff --git a/classes/org/springframework/context/annotation/Configuration.class b/classes/org/springframework/context/annotation/Configuration.class new file mode 100644 index 00000000000..472f9312d55 Binary files /dev/null and b/classes/org/springframework/context/annotation/Configuration.class differ diff --git a/classes/org/springframework/remoting/caucho/HessianExporter.class b/classes/org/springframework/remoting/caucho/HessianExporter.class new file mode 100644 index 00000000000..895808a97e4 Binary files /dev/null and b/classes/org/springframework/remoting/caucho/HessianExporter.class differ diff --git a/classes/org/springframework/remoting/caucho/HessianServiceExporter.class b/classes/org/springframework/remoting/caucho/HessianServiceExporter.class new file mode 100644 index 00000000000..80b9561987f Binary files /dev/null and b/classes/org/springframework/remoting/caucho/HessianServiceExporter.class differ diff --git a/classes/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.class b/classes/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.class new file mode 100644 index 00000000000..b51b4f6dde9 Binary files /dev/null and b/classes/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.class differ diff --git a/classes/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.class b/classes/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.class new file mode 100644 index 00000000000..f8364071e68 Binary files /dev/null and b/classes/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.class differ diff --git a/classes/org/springframework/remoting/rmi/RmiBasedExporter.class b/classes/org/springframework/remoting/rmi/RmiBasedExporter.class new file mode 100644 index 00000000000..576f6b23427 Binary files /dev/null and b/classes/org/springframework/remoting/rmi/RmiBasedExporter.class differ diff --git a/classes/org/springframework/remoting/rmi/RmiServiceExporter.class b/classes/org/springframework/remoting/rmi/RmiServiceExporter.class new file mode 100644 index 00000000000..08ce93604f2 Binary files /dev/null and b/classes/org/springframework/remoting/rmi/RmiServiceExporter.class differ diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/codeql-database.yml b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/codeql-database.yml new file mode 100644 index 00000000000..bf3cd82ec1e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/codeql-database.yml @@ -0,0 +1,28 @@ +--- +sourceLocationPrefix: "/media/i504100/Artem_Flash_1T/codeql-bounties/codeql-repo/java/ql/src" +unicodeNewlines: false +columnKind: "utf16" +primaryLanguage: "java" +inProgress: + primaryLanguage: "java" + installedExtractors: + cpp: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/cpp/" + csharp: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/csharp/" + csv: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/csv/" + go: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/go/" + html: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/html/" + java: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/java/" + javascript: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/javascript/" + properties: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/properties/" + python: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/python/" + xml: + - "file:///media/i504100/Artem_Flash_1T/codeql-bounties/codeql-cli/xml/" diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-errors.log b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-errors.log new file mode 100644 index 00000000000..09b089bd1c9 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-errors.log @@ -0,0 +1 @@ +[2021-06-14 08:53:54] [javac-extractor-9926] [ERROR] 10 errors were reported by javac. diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-extractor-9926.log b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-extractor-9926.log new file mode 100644 index 00000000000..dce041fac87 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-extractor-9926.log @@ -0,0 +1,9 @@ +[2021-06-14 08:53:53] [javac-extractor-9926] Starting extraction for: + sun.java.command=com.semmle.extractor.java.JavaExtractor --javacOptions -source 8 --strict-javac-errors --encoding UTF-8 --files SafeMacComparison.java UnsafeMacComparison.java + user.dir=/media/i504100/Artem_Flash_1T/codeql-bounties/codeql-repo/java/ql/src/experimental/Security/CWE/CWE-208 +[2021-06-14 08:53:54] [javac-extractor-9926] Javac init time: 0.6s +[2021-06-14 08:53:54] [javac-extractor-9926] Javac attr time: 0.0s +[2021-06-14 08:53:54] [javac-extractor-9926] Extractor time: 0.0s +[2021-06-14 08:53:54] [javac-extractor-9926] Other time: 0.2s +[2021-06-14 08:53:54] [javac-extractor-9926] Total time: 0.7s +[2021-06-14 08:53:54] [javac-extractor-9926] [ERROR] 10 errors were reported by javac. diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-output-9926.log b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-output-9926.log new file mode 100644 index 00000000000..9139106f478 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/log/javac-output-9926.log @@ -0,0 +1,31 @@ +[2021-06-14 08:53:53] [javac-output-9926] warning: [options] bootstrap class path not set in conjunction with -source 8 +[2021-06-14 08:53:53] [javac-output-9926] SafeMacComparison.java:1: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] public boolean check(byte[] expected, byte[] data, SecretKey key) throws Exception { +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] SafeMacComparison.java:3: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] mac.init(new SecretKeySpec(key.getEncoded(), "HmacSHA256")); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] SafeMacComparison.java:4: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] byte[] actual = mac.doFinal(data); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] SafeMacComparison.java:5: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] return MessageDigest.isEqual(expected, actual); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] SafeMacComparison.java:6: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] } +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] UnsafeMacComparison.java:1: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] public boolean check(byte[] expected, byte[] data, SecretKey key) throws Exception { +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] UnsafeMacComparison.java:3: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] mac.init(new SecretKeySpec(key.getEncoded(), "HmacSHA256")); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] UnsafeMacComparison.java:4: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] byte[] actual = mac.doFinal(data); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] UnsafeMacComparison.java:5: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] return Arrays.equals(expected, actual); +[2021-06-14 08:53:53] [javac-output-9926] ^ +[2021-06-14 08:53:53] [javac-output-9926] UnsafeMacComparison.java:6: error: class, interface, or enum expected +[2021-06-14 08:53:53] [javac-output-9926] } +[2021-06-14 08:53:53] [javac-output-9926] ^ diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/trap/java/diagnostics/diagnostic.trap.gz b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/trap/java/diagnostics/diagnostic.trap.gz new file mode 100644 index 00000000000..a2dcf3f4619 Binary files /dev/null and b/java/ql/src/experimental/Security/CWE/CWE-208/CWE-208.testproj/trap/java/diagnostics/diagnostic.trap.gz differ diff --git a/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll b/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll index 9f30bf4a7cd..8d44ee571ac 100644 --- a/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll +++ b/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll @@ -274,11 +274,19 @@ predicate createJacksonTreeNodeStep(DataFlow::Node fromNode, DataFlow::Node toNo ) } +/** + * Holds if `type` or one of its supertypes has a field with `JsonTypeInfo` annotation + * that enables polymorphic type handling. + */ predicate hasJsonTypeInfoAnnotation(RefType type) { hasFieldWithJsonTypeAnnotation(type.getASupertype*()) or hasFieldWithJsonTypeAnnotation(type.getAField().getType()) } +/** + * Holds if `type` has a field with `JsonTypeInfo` annotation + * that enables polymorphic type handling. + */ predicate hasFieldWithJsonTypeAnnotation(RefType type) { exists(Annotation a | type.getAField().getAnAnnotation() = a and diff --git a/java/ql/test/query-tests/security/CWE-502/JacksonTest.java b/java/ql/test/query-tests/security/CWE-502/JacksonTest.java new file mode 100644 index 00000000000..902e7025eeb --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-502/JacksonTest.java @@ -0,0 +1,193 @@ +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; +import java.io.IOException; +import java.io.Serializable; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; + +public class JacksonTest { + + public static void withSocket(Action action) throws Exception { + try (ServerSocket serverSocket = new ServerSocket(0)) { + try (Socket socket = serverSocket.accept()) { + byte[] bytes = new byte[1024]; + int n = socket.getInputStream().read(bytes); + String jexlExpr = new String(bytes, 0, n); + action.run(jexlExpr); + } + } + } +} + +interface Action { + void run(T object) throws Exception; +} + +abstract class PhoneNumber implements Serializable { + public int areaCode; + public int local; +} + +class DomesticNumber extends PhoneNumber { +} + +class InternationalNumber extends PhoneNumber { + public int countryCode; +} + +class Employee extends Person { +} + +class Person { + public String name; + public int age; + + // this annotation enables polymorphic type handling + @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) + public Object phone; +} + +class Task { + public Person assignee; +} + +class Tag implements Serializable { + public String title; +} + +class Cat { + public String name; + public Serializable tag; +} + +class UnsafePersonDeserialization { + + // BAD: Person has a field with an annotation that enables polymorphic type + // handling + private static void testUnsafeDeserialization() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.readValue(string, Person.class); + }); + } + + // BAD: Employee extends Person that has a field with an annotation that enables + // polymorphic type handling + private static void testUnsafeDeserializationWithExtendedClass() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.readValue(string, Employee.class); + }); + } + + // BAD: Task has a Person field that has a field with an annotation that enables + // polymorphic type handling + private static void testUnsafeDeserializationWithWrapper() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.readValue(string, Task.class); + }); + } +} + +class SaferPersonDeserialization { + + // GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper + // has a validator + private static void testSafeDeserializationWithValidator() throws Exception { + JacksonTest.withSocket(string -> { + PolymorphicTypeValidator ptv = + BasicPolymorphicTypeValidator.builder() + .allowIfSubType("only.allowed.package") + .build(); + + ObjectMapper mapper = new ObjectMapper(); + mapper.setPolymorphicTypeValidator(ptv); + + mapper.readValue(string, Person.class); + }); + } + + // GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper + // has a validator + private static void testSafeDeserializationWithValidatorAndBuilder() throws Exception { + JacksonTest.withSocket(string -> { + PolymorphicTypeValidator ptv = + BasicPolymorphicTypeValidator.builder() + .allowIfSubType("only.allowed.package") + .build(); + + ObjectMapper mapper = JsonMapper.builder() + .polymorphicTypeValidator(ptv) + .build(); + + mapper.readValue(string, Person.class); + }); + } +} + +class UnsafeCatDeserialization { + + // BAD: deserializing untrusted input while polymorphic type handling is on + private static void testUnsafeDeserialization() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.enableDefaultTyping(); // this enables polymorphic type handling + mapper.readValue(string, Cat.class); + }); + } + + // BAD: deserializing untrusted input while polymorphic type handling is on + private static void testUnsafeDeserializationWithObjectMapperReadValues() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.enableDefaultTyping(); + mapper.readValues(new JsonFactory().createParser(string), Cat.class).readAll(); + }); + } + + // BAD: deserializing untrusted input while polymorphic type handling is on + private static void testUnsafeDeserializationWithObjectMapperTreeToValue() throws Exception { + JacksonTest.withSocket(string -> { + ObjectMapper mapper = new ObjectMapper(); + mapper.enableDefaultTyping(); + mapper.treeToValue(mapper.readTree(string), Cat.class); + }); + } + + // BAD: an attacker can control both data and type of deserialized object + private static void testUnsafeDeserializationWithUnsafeClass() throws Exception { + JacksonTest.withSocket(input -> { + String[] parts = input.split(";"); + String data = parts[0]; + String type = parts[1]; + Class clazz = Class.forName(type); + ObjectMapper mapper = new ObjectMapper(); + mapper.readValue(data, clazz); + }); + } +} + +class SaferCatDeserialization { + + // GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper + // has a validator + private static void testUnsafeDeserialization() throws Exception { + JacksonTest.withSocket(string -> { + PolymorphicTypeValidator ptv = + BasicPolymorphicTypeValidator.builder() + .allowIfSubType("only.allowed.pachage") + .build(); + + ObjectMapper mapper = JsonMapper.builder().polymorphicTypeValidator(ptv).build(); + mapper.enableDefaultTyping(); // this enables polymorphic type handling + + mapper.readValue(string, Cat.class); + }); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected index 7b02131cd73..dd220266013 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected @@ -80,6 +80,22 @@ edges | C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:87:3:87:13 | burlapInput | | C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:91:3:91:14 | burlapInput1 | | C.java:85:54:85:67 | serializedData : byte[] | C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | +| JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:19:54:19:58 | bytes [post update] : byte[] | +| JacksonTest.java:19:54:19:58 | bytes [post update] : byte[] | JacksonTest.java:21:28:21:35 | jexlExpr : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:73:32:73:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:82:32:82:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:91:32:91:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:138:32:138:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:147:32:147:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:156:32:156:37 | string : String | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | JacksonTest.java:165:32:165:36 | input : String | +| JacksonTest.java:73:32:73:37 | string : String | JacksonTest.java:75:30:75:35 | string | +| JacksonTest.java:82:32:82:37 | string : String | JacksonTest.java:84:30:84:35 | string | +| JacksonTest.java:91:32:91:37 | string : String | JacksonTest.java:93:30:93:35 | string | +| JacksonTest.java:138:32:138:37 | string : String | JacksonTest.java:141:30:141:35 | string | +| JacksonTest.java:147:32:147:37 | string : String | JacksonTest.java:150:31:150:68 | createParser(...) | +| JacksonTest.java:156:32:156:37 | string : String | JacksonTest.java:159:32:159:54 | readTree(...) | +| JacksonTest.java:165:32:165:36 | input : String | JacksonTest.java:171:30:171:33 | data | | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | | TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | @@ -176,6 +192,23 @@ nodes | C.java:85:54:85:67 | serializedData : byte[] | semmle.label | serializedData : byte[] | | C.java:87:3:87:13 | burlapInput | semmle.label | burlapInput | | C.java:91:3:91:14 | burlapInput1 | semmle.label | burlapInput1 | +| JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | +| JacksonTest.java:19:54:19:58 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] | +| JacksonTest.java:21:28:21:35 | jexlExpr : String | semmle.label | jexlExpr : String | +| JacksonTest.java:73:32:73:37 | string : String | semmle.label | string : String | +| JacksonTest.java:75:30:75:35 | string | semmle.label | string | +| JacksonTest.java:82:32:82:37 | string : String | semmle.label | string : String | +| JacksonTest.java:84:30:84:35 | string | semmle.label | string | +| JacksonTest.java:91:32:91:37 | string : String | semmle.label | string : String | +| JacksonTest.java:93:30:93:35 | string | semmle.label | string | +| JacksonTest.java:138:32:138:37 | string : String | semmle.label | string : String | +| JacksonTest.java:141:30:141:35 | string | semmle.label | string | +| JacksonTest.java:147:32:147:37 | string : String | semmle.label | string : String | +| JacksonTest.java:150:31:150:68 | createParser(...) | semmle.label | createParser(...) | +| JacksonTest.java:156:32:156:37 | string : String | semmle.label | string : String | +| JacksonTest.java:159:32:159:54 | readTree(...) | semmle.label | readTree(...) | +| JacksonTest.java:165:32:165:36 | input : String | semmle.label | input : String | +| JacksonTest.java:171:30:171:33 | data | semmle.label | data | | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | semmle.label | entityStream : InputStream | | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | semmle.label | new ObjectInputStream(...) | | TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | semmle.label | entityStream : InputStream | @@ -226,4 +259,11 @@ nodes | C.java:79:3:79:72 | unmarshal(...) | C.java:79:43:79:70 | getParameter(...) : String | C.java:79:26:79:71 | new StringReader(...) | Unsafe deserialization of $@. | C.java:79:43:79:70 | getParameter(...) | user input | | C.java:87:3:87:26 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:87:3:87:13 | burlapInput | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input | | C.java:91:3:91:27 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:91:3:91:14 | burlapInput1 | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input | +| JacksonTest.java:75:13:75:50 | readValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:75:30:75:35 | string | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:84:13:84:52 | readValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:84:30:84:35 | string | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:93:13:93:48 | readValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:93:30:93:35 | string | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:141:13:141:47 | readValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:141:30:141:35 | string | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:150:13:150:80 | readValues(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:150:31:150:68 | createParser(...) | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:159:13:159:66 | treeToValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:159:32:159:54 | readTree(...) | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | +| JacksonTest.java:171:13:171:41 | readValue(...) | JacksonTest.java:19:25:19:47 | getInputStream(...) : InputStream | JacksonTest.java:171:30:171:33 | data | Unsafe deserialization of $@. | JacksonTest.java:19:25:19:47 | getInputStream(...) | user input | | TestMessageBodyReader.java:22:18:22:65 | readObject(...) | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | Unsafe deserialization of $@. | TestMessageBodyReader.java:20:55:20:78 | entityStream | user input | diff --git a/java/ql/test/query-tests/security/CWE-502/options b/java/ql/test/query-tests/security/CWE-502/options index 03027487dce..fc5cac9e843 100644 --- a/java/ql/test/query-tests/security/CWE-502/options +++ b/java/ql/test/query-tests/security/CWE-502/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.10 diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/annotation/JsonTypeInfo.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/annotation/JsonTypeInfo.java new file mode 100644 index 00000000000..605c313607e --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/annotation/JsonTypeInfo.java @@ -0,0 +1,27 @@ +package com.fasterxml.jackson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface JsonTypeInfo { + JsonTypeInfo.Id use(); + + public static enum Id { + CLASS("@class"), + MINIMAL_CLASS("@c"); + + private final String _defaultPropertyName; + + private Id(String defProp) { + this._defaultPropertyName = defProp; + } + + public String getDefaultPropertyName() { + return this._defaultPropertyName; + } + } +} diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonFactory.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonFactory.java index 06f71ab187d..12696cd4397 100644 --- a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonFactory.java +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonFactory.java @@ -9,4 +9,8 @@ public class JsonFactory { public JsonGenerator createGenerator(Writer writer) { return new JsonGenerator(); } + + public JsonParser createParser(String content) { + return null; + } } diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonParser.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonParser.java new file mode 100644 index 00000000000..2c5527d50ab --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/JsonParser.java @@ -0,0 +1,3 @@ +package com.fasterxml.jackson.core; + +public abstract class JsonParser {} diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/TreeNode.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/TreeNode.java new file mode 100644 index 00000000000..0d89838457a --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/core/TreeNode.java @@ -0,0 +1,3 @@ +package com.fasterxml.jackson.core; + +public interface TreeNode {} diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/JsonNode.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/JsonNode.java index b04572cd4da..06602e943f5 100644 --- a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/JsonNode.java +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/JsonNode.java @@ -1,8 +1,8 @@ package com.fasterxml.jackson.databind; import java.util.*; +import com.fasterxml.jackson.core.TreeNode; -public abstract class JsonNode implements Iterable { - public JsonNode() { - } +public abstract class JsonNode implements TreeNode, Iterable { + public JsonNode() {} } diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/MappingIterator.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/MappingIterator.java index ac427ef01c9..929676e6456 100644 --- a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/MappingIterator.java +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/MappingIterator.java @@ -25,4 +25,8 @@ public class MappingIterator implements Iterator, Closeable { public void close() throws IOException { } + + public List readAll() { + return null; + } } diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/ObjectMapper.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/ObjectMapper.java index 71dc99a351d..ed17a18935e 100644 --- a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/ObjectMapper.java +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/ObjectMapper.java @@ -1,5 +1,8 @@ package com.fasterxml.jackson.databind; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; import java.io.*; import java.util.*; @@ -38,4 +41,28 @@ public class ObjectMapper { public T convertValue(Object fromValue, Class toValueType) throws IllegalArgumentException { return null; } + + public ObjectMapper setPolymorphicTypeValidator(PolymorphicTypeValidator ptv) { + return null; + } + + public ObjectMapper enableDefaultTyping() { + return null; + } + + public T readValue(String content, Class valueType) { + return null; + } + + public MappingIterator readValues(JsonParser p, Class valueType) { + return null; + } + + public T treeToValue(TreeNode n, Class valueType) { + return null; + } + + public JsonNode readTree(String content) { + return null; + } } diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/cfg/MapperBuilder.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/cfg/MapperBuilder.java new file mode 100644 index 00000000000..db2c24c4362 --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/cfg/MapperBuilder.java @@ -0,0 +1,9 @@ +package com.fasterxml.jackson.databind.cfg; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; + +public abstract class MapperBuilder> { + public M build() { return null; } + public B polymorphicTypeValidator(PolymorphicTypeValidator ptv) { return null; } +} diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/json/JsonMapper.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/json/JsonMapper.java new file mode 100644 index 00000000000..adec92a9210 --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/json/JsonMapper.java @@ -0,0 +1,9 @@ +package com.fasterxml.jackson.databind.json; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.cfg.MapperBuilder; + +public class JsonMapper extends ObjectMapper { + public static JsonMapper.Builder builder() { return null; } + public static class Builder extends MapperBuilder {} +} \ No newline at end of file diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.java new file mode 100644 index 00000000000..243cd467b4b --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/BasicPolymorphicTypeValidator.java @@ -0,0 +1,10 @@ +package com.fasterxml.jackson.databind.jsontype; + +public class BasicPolymorphicTypeValidator extends PolymorphicTypeValidator { + public static BasicPolymorphicTypeValidator.Builder builder() { return null; } + + public static class Builder { + public BasicPolymorphicTypeValidator.Builder allowIfSubType(final String prefixForSubType) { return null; } + public BasicPolymorphicTypeValidator build() { return null; } + } +} diff --git a/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.java b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.java new file mode 100644 index 00000000000..37e68d2c429 --- /dev/null +++ b/java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.java @@ -0,0 +1,3 @@ +package com.fasterxml.jackson.databind.jsontype; + +public abstract class PolymorphicTypeValidator {}