mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Add Gson support to unsafe deserialization query
This commit is contained in:
24
java/ql/test/query-tests/security/CWE-502/AndroidManifest.xml
Executable file
24
java/ql/test/query-tests/security/CWE-502/AndroidManifest.xml
Executable file
@@ -0,0 +1,24 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.app"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1"
|
||||
android:versionName="0.1" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".GsonActivity"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
17
java/ql/test/query-tests/security/CWE-502/GsonActivity.java
Normal file
17
java/ql/test/query-tests/security/CWE-502/GsonActivity.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.example.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class GsonActivity extends Activity {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(-1);
|
||||
|
||||
ParcelableEntity entity = (ParcelableEntity) getIntent().getParcelableExtra("jsonEntity");
|
||||
}
|
||||
}
|
||||
77
java/ql/test/query-tests/security/CWE-502/GsonServlet.java
Normal file
77
java/ql/test/query-tests/security/CWE-502/GsonServlet.java
Normal file
@@ -0,0 +1,77 @@
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.typeadapters.RuntimeTypeAdapterFactory;
|
||||
|
||||
import com.example.User;
|
||||
import com.thirdparty.Person;
|
||||
|
||||
public class GsonServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
// GOOD: concrete class type specified
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, User.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
// GOOD: concrete class type specified
|
||||
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, Person.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
// BAD: allow class name to be controlled by remote source
|
||||
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, Class.forName(clazz)); // $unsafeDeserialization
|
||||
} catch (ClassNotFoundException cne) {
|
||||
throw new IOException(cne.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// BAD: allow class name to be controlled by remote source even with a type adapter factory
|
||||
public void doHead(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
try {
|
||||
RuntimeTypeAdapterFactory<User> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
|
||||
.of(User.class, "type");
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(runtimeTypeAdapterFactory).create();
|
||||
Object obj = gson.fromJson(json, Class.forName(clazz)); // $unsafeDeserialization
|
||||
} catch (ClassNotFoundException cne) {
|
||||
throw new IOException(cne.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// GOOD: specify allowed class types without explicitly configured vulnerable subclass types
|
||||
public void doTrace(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
RuntimeTypeAdapterFactory<Person> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
|
||||
.of(Person.class, "type");
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(runtimeTypeAdapterFactory).create();
|
||||
Person obj = gson.fromJson(json, Person.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.example.app;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class ParcelableEntity implements Parcelable {
|
||||
private static final Gson GSON = new GsonBuilder().create();
|
||||
|
||||
public ParcelableEntity(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
private Object obj;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
parcel.writeString(obj.getClass().getName());
|
||||
parcel.writeString(GSON.toJson(obj));
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator CREATOR = new Creator<ParcelableEntity>() {
|
||||
@Override
|
||||
public ParcelableEntity createFromParcel(Parcel parcel) {
|
||||
try {
|
||||
Class clazz = Class.forName(parcel.readString());
|
||||
Object obj = GSON.fromJson(parcel.readString(), clazz); // $unsafeDeserialization
|
||||
return new ParcelableEntity(obj);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableEntity[] newArray(int size) {
|
||||
return new ParcelableEntity[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.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.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0
|
||||
|
||||
Reference in New Issue
Block a user