当前位置:网站首页>Antisamy: a solution against XSS attack tutorial

Antisamy: a solution against XSS attack tutorial

2022-07-07 18:49:00 Huazai coding

1. XSS Introduce

XSS It's a cross site scripting attack (Cross Site Scripting) For short , For discord CSS(Cascading Style Sheets) confusion , Therefore, the cross-site scripting attack is abbreviated as XSS. XSS A malicious attacker goes to Web Malicious insert in the page Script Code , When the user browses the page , Embedded in Web Inside Script Code will be executed , So as to achieve the purpose of malicious attacks on users . It's kind of like SQL Inject . When a website attacker finds this vulnerability , And after the attack succeeds , An attacker may be given, but not limited to, higher privileges ( If you do something )、 Private web content 、 Conversation and cookie And so on .

XSS There are two types of attacks

  • A persistent :XSS The attack code is stored in the database of the server , Very secretive . for example , When the attacker injects XSS Attack code , Posts or blogs are stored on the server , Comments or message boards of posts are naturally persisted to the database of the server , This includes XSS Attack code . When other users browse this post ,XSS The attack code begins to parse and execute in the user's browser .
  • reflective : reflective XSS Also known as non persistent XSS, This kind of attack has the characteristic of one-off . for example , The attacker will contain XSS The malicious link of the code is sent to the user , When users access links , The server receives the user request and processes it , Then include XSS The data of the code is returned to the user's browser , Then the user browser resolution contains XSS Code data , It will trigger XSS Loophole .
  • DOM type : Different from the above two types ,DOM type XSS The attack does not go through the server , It is directly constructed by the attacker to contain XSS Attack code URL, Then let the target user access this URL, When the user's browser processes this response ,DOM Type object will handle XSS Code , Trigger XSS Loophole .

2. AntiSamy Introduce

Therefore, in order to avoid the harm that this vulnerability brings to the users of the website ,OWASP The organization open source a project called AntiSamy Project , Help our website defend XSS attack . It is through the input of the user HTML / CSS / JavaScript And so on , Make sure the input meets the application specification .AntiSamy Widely used in Web Services are for storage and reflection XSS In the defense of .

Official information about AntiSamy It's like this :

AntiSamy It's a API or library , It can help our developers to ensure that the client will not be in what they provide HTML Provide malicious code in , these HTML Used to save the configuration file on the server 、 Notes, etc. . About web Application terminology “ Malicious code ” Usually refers to “JavaScript”. Most of the time ,CSS Only when calling JavaScript Is considered malicious . However , in many instances ,“ natural ” HTML and CSS Can be used maliciously .

3. AntiSamy Use

3.1 Import dependence

AntiSamy Of maven coordinate :

<dependency>
  <groupId>org.owasp.antisamy</groupId>
  <artifactId>antisamy</artifactId>
  <version>1.6.2</version>
</dependency>

3.2 Select a policy file

AntiSamy Some policy files are predefined , These policy files represent the allowed users to provide HTML ( There may be CSS) Typical application scenarios for formatting information , We can choose the appropriate policy file according to our own application scenario . The specific policy documents are as follows :

1、antisamy-slashdot.xml

  • Slashdot Is a technology news website , It allows users to reply anonymously to very limited HTML Tagged news posts . Now? ,Slashdot Not only is it one of the coolest websites , It is also a website that has been successfully attacked by many different .
  • Slashdot The rules are quite strict : Users can only submit the following <b>, <u>, <i>, <a>, <blockquote> these HTML Mark , Cannot submit CSS.
  • therefore ,antisamy-slashdot.xml Files support similar functions , All directly to the font 、 Color or text formatting tags that focus on operations are allowed , But... Is not allowed CSS and JavaScript The mark appears .

2、antisamy-ebay.xml

  • eBay It is the most popular online auction website in the world , It is a public site , So anyone can publish rich HTML List of contents . in consideration of eBay As an attractive target , It suffers from some complex XSS The attack is not surprising . Lists are allowed to contain more than Slashdot Richer content —— So its attack surface is quite large .
  • therefore ,antisamy-ebay.xml The policies provided by the policy file are rich in support HTML Mark , But not supported CSS Mark and JavaScript Mark .

3、antisamy-myspace.xml

  • MySpace It was once a very popular social networking site , Users can submit almost everything they want HTML and CSS —— As long as it does not contain JavaScript. MySpace Use a word blacklist to verify the user's HTML, This is why they are notorious Samy Worm attacks .Samy Worms use fragment attacks and a word that should be blacklisted (eval)—— It is the inspiration of this project .
  • therefore ,antisamy-myspace.xml The policies provided by the policy file support very rich HTML and CSS Mark , But not supported JavaScript Mark .

4、antisamy-anythinggoes.xml

  • If you want to allow every valid HTML and CSS Elements ( however Don't allow JavaScript Or obvious CSS Related fishing attacks ), You can use this policy file . It contains the basic rules of each element , So when using other customized policy files , It can be used as a knowledge base .

5、antisamy-tinymce.xml

  • Only text formats are allowed through , Relatively safe .

6、antisamy.xml

  • The default rules , Allow most HTML Mark , Don't allow JavaScript The mark appears .

3.3 SpringBoot Integrate AntiSamy Use

The project directory structure is as follows :

 Insert picture description here

First step , establish maven engineering antiSamy_demo And configuration pom.xml file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hzz</groupId>
    <artifactId>antiSamy_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.owasp.antisamy</groupId>
            <artifactId>antisamy</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

The second step , establish application.yml file

server:
  port: 9000

The third step , Create a policy file /resources/antisamy-slashdot.xml, Policy files can be directly from antisamy jar Copy under package

 Insert picture description here

Step four , Create entity class User

package com.hzz.entity;

import lombok.Data;

@Data
public class User {
    
    private int id;
    private String name;
    private int age;
}

Step five , establish UserController

package com.hzz.controller;

import com.hzz.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/save")
    public String save(User user){
    
        System.out.println("UserController save.... " + user);
        return user.getName();
    }
}

Step six , establish /resources/static/index.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" action="/user/save">
    id:<input type="text" name="id"><br>
    name:<input type="text" name="name"><br>
    age:<input type="text" name="age"><br>
    <input type="submit" value="submit">
</form>
</body>
</html>

Step seven , Create filters , Used to filter all request parameters submitted to the server

package com.hzz.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

// Filter all request parameters submitted to the server 
public class XssFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // Pass in the rewritten Request
        filterChain.doFilter(new XssRequestWrapper(request), servletResponse);
    }
}

filter XssFilter There is no direct filtering and cleaning of request parameters , It's a direct release . Actually , The work of filtering and cleaning is in another class XssRequestWrapper In the , When the above filter is released, you need to call filterChain.doFilter() Method , This method requires an incoming request request object , At this point, we can put the current request Objects are packaged , and XssRequestWrapper Namely request Object wrapper class , When the filter is released, the wrapper class will be called automatically getParameterValues Method , We can do it in the packaging class getParameterValues Method to filter and clean up the request parameters .

XssRequestWrapper The wrapper class is implemented as follows

package com.hzz.filter;

import org.owasp.validator.html.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.UnsupportedEncodingException;

public class XssRequestWrapper extends HttpServletRequestWrapper {
    
    /** *  Policy file : You need to put the policy file to be used in the project resource file path  */
    private static String antiSamyPath = XssRequestWrapper.class.getClassLoader()
            .getResource( "antisamy-ebay.xml").getFile();

    public static Policy policy = null;

    static {
    
        // Specify the policy file 
        try {
    
            policy = Policy.getInstance(java.net.URLDecoder.decode(antiSamyPath, "utf-8")); // My project path has Chinese , Transcoding required , Otherwise, an error will be reported , If your paths are all in English, ignore the transcoding process 
        } catch (PolicyException | UnsupportedEncodingException e) {
    
            e.printStackTrace();
        }
    }

    /** * Antisamy  Filtering data  * @param taintedHTML  Data to be filtered  * @Return  Return filtered data  */
    private String xssClean(String taintedHTML) {
    
        try {
    
            // Use AntiSamy  To filter 
            AntiSamy antiSamy = new AntiSamy();
            CleanResults cr = antiSamy.scan(taintedHTML, policy);
            taintedHTML = cr.getCleanHTML();
        } catch (ScanException e) {
    
            e.printStackTrace();
        } catch (PolicyException e) {
    
            e.printStackTrace();
        }
        return taintedHTML;
    }


    public XssRequestWrapper(HttpServletRequest request) {
    
        super(request);
    }

    @Override
    public String[] getParameterValues(String name) {
    
        String[] values = super.getParameterValues(name);
        if (values == null) {
    
            return null;
        }
        int len = values.length;
        String[] newArray = new String[len];
        for (int j = 0; j < len; j++) {
    
            System.out.println("Antisamy  Filter cleaning , Clean up the previous parameter values :"+values[j]);
            // Filter cleaning 
            newArray[j] = xssClean(values[j]);
            System.out.println("Antisamy  Filter cleaning , Parameter values after cleaning :"+newArray[j]);
        }
        return newArray;
    }
}

Step eight , To make the filter defined above effective , You need to create a configuration class , Used to initialize the filter object

package com.hzz.config;

import com.hzz.filter.XssFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// Configure cross site attack filters 
@Configuration
public class AntiSamyConfiguration {
    
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
    
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
}

Step nine , Create a startup class and start the project , Visit the homepage address of the website http://localhost:9000/index.html

package com.hzz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AntiSamyApp {
    
    public static void main(String[] args) {
    
        SpringApplication.run(AntiSamyApp.class, args);
    }
}

Step 10 , Input test data , And observe the background printing results

 Insert picture description here
 Insert picture description here
You can see from the above picture that , The test of XSS The attack code was directly cleaned up , There is no XSS Code , Will not be executed by the browser , Successfully avoided XSS attack .

Upgrade :

Before , When we filter the request parameters, we just wrap the class getParameterValues Methods are dealt with , In a real project, the data submitted by the user may be in the request header , It is also possible that the user submitted json data , So if you consider all the cases , We can clean up multiple methods in the wrapper class , stay XssRequestWrapper The following methods are added to the implementation class :

@Override
public String getParameter(String paramString) {
    
    String str = super.getParameter(paramString);
    if (str == null) {
    
        return null;
    }
    System.out.println("Antisamy  Filter cleaning , Clean up the previous parameter values :"+str);
    // Filter cleaning 
    str = xssClean(str);
    System.out.println("Antisamy  Filter cleaning , Parameter values after cleaning :"+str);
    return str;
}


@Override
public String getHeader(String paramString) {
    
    String str = super.getHeader(paramString);
    if (str == null) {
    
        return null;
    }
    System.out.println("Antisamy  Filter cleaning , Clean up the previous parameter values :"+str);
    // Filter cleaning 
    str = xssClean(str);
    System.out.println("Antisamy  Filter cleaning , Parameter values after cleaning :"+str);
    return str;
}

@Override
public Map<String, String[]> getParameterMap() {
    
    Map<String, String[]> requestMap = super.getParameterMap();
    for (Map.Entry<String, String[]> me : requestMap.entrySet()) {
    
        String[] values = me.getValue();
        for (int i = 0; i < values.length; i++) {
    
            System.out.println("Antisamy  Filter cleaning , Clean up the previous parameter values :"+values[i]);
            // Filter cleaning 
            values[i] = xssClean(values[i]);
            System.out.println("Antisamy  Filter cleaning , Parameter values after cleaning :"+values[i]);
        }
    }
    return requestMap;
}
原网站

版权声明
本文为[Huazai coding]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071619353893.html