天天看點

CuteKe網站開發與安全2——記錄URL與URL不符合1. 記錄URL2. URL不符合2.1 是否使用代理?2.2 HOST實踐參考資料

    我的CuteKe網站也上線一段時間了,之前也是做了通路日志,發現日志還是不利于觀察,還是把它通路記錄資料庫化了。但是這幾天卻發現在記錄URL的時候發現了一個問題。

1. 記錄URL

    我們先來看看如何記錄URL與IP位址:

1.1 通路記錄Model

    因為我們要把通路記錄資料化,是以我們要建立通路記錄實體類:

VistorLog

,代碼如下:

@Entity
public class VisitorLog {
    private static final long serialVersionUID = 1L;

    @Id // 主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增長政策
    private Long id; // 使用者的唯一辨別


    @NotEmpty(message = "通路位址不能為空")
    @Column(nullable = false)
    private String url;

    @NotEmpty(message = "通路方法不能為空")
    @Column(nullable = false)
    private String httpMethod;
    
    @NotEmpty(message = "IP位址不能為空")
    @Column(nullable = false)
    private String ip;


    @NotEmpty(message = "IP位址映射的真實不能為空")
    @Column(nullable = false)
    private String trueAddress;

    @Column(nullable = false) // 映射為字段,值不能為空
    @org.hibernate.annotations.CreationTimestamp  // 由資料庫自動建立時間
    private Timestamp visitTime;
    
    
    @NotEmpty(message = "背景通路方法不能為空")
    @Column(nullable = false)
    private String classMethod;

    @NotEmpty(message = "通路方法參數")
    @Column(nullable = false)
    private String getClassMethodArgs;

    protected  VisitorLog(){
        
    }

    public VisitorLog(String url, String httpMethod, String ip, String trueAddress,String classMethod, String getClassMethodArgs) {
        this.url = url;
        this.httpMethod = httpMethod;
        this.ip = ip;
        this.trueAddress= trueAddress;
        this.classMethod = classMethod;
        this.getClassMethodArgs = getClassMethodArgs;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getHttpMethod() {
        return httpMethod;
    }

    public void setHttpMethod(String httpMethod) {
        this.httpMethod = httpMethod;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getClassMethod() {
        return classMethod;
    }

    public void setClassMethod(String classMethod) {
        this.classMethod = classMethod;
    }

    public String getGetClassMethodArgs() {
        return getClassMethodArgs;
    }

    public void setGetClassMethodArgs(String getClassMethodArgs) {
        this.getClassMethodArgs = getClassMethodArgs;
    }
}

           

1.2 利用Spring AOP

    在gradle裡添加

spring-boot-starter-aop

依賴以後,我們可以這樣設計:

  1. 切入點:每個

    Controller

    的每個方法即各個請求方法
@Pointcut("execution(public * com.cuteke.spring.boot.blog.controlller.*.*(..))")
    public void log() {
    };
           
  1. 通知:在這裡我選擇的是

    前置通知

    ,你也可以選擇其他通知
@Before("log()")
    public void doBefore(JoinPoint joinPoint) {
    ....
    }
           
  1. 擷取HttpServletRequest:我們通過Request上下文來擷取

    HttpServertRequest

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
           
  1. 擷取各個屬性:擷取到

    HttpServertRequest

    就可以通過調用其方法就可以擷取到

    VisitLog

    的各個屬性了:
String url=new String(request.getRequestURL());
String method=request.getMethod();
String ip=IpUtil.getClinetIpByReq(request);
String class_method=joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
String args= Arrays.toString(joinPoint.getArgs());
logger.info("url={} method={} ip={} class_method={} args={}", url, method
                , ip, class_method
                , joinPoint.getArgs());
VisitorLog visitorLog=new VisitorLog(url,method,ip,IpUtil.getAddressByIP(ip),class_method,args);
vistorLogService.saveVistorLog(visitorLog);
           

IpUtil

是處理ip的工具類,核心思想是通過

getRemoteAddr()

方法和過濾掉代理ip來實作的,我們會在其餘章節裡面提到,百度也能很簡單的找到

2. URL不符合

    網站上線了幾個星期,我在資料找到了很奇怪的記錄,如下圖1所示:

CuteKe網站開發與安全2——記錄URL與URL不符合1. 記錄URL2. URL不符合2.1 是否使用代理?2.2 HOST實踐參考資料

圖1. 資料庫中行URL不符合

    其中怪異的url我都用紅線劃出來了,而且發現了沒,這些搞事的url都是國外的,國外還是喜歡搞事情呀!

2.1 是否使用代理?

    代理可以分為兩種:

  1. 正向代理:用戶端要配置代理伺服器,由代理伺服器代替通路你,是以說URL一般并不會改變
  2. 反向代理:用戶端不知道代理的存在,通路URL的網址時,會經過反向代理伺服器,由反向代理伺服器轉向對應的伺服器上通路,一般用于

    負載均衡,URL一般也不會改變

    其實使用代理的情況下是可以出現我這種情況的,因為伺服器的存在,修改URL或者其他操作是使用者不知道的,我們知道URL是用來解析ip位址,像國外這種情況隻要能确定我的伺服器IP位址,不管URL是不是我的網站URL,都可以通路我的網站。

2.2 HOST實踐

    前面講到隻要解析我的伺服器IP位址不管URL是否正确都可以,我們就在本機實踐一下,我們知道在C:\Windows\System32\drivers\etc有一個HOST檔案,我們隻要改變URL對應的IP即可完成解析。代碼如下:

# localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
#	::1             localhost
127.0.0.1 www.cuteke.cn
           

    在這裡我把自己的網站域名解析成本機位址,在本機我也開啟我的網站,不過裡面内容不一樣,在浏覽器輸入

www.cuteke.cn

,發現頁面如下圖所示:

CuteKe網站開發與安全2——記錄URL與URL不符合1. 記錄URL2. URL不符合2.1 是否使用代理?2.2 HOST實踐參考資料

圖1. 本地通路CuteKe網站

    這頁面是本機伺服器展示展示的頁面,因為本機的置頂文章和公網上置頂的文章不一樣。同時我們看一下本地資料庫的通路記錄:

CuteKe網站開發與安全2——記錄URL與URL不符合1. 記錄URL2. URL不符合2.1 是否使用代理?2.2 HOST實踐參考資料

圖2. 本地資料庫通路記錄

    最後兩行我們可以發現URL并不是

localhost

而是

www.cuteke.cn

,也是驗證了我們的思想。

修改HOSTS檔案後如果通路的URL還是解析成原來的位址,那麼記得清楚一下系統DNS和浏覽器DNS緩存
修改HOSTS檔案隻是其中一種可能,還有一種極大的可能是Http Host頭攻擊,我們在下一章會講述其原理和具體防禦措施

參考資料

[1] Spring Boot進階之Web進階

[2] 正向代理與反向代理【總結】