Skip to content

Instantly share code, notes, and snippets.

@hatakawas
Created December 29, 2021 02:23
Show Gist options
  • Save hatakawas/c586ef0074aeb751edad00d898521965 to your computer and use it in GitHub Desktop.
Save hatakawas/c586ef0074aeb751edad00d898521965 to your computer and use it in GitHub Desktop.
检测一个URL是否会引起SSRF问题
@Slf4j
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SsrfChecker {
private List<String> allowedProtocols;
private List<Integer> allowedPorts;
private List<String> deniedHosts;
private List<String> allowedHosts;
public boolean isSafe(String url) throws MalformedURLException {
URL urlObj = new URL(url);
return isSafeProtocol(urlObj) && isSafePort(urlObj) && isSafeHost(urlObj);
}
public boolean isSafeProtocol(URL url) {
boolean isSafe = false;
String protocol = url.getProtocol();
for (String p : allowedProtocols) {
if (protocol.equalsIgnoreCase(p)) {
isSafe = true;
break;
}
}
return isSafe;
}
public boolean isSafePort(URL url) {
boolean isSafe = false;
int port = url.getPort();
for (Integer p : allowedPorts) {
if (port == p) {
isSafe = true;
break;
}
}
return isSafe;
}
public boolean isSafeHost(URL url) {
boolean isSafe = true;
String host = url.getHost().toLowerCase();
for (String deniedHost : deniedHosts) { // 主机黑名单
if (isMatch(host, deniedHost)) {
isSafe = false;
break;
}
}
for (String allowedHost : allowedHosts) { // 主机白名单
if (isMatch(host, allowedHost)) {
isSafe = true;
break;
}
}
return isSafe;
}
/**
* 通配符匹配
*
* @param s 待匹配字符串
* @param p 通配符模式串
* @return 匹配结果
*/
public boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
for (int i = 1; i <= n; i++) {
dp[0][i] = dp[0][i - 1] && p.charAt(i - 1) == '*';
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
dp[i][j] = dp[i - 1][j - 1];
} else if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
}
}
}
return dp[m][n];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment