Files
codeql/java/ql/test/query-tests/security/CWE-502/JoddJsonServlet.java
2025-06-24 16:42:14 +02:00

103 lines
3.9 KiB
Java

import java.io.IOException;
import java.io.Reader;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jodd.json.JsonParser;
import com.example.User;
import com.thirdparty.Person;
public class JoddJsonServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
// GOOD: class type specified (despite a dangerous configuration)
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String json = req.getParameter("json");
String clazz = req.getParameter("class");
JsonParser parser = new JsonParser();
parser.setClassMetadataName("class");
Person person = parser.parse(json, Person.class);
}
@Override
// BAD: dangerously configured parser with no class restriction passed to `parse`,
// using a few different possible call sequences.
public void doHead(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String json = req.getParameter("json"); // $ Source
String clazz = req.getParameter("class");
int callOrder;
try {
callOrder = Integer.parseInt(req.getParameter("callOrder"));
}
catch(NumberFormatException e) {
throw new RuntimeException(e);
}
JsonParser parser = new JsonParser();
if(callOrder == 0) {
parser.setClassMetadataName("class");
User obj = parser.parse(json, null); // $ Alert
} else if(callOrder == 1) {
parser.setClassMetadataName("class").parse(json, null); // $ Alert
} else if(callOrder == 2) {
parser.setClassMetadataName("class").lazy(true).parse(json, null); // $ Alert
} else if(callOrder == 3) {
parser.withClassMetadata(true).lazy(true).parse(json, null); // $ Alert
}
}
@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"); // $ Source
String clazz = req.getParameter("class");
try {
JsonParser parser = new JsonParser();
Object obj = parser.parse(json, Class.forName(clazz)); // $ Alert
} catch (ClassNotFoundException cne) {
throw new IOException(cne.getMessage());
}
}
@Override
// GOOD: dangerously configured parser is ameliorated by setting a list of allowed classes, using various call orders,
// or by explicitly disabling the class metadata option.
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String json = req.getParameter("json");
String clazz = req.getParameter("class");
int callOrder;
try {
callOrder = Integer.parseInt(req.getParameter("callOrder"));
}
catch(NumberFormatException e) {
throw new RuntimeException(e);
}
JsonParser parser = new JsonParser();
if(callOrder == 0) {
parser.setClassMetadataName("class");
parser.allowClass("example.Class");
User obj = parser.parse(json, null);
} else if(callOrder == 1) {
parser.allowClass("example.Class");
parser.setClassMetadataName("class");
User obj = parser.parse(json, null);
} else if(callOrder == 2) {
parser.setClassMetadataName("class").allowClass("example.Class").parse(json, null);
} else if(callOrder == 3) {
parser.allowClass("example.Class").setClassMetadataName("class").parse(json, null);
} else if(callOrder == 4) {
parser.setClassMetadataName("class").withClassMetadata(false).parse(json, null);
} else if(callOrder == 5) {
parser.withClassMetadata(true).setClassMetadataName(null).parse(json, null);
}
}
}