Skip to content

Instantly share code, notes, and snippets.

@circlee
Created February 28, 2020 04:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save circlee/126a2bd68003b1eea4c19ab7804614a5 to your computer and use it in GitHub Desktop.
Save circlee/126a2bd68003b1eea4c19ab7804614a5 to your computer and use it in GitHub Desktop.
luxy xssEscapeStringDeserializer
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreXssEscape {
}
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.springframework.data.annotation.Transient;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter;
public class XssEscapeStringDeserializer extends StringDeserializer implements ContextualDeserializer {
private static final long serialVersionUID = -5674806753698655941L;
// lucy xss escape filter
private final transient XssEscapeFilter xssEscapeFilter = XssEscapeFilter.getInstance();
private StringDeserializer stringSerializer = new StringDeserializer();
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
boolean propertyXssEscapeIngored = Optional.ofNullable(property.getAnnotation(IgnoreXssEscape.class)).isPresent();
// 해당 프로퍼티에 IgnoreXssEscape annotation이 정의 되어있다면 xssEscape 대상이 아니다.
if(propertyXssEscapeIngored) {
return stringSerializer;
}
boolean contextXssEscapeIngored = Optional.ofNullable(property.getContextAnnotation(IgnoreXssEscape.class)).isPresent();
// 해당 프로퍼티에 IgnoreXssEscape annotation이 정의 되어있다면 xssEscape 대상이 아니다.
if(contextXssEscapeIngored) {
return stringSerializer;
}
return this;
}
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = super.deserialize(p, ctxt);
return xssEscapeFilter.doFilter(getRequestPath(), p.currentName(), value);
}
private String getRequestPath() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes instanceof ServletRequestAttributes) {
HttpServletRequest req = ((ServletRequestAttributes)requestAttributes).getRequest();
return req.getRequestURI();
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment