Skip to content

Commit b37bed3

Browse files
committed
change format for sf rule
1 parent 562617f commit b37bed3

File tree

7 files changed

+237
-28
lines changed

7 files changed

+237
-28
lines changed

java-command-exec/java-command-exec.sf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
desc(
2-
title: "Find Runtime.getRuntime().exec Point",
2+
title: "Find Runtime.getRuntime().exec Sink Point",
3+
title_zh: "查找 Runtime.getRuntime().exec 参数位置",
34
lib: 'runtime-exec',
45
type: audit,
56
)
Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,51 @@
11
desc(
2-
title: 'checking [freemaker.Template.Process directly]',
3-
type: audit
2+
title: 'checking [freemaker.Template.Process directly] audit prompt',
3+
type: audit,
4+
level: warning,
45
)
6+
getTemplate(,*?{!opcode: const} as $sink).process(,* as $params,);
7+
check $params;
8+
$params.put(,,* as $sink);
9+
check $sink then "Found Freemaker Process Using" else "No Freemaker Process Simple";
10+
alert $sink;
11+
12+
desc(
13+
lang: java,
14+
'file://basic.java': <<<BASIC
15+
import freemarker.template.*;
516

6-
// write your SyntaxFlow Rule, like:
7-
// DocumentBuilderFactory.newInstance()...parse(* #-> * as $source) as $sink; // find some call chain for parse
8-
// check $sink then 'find sink point' else 'No Found' // if not found sink, the rule will stop here and report error
9-
// alert $source // record $source
17+
import java.io.*;
18+
import java.util.*;
1019

11-
getTemplate().process() as $sink;
20+
public class FreemarkerExample {
21+
public static void main(String[] args) {
22+
// 配置 Freemarker
23+
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
24+
try {
25+
cfg.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
26+
cfg.setDefaultEncoding("UTF-8");
27+
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
28+
cfg.setLogTemplateExceptions(false);
29+
cfg.setWrapUncheckedExceptions(true);
1230

13-
check $sink then "Found Freemaker Process Using" else "No Freemaker Process Simple";
31+
// 加载模板
32+
Template template = cfg.getTemplate("welcome.ftl");
33+
34+
// 数据模型
35+
Map<String, Object> templateData = new HashMap<>();
36+
templateData.put("user", "John Doe");
37+
38+
// 渲染模板
39+
Writer out = new StringWriter();
40+
template.process(templateData, out);
41+
42+
// 输出渲染后的文本
43+
System.out.println(out.toString());
1444

15-
// the template is generate by yak.ssa.syntaxflow command line
45+
} catch (IOException | TemplateException e) {
46+
e.printStackTrace();
47+
}
48+
}
49+
}
50+
BASIC
51+
)
Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
desc(
2-
title: 'checking [freemaker.Template.CreateProcessingEnvironment]',
3-
type: audit
2+
title: 'checking [freemaker.Template.CreateProcessingEnvironment] use point',
3+
type: audit,
4+
level: warning,
45
)
56

6-
// write your SyntaxFlow Rule, like:
7-
// DocumentBuilderFactory.newInstance()...parse(* #-> * as $source) as $sink; // find some call chain for parse
8-
// check $sink then 'find sink point' else 'No Found' // if not found sink, the rule will stop here and report error
9-
// alert $source // record $source
10-
117
getTemplate().createProcessingEnvironment() as $env;
128
$env.process() as $sink;
139
$env.invoke() as $sink;
1410

1511
check $sink then "Found Freemaker CreateProcessingEnvironment invoke or process";
1612
alert $env;
17-
18-
// the template is generate by yak.ssa.syntaxflow command line

java-jdbc/java-jdbc-execute.sf

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,56 @@
11
desc(
22
title: "JDBC getConnection.createStatement.executeQuery SQL",
33
title_zh: "JDBC getConnection.createStatement.executeQuery SQL 执行语句",
4-
is_vuln: "false",
4+
type: audit,
5+
level: 'low',
6+
lib: 'jdbc-raw-execute-sink',
57
)
68

79
DriverManager.getConnection().createStatement() as $stmt;
810
$stmt?{!.set*()} as $checkedStmt;
9-
$checkedStmt.executeQuery() as $sink;
11+
$checkedStmt.executeQuery(*<slice(start=1)> as $sink);
12+
check $sink;
1013

11-
check $sink;
14+
$sink as $output;
15+
alert $output;
16+
17+
desc(
18+
lang: java,
19+
"file:///unsafe.java": <<<UNSAFE
20+
import java.sql.*;
21+
22+
public class JdbcExample {
23+
public static void main(String[] args) {
24+
String url = "jdbc:mysql://localhost:3306/exampledb";
25+
String username = "root";
26+
String password = "password";
27+
28+
try {
29+
// 加载和注册 JDBC 驱动
30+
Class.forName("com.mysql.cj.jdbc.Driver");
31+
32+
// 建立连接
33+
Connection conn = DriverManager.getConnection(url, username, password);
34+
35+
// 创建 Statement
36+
Statement stmt = conn.createStatement();
37+
38+
// 执行查询
39+
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
40+
41+
// 处理 ResultSet
42+
while (rs.next()) {
43+
System.out.println(rs.getString("username"));
44+
}
45+
46+
// 关闭连接
47+
rs.close();
48+
stmt.close();
49+
conn.close();
50+
} catch (Exception e) {
51+
e.printStackTrace();
52+
}
53+
}
54+
}
55+
UNSAFE
56+
)

java-jdbc/java-jdbc-prepare-stmt.sf

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
11
desc(
22
title: "JDBC getConnection.prepareStatement.executeQuery SQL",
33
title_zh: "JDBC getConnection.prepareStatement.executeQuery SQL 执行语句",
4-
is_vuln: "false",
4+
type: audit,
5+
level: low,
6+
lib: 'jdbc-prepared-execute-sink'
57
)
68

79
DriverManager.getConnection() as $conn;
8-
$conn.prepareStatement() as $stmt;
9-
$stmt.executeQuery() as $sink;
10+
$conn.prepareStatement(*<slice(start=1)> as $output) as $stmt;
11+
$stmt.executeQuery() as $call;
12+
check $call;
13+
check $output;
14+
alert $output;
1015

11-
// check $sink then "Prepared Statement SQL ExecuteQuery" then "Not Found Prepare Statement SQL ExecuteQuery";
16+
desc(
17+
lang: java,
18+
"file://a.java": <<<CODE
19+
import java.sql.*;
20+
21+
public class PreparedStatementExample {
22+
public static void main(String[] args) {
23+
String url = "jdbc:mysql://localhost:3306/exampledb";
24+
String username = "root";
25+
String password = "password";
26+
String userId = "1"; // 假设这是用户输入
27+
28+
try {
29+
Connection conn = DriverManager.getConnection(url, username, password);
30+
31+
// 使用 PreparedStatement
32+
String sql = "SELECT * FROM users WHERE id = ?";
33+
PreparedStatement pstmt = conn.prepareStatement(sql);
34+
pstmt.setString(1, userId); // 设置占位符的值
35+
36+
ResultSet rs = pstmt.executeQuery();
37+
38+
while (rs.next()) {
39+
System.out.println(rs.getString("username"));
40+
}
41+
42+
rs.close();
43+
pstmt.close();
44+
conn.close();
45+
} catch (SQLException e) {
46+
e.printStackTrace();
47+
}
48+
}
49+
}
50+
CODE
51+
)
Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
1+
desc(
2+
title: "Unsafe Config for CSRF Protection '.csrf().disable()'",
3+
title_zh: "关闭 CSRF 保护",
4+
type: vuln,
5+
level: low,
6+
)
7+
18
configure(* as $configEntry);
9+
check $configEntry;
210

311
$configEntry ... csrf().disable() as $disableCSRF;
4-
512
check $disableCSRF;
13+
alert $disableCSRF;
14+
15+
desc(
16+
lang: java,
17+
'safefile://config2.java': <<<SAFE
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
20+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
21+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
22+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
23+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
24+
import org.springframework.security.crypto.password.PasswordEncoder;
25+
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
26+
27+
@EnableWebSecurity
28+
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
29+
30+
@Override
31+
protected void configure(HttpSecurity http) throws Exception {
32+
http
33+
.csrf().enable().and() // 开启 CSRF 保护,默认使用
34+
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 使用 Cookie 存储 CSRF 令牌
35+
.and()
36+
.headers()
37+
.contentSecurityPolicy("script-src 'self'; report-uri /csp-report-endpoint/"); // 添加 CSP 策略
38+
}
39+
}
40+
SAFE,
41+
'file://config.java': <<<CONFIG
42+
import org.springframework.context.annotation.Bean;
43+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
44+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
45+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
46+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
47+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
48+
import org.springframework.security.crypto.password.PasswordEncoder;
49+
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
50+
51+
@EnableWebSecurity
52+
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
53+
54+
@Override
55+
protected void configure(HttpSecurity http) throws Exception {
56+
http
57+
.csrf().disable().and() // 开启 CSRF 保护,默认使用
58+
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 使用 Cookie 存储 CSRF 令牌
59+
.and()
60+
.headers()
61+
.contentSecurityPolicy("script-src 'self'; report-uri /csp-report-endpoint/"); // 添加 CSP 策略
62+
}
63+
}
64+
CONFIG
65+
)
Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,42 @@
1+
desc(
2+
title: "Find XSS Filter Call Existed, Please Checking Bypass tactics",
3+
title_zh: "XSS 过滤器被使用,请排查是否可绕过",
4+
type: audit,
5+
level: low,
6+
)
7+
18
/(?i).*xss.*((clear)|(filter)|(escape)).*/ as $entryCall;
29
/(?i)((clear)|(filter)|(escape)).*xss.*/ as $entryCall;
310

411
$entryCall(* as $paramEntry);
512
$paramEntry.../(?i)replace(all)?/() as $replacers;
613

714
check $entryCall then "Find XSS Escaper" else "No XSS Escaper";
8-
alert $replacers;
15+
alert $entryCall;
16+
17+
desc(
18+
lang: java,
19+
"file:///unsafe.java": <<<UNSAFE
20+
@ApiIgnore
21+
@Controller("dynamicPageAction")
22+
@RequestMapping("/demo/clearXSS")
23+
public class MCmsAction extends net.demo.cms.action.BaseAction {
24+
private String clearXss(String value) {
25+
26+
if (value == null || "".equals(value)) {
27+
return value;
28+
}
29+
30+
value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
31+
value = value.replaceAll("\\(", "&#40;").replace("\\)", "&#41;");
32+
value = value.replaceAll("'", "&#39;");
33+
value = value.replaceAll("eval\\((.*)\\)", "");
34+
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']",
35+
"\"\"");
36+
value = value.replace("script", "");
937

38+
return value;
39+
}
40+
}
41+
UNSAFE
42+
)

0 commit comments

Comments
 (0)