I haven’t updated my blog for a long time. It’s more because of self-discipline. I need to keep studying and write some notes for study. Before at the time of learning, always didn’t pay attention to site safety aspects, in the B stand today accidentally saw the XSS related content, today is a good comb XSS related knowledge, can in the later work to avoid XSS the threat posed by the web site, in fact, a web site can safe operation, need further study safety knowledge.
What is XSS?
An explanation from Baidu.com
Through the use of webpage development left loopholes, through the clever method to inject malicious instruction code to the webpage, the user load and execute the malicious web page program made by the attacker. These malicious web programs are usually JavaScript, but can actually include Java, VBScript, ActiveX, Flash, or even plain HTML. After a successful attack, the attacker may gain various contents including but not limited to higher permissions (such as performing some operations), private web content, sessions and cookies.
I think:
XSS refers to malicious users uploading malicious script codes to access users’ private resources
In the project where the front and back end are separated, no matter JWT or other technologies are used, we prefer to keep the Token of the back end in the front end. If there is XSS attack, there will be a threat, such as: After the user logs in successfully, the malicious program will call localstorage. getItem to obtain the user’s token and send the token to the malicious user through Ajax or other means. Malicious users can use this token to access restricted resources and obtain private information.
The above is a simple XSS attack diagram, because the main purpose is to express the meaning simply, some expressions and ideas may not be perfect, I will supplement later
Second, the harm of XSS attack
For example, when users post or register, enter ** in the text box, this code is not escaped, but directly saved to the database. When the view layer renders the HTML in the future, this code will be printed to the page, and the contents of the
<html>// The script will run directly<script>alert('xss')</script>
</html>
Copy the code
Therefore, the most effective way to avoid XSS attack is to escape the data entered by the user and store it in the database. Wait until the view layer renders the HTML page. Escaped text is not executed as JavaScript, which protects against XSS attacks.
1. Upload malicious codes<script>alert("xss")</script>2. The alert(" XSS ") escaped by the server will not be processed as a script, and all labels will be removed as a simple stringCopy the code
3. Address XSS threats
Here we use the HuTool utility class, which provides a solution to the XSS threat
Htmlutil. filter Filters HTML text to prevent XSS attacks. String HTML ="<alert></alert>";
// Result: ""
String filter = HtmlUtil.filter(html);
Copy the code
hutool.cn/
3.1 Importing Dependencies
<! Hutool --> <dependency> <groupId>cn. Hutool </groupId> <artifactId>hutool-all</artifactId> <version>5.4. 0</version>
</dependency>
Copy the code
3.2 Define the request wrapper class
HttpServletRequest is an interface with many methods to implement, which would be a time-consuming operation and impractical to implement.
So, we choose to inherit HttpServletRequestWrapper * * * *
HttpServletRequestWrapper is to use the decorator pattern, also is equivalent to a filter, if you need to obtain parameters or return values only needs to inherit this class to rewrite a method can be achieved, such as: We need to intercept the request, if the value of the request parameter is equal to Yangzinan, we convert it to mic, we just need to inherit and override the method in it:
@Override
public String getParameter(String name) {
// Get parameters
String value = super.getParameter(name);
if(value == "yangzinan"){
value = "mic";
}
// The servlet returns value as mic
return value;
}
Copy the code
Let’s start coding now:
/** * prevent XSS attacks */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/** * constructor that passes request to the parent class *@param request
*/
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
/** * get the argument, escape the argument *@param name
* @return* /
@Override
public String getParameter(String name) {
// Get parameters
String value = super.getParameter(name);
if(! StrUtil.hasBlank(value)){// Escape the argument
value = HtmlUtil.filter(value);
}
return value;
}
/** * Returns array *@param name
* @return* /
@Override
public String[] getParameterValues(String name) {
// Get the collection
String[] values = super.getParameterValues(name);
// Check whether the set is empty, if not, escape
if(values ! =null) {// go through the number group
for(int i = 0; i < values.length; i++){ String value = values[i];if(! StrUtil.hasBlank(value)){/ / escape
value = HtmlUtil.filter(value);
}
// Put the escaped data back into the arrayvalues[i] = value; }}return values;
}
/** * get the data in the request header and escape *@param name
* @return* /
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if(! StrUtil.hasBlank(value)){ value = HtmlUtil.filter(value); }return value;
}
/** * get argument *@return* /
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameterMap = super.getParameterMap();
Since super.getParameterMap() returns a Map, we need to define the Map implementation class to encapsulate the data
Map<String,String[]> params = new LinkedHashMap<>();
// If the parameter is not null
if(parameterMap ! =null) {// Iterate over the map
for(String key:parameterMap.keySet()){
// Get value based on key
String[] values = parameterMap.get(key);
// go through the number group
for(int i = 0; i<values.length; i++){ String value = values[i];if(! StrUtil.hasBlank(value)){/ / escape
value = HtmlUtil.filter(value);
}
// Put the escaped data back into the array
values[i] = value;
}
// Put the escaped array into linkMapparams.put(key,values); }}return params;
}
/** * get input stream *@return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream(a) throws IOException {
// Get the input stream
ServletInputStream in = super.getInputStream();
// Used to store input streams
StringBuffer body = new StringBuffer();
InputStreamReader reader = new InputStreamReader(in, Charset.forName("UTF-8"));
BufferedReader bufferedReader = new BufferedReader(reader);
// Read the input stream line by line
String line = bufferedReader.readLine();
while(line ! =null) {// Append the first row of data to a StringBuffer
body.append(line);
// Continue reading the next stream until line is empty
line = bufferedReader.readLine();
}
/ / close the flow
bufferedReader.close();
reader.close();
in.close();
// Convert body to map
Map<String,Object> map = JSONUtil.parseObj(body.toString());
// Create an empty map to store the results
Map<String,Object> resultMap = new HashMap<>(map.size());
// go through the number group
for(String key:map.keySet()){
Object value = map.get(key);
// If map.get(key) returns a string, escape it. If not, store the resultMap directly
if(map.get(key) instanceof String){
resultMap.put(key,HtmlUtil.filter(value.toString()));
}else{ resultMap.put(key,value); }}// Convert the resultMap to a JSON string
String resultStr = JSONUtil.toJsonStr(resultMap);
// Convert the JSON string to bytes
final ByteArrayInputStream bis = new ByteArrayInputStream(resultStr.getBytes());
// Implement the interface
return new ServletInputStream() {
@Override
public boolean isFinished(a) {
return false;
}
@Override
public boolean isReady(a) {
return false;
}
@Override
public void setReadListener(ReadListener listener) {}@Override
public int read(a) throws IOException {
returnbis.read(); }}; }}Copy the code
3.3 Creating a Filter
We need to create a filter and inject our custom request wrapper class into the filter to make it work
/** * XSS filter */
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssHttpServletRequestWrapper,response);
}
@Override
public void destroy(a) {}}Copy the code
Where ** @webfilter (urlPatterns = “/*”)** means to intercept all requests and escape all parameters
3.4 test
To test, we need to add **@ServletComponentScan** annotations
@ServletComponentScan
@SpringBootApplication
public class GoflyWxApiApplication {
public static void main(String[] args) { SpringApplication.run(GoflyWxApiApplication.class, args); }}Copy the code
Test controller
@Api(" Test interface ")
@RestController
public class TestController {
@PostMapping("/test")
public R testController(@Valid @RequestBody TestForm testForm){
return R.ok().put("message"."hello,"+testForm.getName()); }}Copy the code
That’s all for today. These days, I’m looking at Rabbitmq. Good night 😴