【问题标题】:403 Forbidden SQL-Injection Error for POST with Content-Type = text/xml403 Forbidden SQL-Injection Error for POST with Content-Type = text/xml
【发布时间】:2021-04-22 20:36:14
【问题描述】:

我需要使用 feign 发出 API 请求。方法类型:POST;标头必须包含Content-Type = text/xml

我的代码:

@Component
@ConfigurationProperties("client.machine")
class MachineProperties {
    lateinit var url: String
    lateinit var timeout: String
}

@Configuration
class MachineClientConfig(
    private val connectionProperties: MachineProperties,
    private val meterRegistry: MeterRegistry,
    private val objectMapper: ObjectMapper
) {
    @Bean
    fun machineApi() = Feign.builder()
        .addCapability(MicrometerCapability(meterRegistry))
        .retryer(DefaultEtsmIntegratonRetryer())
        .encoder(JacksonEncoder(objectMapper))
        .decoder(JacksonDecoder(objectMapper))
        .decode404()
        .logger(Slf4jLogger(MachineApi::class.java))
        .options(Request.Options(connectionProperties.timeout.toInt(), connectionProperties.timeout.toInt()))
        .target(MachineApi::class.java, connectionProperties.url)!!
}

@Headers(
    HttpHeaders.ACCEPT + ": " + MediaType.TEXT_XML_VALUE,
    HttpHeaders.CONTENT_TYPE + ": " + MediaType.TEXT_XML_VALUE
)
interface MachineApi {
    @RequestLine("POST /api/v1/charge")
    fun sendRequest(body: String): MachineResponse
}

@Service
class MachineClient(private val machineApi: MachineApi) {
    fun sendRequest(body: String, dealId: Long): MachineResponse {
        return machineApi.sendRequest(body)
    }
}

public class JacksonEncoder implements Encoder {

  private final ObjectMapper mapper;

  public JacksonEncoder() {
    this(Collections.<Module>emptyList());
  }

  public JacksonEncoder(Iterable<Module> modules) {
    this(new ObjectMapper()
        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
        .configure(SerializationFeature.INDENT_OUTPUT, true)
        .registerModules(modules));
  }

  public JacksonEncoder(ObjectMapper mapper) {
    this.mapper = mapper;
  }

  @Override
  public void encode(Object object, Type bodyType, RequestTemplate template) {
    try {
      JavaType javaType = mapper.getTypeFactory().constructType(bodyType);
      template.body(mapper.writerFor(javaType).writeValueAsBytes(object), Util.UTF_8);
    } catch (JsonProcessingException e) {
      throw new EncodeException(e.getMessage(), e);
    }
  }
}

当我从 MachineClient 类调用 sendRequest 方法时,我收到如下错误:

feign.FeignException$Forbidden: [403 Forbidden] during [POST] to [https://dev.ed.com/tsm/v1/charge] [MachineApi#sendRequest(String)]: [{
    "httpCode": "403",
    "moreInformation": "SQL-Injection Error"
}]

但是当我尝试通过 curl 拨打电话时效果很好。

curl --location --request POST 'https://dev.ed.com/tsm/v1/charge' \
--header 'Content-Type: text/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ChargeRq>...</ChargeRq>'

我的代码中缺少什么以及为什么会出现错误?请帮忙,我没有更多的想法

【问题讨论】:

  • body 变量的值是多少?您可以打印和检查。另外,我看到 content-type 丢失了,它出现在 curl 请求中
  • @sidgate body 是由MarshallerJAXBContext (javax.xml.bind) 生成的xml 字符串。生成后,我在控制台中打印这个xml,并在通过curl检查时使用它(我只是从控制台复制并粘贴到Postman中)。
  • @sidgate 我试图发送一个空字符串"",得到了同样的错误。然后我不明白为什么没有发送值:-(

标签: rest kotlin http-status-code-403 feign


【解决方案1】:

解决方法如下:

由于 Content -Type = "text / xml" 是必需的,我需要使用 JAXBEncoder。在这种情况下,我需要发送的不是字符串,而是 ChargeRqType - 使用 jaxb 接收的对象。

@Component
@ConfigurationProperties("client.machine")
class MachineProperties {
    lateinit var url: String
    lateinit var timeout: String
}

@Configuration
class MachineClientConfig(
    private val connectionProperties: MachineProperties,
    private val meterRegistry: MeterRegistry,
    private val jaxbContextFactory: JAXBContextFactory,
    private val objectMapper: ObjectMapper
) {
    @Bean
    fun creditMachineApi() = Feign.builder()
        .addCapability(MicrometerCapability(meterRegistry))
        .retryer(DefaultEtsmIntegratonRetryer())
        .encoder(JAXBEncoder(jaxbContextFactory))
        .decoder(JacksonDecoder(objectMapper))
        .logger(Slf4jLogger(MachineApi::class.java))
        .options(Request.Options(connectionProperties.timeout.toInt(), connectionProperties.timeout.toInt()))
        .target(MachineApi::class.java, connectionProperties.url)!!
}

@Headers(
    HttpHeaders.ACCEPT + ": " + MediaType.TEXT_XML_VALUE,
    HttpHeaders.CONTENT_TYPE + ": " + MediaType.TEXT_XML_VALUE
)
interface MachineApi {
    @RequestLine("POST /tsm/v1/charge")
    fun sendRequest(body: ChargeRqType): MachineResponse
}

@Service
class MachineClient(private val machineApi: MachineApi) {

    fun sendRequest(body: ChargeRqType, dealId: Long) =
        machineApi.sendRequest(body)
}

@Configuration
class JAXBConfig {
    @Bean
    fun jaxbContextFactory() = JAXBContextFactory.Builder()
        .withMarshallerJAXBEncoding("UTF-8")
        .withMarshallerSchemaLocation(ClassPathResource("xsd/SrvCreateApp03.xsd").path)
        .build()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 2020-08-03
    • 2012-10-16
    • 2019-12-21
    • 1970-01-01
    相关资源
    最近更新 更多