Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Administrator
/
framework-tools
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 76178edf
authored
Jul 04, 2024
by
henry
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
删除多余的包
1 parent
9833ab8e
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
403 deletions
arch-gateway/src/main/java/org/arch/config/xssFilter/JsonUtil.java
arch-gateway/src/main/java/org/arch/config/xssFilter/XssFilter.java
arch-gateway/src/main/java/org/arch/config/xssFilter/XssUtil.java
arch-gateway/src/main/java/org/arch/config/xssFilter/JsonUtil.java
deleted
100644 → 0
View file @
9833ab8
package
org
.
arch
.
config
.
xssFilter
;
import
com.alibaba.fastjson.JSONObject
;
import
org.springframework.util.StringUtils
;
/**
* JSON处理工具类
*
* @author lieber
*/
public
enum
JsonUtil
{
/**
* 实例
*/
INSTANCE
;
/**
* json对象字符串开始标记
*/
private
final
static
String
JSON_OBJECT_START
=
"{"
;
/**
* json对象字符串结束标记
*/
private
final
static
String
JSON_OBJECT_END
=
"}"
;
/**
* json数组字符串开始标记
*/
private
final
static
String
JSON_ARRAY_START
=
"["
;
/**
* json数组字符串结束标记
*/
private
final
static
String
JSON_ARRAY_END
=
"]"
;
/**
* 判断字符串是否json对象字符串
*
* @param val 字符串
* @return true/false
*/
public
boolean
isJsonObj
(
String
val
)
{
if
(
StringUtils
.
isEmpty
(
val
))
{
return
false
;
}
val
=
val
.
trim
();
if
(
val
.
startsWith
(
JSON_OBJECT_START
)
&&
val
.
endsWith
(
JSON_OBJECT_END
))
{
try
{
JSONObject
.
parseObject
(
val
);
return
true
;
}
catch
(
Exception
e
)
{
return
false
;
}
}
return
false
;
}
/**
* 判断字符串是否json数组字符串
*
* @param val 字符串
* @return true/false
*/
public
boolean
isJsonArr
(
String
val
)
{
if
(
StringUtils
.
isEmpty
(
val
))
{
return
false
;
}
val
=
val
.
trim
();
if
(
StringUtils
.
isEmpty
(
val
))
{
return
false
;
}
val
=
val
.
trim
();
if
(
val
.
startsWith
(
JSON_ARRAY_START
)
&&
val
.
endsWith
(
JSON_ARRAY_END
))
{
try
{
JSONObject
.
parseArray
(
val
);
return
true
;
}
catch
(
Exception
e
)
{
return
false
;
}
}
return
false
;
}
/**
* 判断对象是否是json对象
*
* @param obj 待判断对象
* @return true/false
*/
public
boolean
isJsonObj
(
Object
obj
)
{
String
str
=
JSONObject
.
toJSONString
(
obj
);
return
this
.
isJsonObj
(
str
);
}
/**
* 判断字符串是否json字符串
*
* @param str 字符串
* @return true/false
*/
public
boolean
isJson
(
String
str
)
{
if
(
StringUtils
.
isEmpty
(
str
))
{
return
false
;
}
return
this
.
isJsonObj
(
str
)
||
this
.
isJsonArr
(
str
);
}
}
arch-gateway/src/main/java/org/arch/config/xssFilter/XssFilter.java
deleted
100644 → 0
View file @
9833ab8
package
org
.
arch
.
config
.
xssFilter
;
import
io.netty.buffer.ByteBufAllocator
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cloud.gateway.filter.GatewayFilterChain
;
import
org.springframework.cloud.gateway.filter.GlobalFilter
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.io.buffer.DataBuffer
;
import
org.springframework.core.io.buffer.DataBufferUtils
;
import
org.springframework.core.io.buffer.NettyDataBufferFactory
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.server.reactive.ServerHttpRequest
;
import
org.springframework.http.server.reactive.ServerHttpRequestDecorator
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.server.ServerWebExchange
;
import
reactor.core.publisher.Flux
;
import
reactor.core.publisher.Mono
;
import
javax.validation.constraints.NotEmpty
;
import
java.net.URI
;
import
java.nio.charset.StandardCharsets
;
import
java.util.List
;
import
java.util.Optional
;
/**
* XSS过滤
*
*/
//@Component
@Slf4j
//@ConfigurationProperties("config.xss")
@Data
//@Order(4)
public
class
XssFilter
implements
GlobalFilter
,
Ordered
{
private
List
<
XssWhiteUrl
>
whiteUrls
;
@Override
public
Mono
<
Void
>
filter
(
ServerWebExchange
exchange
,
GatewayFilterChain
chain
)
{
ServerHttpRequest
request
=
exchange
.
getRequest
();
URI
uri
=
request
.
getURI
();
String
method
=
request
.
getMethodValue
();
if
(
this
.
white
(
uri
.
getPath
(),
method
))
{
return
chain
.
filter
(
exchange
);
}
if
((
HttpMethod
.
POST
.
name
().
equals
(
method
)
||
HttpMethod
.
PUT
.
name
().
equals
(
method
)))
{
return
DataBufferUtils
.
join
(
request
.
getBody
()).
flatMap
(
d
->
Mono
.
just
(
Optional
.
of
(
d
))).
defaultIfEmpty
(
Optional
.
empty
())
.
flatMap
(
optional
->
{
// 取出body中的参数
String
bodyString
=
""
;
if
(
optional
.
isPresent
())
{
byte
[]
oldBytes
=
new
byte
[
optional
.
get
().
readableByteCount
()];
optional
.
get
().
read
(
oldBytes
);
bodyString
=
new
String
(
oldBytes
,
StandardCharsets
.
UTF_8
);
}
HttpHeaders
httpHeaders
=
request
.
getHeaders
();
// 执行XSS清理
log
.
info
(
"{} - [{}] XSS处理前参数:{}"
,
method
,
uri
.
getPath
(),
bodyString
);
bodyString
=
XssUtil
.
INSTANCE
.
cleanXss
(
bodyString
);
log
.
info
(
"{} - [{}] XSS处理后参数:{}"
,
method
,
uri
.
getPath
(),
bodyString
);
ServerHttpRequest
newRequest
=
request
.
mutate
().
uri
(
uri
).
build
();
// 重新构造body
byte
[]
newBytes
=
bodyString
.
getBytes
(
StandardCharsets
.
UTF_8
);
DataBuffer
bodyDataBuffer
=
toDataBuffer
(
newBytes
);
Flux
<
DataBuffer
>
bodyFlux
=
Flux
.
just
(
bodyDataBuffer
);
// 重新构造header
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
putAll
(
httpHeaders
);
// 由于修改了传递参数,需要重新设置CONTENT_LENGTH,长度是字节长度,不是字符串长度
int
length
=
newBytes
.
length
;
headers
.
remove
(
HttpHeaders
.
CONTENT_LENGTH
);
headers
.
setContentLength
(
length
);
headers
.
set
(
HttpHeaders
.
CONTENT_TYPE
,
"application/json;charset=utf8"
);
// 重写ServerHttpRequestDecorator,修改了body和header,重写getBody和getHeaders方法
newRequest
=
new
ServerHttpRequestDecorator
(
newRequest
)
{
@Override
public
Flux
<
DataBuffer
>
getBody
()
{
return
bodyFlux
;
}
@Override
public
HttpHeaders
getHeaders
()
{
return
headers
;
}
};
return
chain
.
filter
(
exchange
.
mutate
().
request
(
newRequest
).
build
());
});
}
else
{
return
chain
.
filter
(
exchange
);
}
}
/**
* 是否是白名单
*
* @param url 路由
* @param method 请求方式
* @return true/false
*/
private
boolean
white
(
String
url
,
String
method
)
{
return
whiteUrls
!=
null
&&
whiteUrls
.
contains
(
XssWhiteUrl
.
builder
().
url
(
url
).
method
(
method
).
build
());
}
/**
* 字节数组转DataBuffer
*
* @param bytes 字节数组
* @return DataBuffer
*/
private
DataBuffer
toDataBuffer
(
byte
[]
bytes
)
{
NettyDataBufferFactory
nettyDataBufferFactory
=
new
NettyDataBufferFactory
(
ByteBufAllocator
.
DEFAULT
);
DataBuffer
buffer
=
nettyDataBufferFactory
.
allocateBuffer
(
bytes
.
length
);
buffer
.
write
(
bytes
);
return
buffer
;
}
public
static
final
int
ORDER
=
10
;
@Override
public
int
getOrder
()
{
return
ORDER
;
}
@Data
@Validated
@AllArgsConstructor
@NoArgsConstructor
@Builder
private
static
class
XssWhiteUrl
{
@NotEmpty
private
String
url
;
@NotEmpty
private
String
method
;
}
}
arch-gateway/src/main/java/org/arch/config/xssFilter/XssUtil.java
deleted
100644 → 0
View file @
9833ab8
package
org
.
arch
.
config
.
xssFilter
;
import
com.alibaba.fastjson.JSONObject
;
import
org.jsoup.Jsoup
;
import
org.jsoup.nodes.Document
;
import
org.jsoup.safety.Safelist
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
/**
* xss拦截工具类
*
* @author lieber
*/
public
enum
XssUtil
{
/**
* 实例
*/
INSTANCE
;
private
final
static
String
RICH_TEXT
=
"</"
;
/**
* 自定义白名单
*/
private
final
static
Safelist
CUSTOM_WHITELIST
=
Safelist
.
relaxed
()
.
addAttributes
(
"video"
,
"width"
,
"height"
,
"controls"
,
"alt"
,
"src"
)
.
addAttributes
(
":all"
,
"style"
,
"class"
);
/**
* jsoup不格式化代码
*/
private
final
static
Document
.
OutputSettings
OUTPUT_SETTINGS
=
new
Document
.
OutputSettings
().
prettyPrint
(
false
);
/**
* 清除json对象中的xss攻击字符
*
* @param val json对象字符串
* @return 清除后的json对象字符串
*/
private
String
cleanObj
(
String
val
)
{
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
val
);
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
jsonObject
.
entrySet
())
{
if
(
entry
.
getValue
()
!=
null
&&
entry
.
getValue
()
instanceof
String
)
{
String
str
=
(
String
)
entry
.
getValue
();
str
=
this
.
cleanXss
(
str
);
entry
.
setValue
(
str
);
}
}
return
jsonObject
.
toJSONString
();
}
/**
* 清除json数组中的xss攻击字符
*
* @param val json数组字符串
* @return 清除后的json数组字符串
*/
private
String
cleanArr
(
String
val
)
{
List
<
String
>
list
=
JSONObject
.
parseArray
(
val
,
String
.
class
);
List
<
String
>
result
=
new
ArrayList
<>(
list
.
size
());
for
(
String
str
:
list
)
{
str
=
this
.
cleanXss
(
str
);
result
.
add
(
str
);
}
return
JSONObject
.
toJSONString
(
result
);
}
/**
* 清除xss攻击字符串,此处优化空间较大
*
* @param str 字符串
* @return 清除后无害的字符串
*/
public
String
cleanXss
(
String
str
)
{
if
(
JsonUtil
.
INSTANCE
.
isJsonObj
(
str
))
{
str
=
this
.
cleanObj
(
str
);
}
else
if
(
JsonUtil
.
INSTANCE
.
isJsonArr
(
str
))
{
str
=
this
.
cleanArr
(
str
);
}
else
{
boolean
richText
=
this
.
richText
(
str
);
if
(!
richText
)
{
str
=
str
.
trim
();
str
=
str
.
replaceAll
(
" +"
,
" "
);
}
String
afterClean
=
Jsoup
.
clean
(
str
,
""
,
CUSTOM_WHITELIST
,
OUTPUT_SETTINGS
);
if
(
paramError
(
richText
,
afterClean
,
str
))
{
// throw new BizRunTimeException(ApiCode.PARAM_ERROR, "参数包含特殊字符");
throw
new
RuntimeException
(
"参数包含特殊字符"
);
}
str
=
richText
?
afterClean
:
this
.
backSpecialStr
(
afterClean
);
}
return
str
;
}
/**
* 判断是否是富文本
*
* @param str 待判断字符串
* @return true/false
*/
private
boolean
richText
(
String
str
)
{
return
str
.
contains
(
RICH_TEXT
);
}
/**
* 判断是否参数错误
*
* @param richText 是否富文本
* @param afterClean 清理后字符
* @param str 原字符串
* @return true/false
*/
private
boolean
paramError
(
boolean
richText
,
String
afterClean
,
String
str
)
{
// 如果包含富文本字符,那么不是参数错误
if
(
richText
)
{
return
false
;
}
// 如果清理后的字符和清理前的字符匹配,那么不是参数错误
if
(
Objects
.
equals
(
str
,
afterClean
))
{
return
false
;
}
// 如果仅仅包含可以通过的特殊字符,那么不是参数错误
if
(
Objects
.
equals
(
str
,
this
.
backSpecialStr
(
afterClean
)))
{
return
false
;
}
// 如果还有......
return
true
;
}
/**
* 转义回特殊字符
*
* @param str 已经通过转义字符
* @return 转义后特殊字符
*/
private
String
backSpecialStr
(
String
str
)
{
return
str
.
replaceAll
(
"&"
,
"&"
);
}
}
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment