CVE-2023-7171 (Java, published 2023-12-29T18:15Z)
Description: value: A vulnerability was found in Novel-Plus up to 4.2.0. It has been declared as problematic. Affected by this vulnerability is an unknown functionality of the file novel-admin/src/main/java/com/java2nb/novel/controller/FriendLinkController.java of the component Friendly Link Handler. The manipulation leads to cross site scripting. The attack can be launched remotely. The exploit has been disclosed to the public and may be used. The patch is named d6093d8182362422370d7eaf6c53afde9ee45215. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-249307.
Severity: nan (CVSS v3 base score: 4.8)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/201206030/novel-plus
Files changed:
novel-admin/src/main/java/com/java2nb/novel/controller/FriendLinkController.java
novel-admin/src/main/java/com/java2nb/novel/domain/FriendLinkDO.java
novel-admin/src/main/resources/templates/novel/friendLink/add.html
novel-admin/src/main/resources/templates/novel/friendLink/edit.html
Commit message: fix(novel-admin): 友情链接URL格式校验


Vulnerable code:
    public R save(FriendLinkDO friendLink) {
    public R update(FriendLinkDO friendLink) {
import java.io.Serializable;


import java.math.BigDecimal;



import java.util.Date;
 * 
 * 
	private static final long serialVersionUID = 1L;

	
	//主键
			private Integer id;
	//链接名
			private String linkName;
	//链接url
			private String linkUrl;
	//排序号
			private Integer sort;
	//是否开启，0：不开启，1：开启
			private Integer isOpen;
	//创建人id
		//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
	//所以通过序列化成字符串来解决
	@JsonSerialize(using = LongToStringSerializer.class)
			private Long createUserId;
	//创建时间
			@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
		private Date createTime;
	//更新者用户id
		//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
	//所以通过序列化成字符串来解决
	@JsonSerialize(using = LongToStringSerializer.class)
			private Long updateUserId;
	//更新时间
			@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
		private Date updateTime;

	/**
	 * 设置：主键
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	/**
	 * 获取：主键
	 */
	public Integer getId() {
		return id;
	}
	/**
	 * 设置：链接名
	 */
	public void setLinkName(String linkName) {
		this.linkName = linkName;
	}
	/**
	 * 获取：链接名
	 */
	public String getLinkName() {
		return linkName;
	}
	/**
	 * 设置：链接url
	 */
	public void setLinkUrl(String linkUrl) {
		this.linkUrl = linkUrl;
	}
	/**
	 * 获取：链接url
	 */
	public String getLinkUrl() {
		return linkUrl;
	}
	/**
	 * 设置：排序号
	 */
	public void setSort(Integer sort) {
		this.sort = sort;
	}
	/**
	 * 获取：排序号
	 */
	public Integer getSort() {
		return sort;
	}
	/**
	 * 设置：是否开启，0：不开启，1：开启
	 */
	public void setIsOpen(Integer isOpen) {
		this.isOpen = isOpen;
	}
	/**
	 * 获取：是否开启，0：不开启，1：开启
	 */
	public Integer getIsOpen() {
		return isOpen;
	}
	/**
	 * 设置：创建人id
	 */
	public void setCreateUserId(Long createUserId) {
		this.createUserId = createUserId;
	}
	/**
	 * 获取：创建人id
	 */
	public Long getCreateUserId() {
		return createUserId;
	}
	/**
	 * 设置：创建时间
	 */
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	/**
	 * 获取：创建时间
	 */
	public Date getCreateTime() {
		return createTime;
	}
	/**
	 * 设置：更新者用户id
	 */
	public void setUpdateUserId(Long updateUserId) {
		this.updateUserId = updateUserId;
	}
	/**
	 * 获取：更新者用户id
	 */
	public Long getUpdateUserId() {
		return updateUserId;
	}
	/**
	 * 设置：更新时间
	 */
	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}
	/**
	 * 获取：更新时间
	 */
	public Date getUpdateTime() {
		return updateTime;
	}
                                       type="text" required>
                                       type="text" required>

Fixed code:
import org.springframework.validation.annotation.Validated;
    public R save(@Validated FriendLinkDO friendLink) {
    public R update(@Validated FriendLinkDO friendLink) {
import org.hibernate.validator.constraints.URL;
import java.io.Serializable;
import java.util.Date;

    private static final long serialVersionUID = 1L;


    //主键
    private Integer id;
    //链接名
    private String linkName;
    //链接url
    @URL
    private String linkUrl;
    //排序号
    private Integer sort;
    //是否开启，0：不开启，1：开启
    private Integer isOpen;
    //创建人id
    //java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
    //所以通过序列化成字符串来解决
    @JsonSerialize(using = LongToStringSerializer.class)
    private Long createUserId;
    //创建时间
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    //更新者用户id
    //java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
    //所以通过序列化成字符串来解决
    @JsonSerialize(using = LongToStringSerializer.class)
    private Long updateUserId;
    //更新时间
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    /**
     * 设置：主键
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取：主键
     */
    public Integer getId() {
        return id;
    }

    /**
     * 设置：链接名
     */
    public void setLinkName(String linkName) {
        this.linkName = linkName;
    }

    /**
     * 获取：链接名
     */
    public String getLinkName() {
        return linkName;
    }

    /**
     * 设置：链接url
     */
    public void setLinkUrl(String linkUrl) {
        this.linkUrl = linkUrl;
    }

    /**
     * 获取：链接url
     */
    public String getLinkUrl() {
        return linkUrl;
    }

    /**
     * 设置：排序号
     */
    public void setSort(Integer sort) {
        this.sort = sort;
    }

    /**
     * 获取：排序号
     */
    public Integer getSort() {
        return sort;
    }

    /**
     * 设置：是否开启，0：不开启，1：开启
     */
    public void setIsOpen(Integer isOpen) {
        this.isOpen = isOpen;
    }

    /**
     * 获取：是否开启，0：不开启，1：开启
     */
    public Integer getIsOpen() {
        return isOpen;
    }

    /**
     * 设置：创建人id
     */
    public void setCreateUserId(Long createUserId) {
        this.createUserId = createUserId;
    }

    /**
     * 获取：创建人id
     */
    public Long getCreateUserId() {
        return createUserId;
    }

    /**
     * 设置：创建时间
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * 获取：创建时间
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * 设置：更新者用户id
     */
    public void setUpdateUserId(Long updateUserId) {
        this.updateUserId = updateUserId;
    }

    /**
     * 获取：更新者用户id
     */
    public Long getUpdateUserId() {
        return updateUserId;
    }

    /**
     * 设置：更新时间
     */
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    /**
     * 获取：更新时间
     */
    public Date getUpdateTime() {
        return updateTime;
    }
                                       type="url" required>
                                       type="url" required>