1
0

More than 1 year has passed since last update.

Spring bootでTomcatのリクエスト情報をログへ出力する

Last updated at Posted at 2023-01-08

背景

Spring bootで開発したAPIに対して脆弱性テストを実施した際に、tomcatのエラーページが表示されるケースがあった。
調べた限りでは、Controllerまで到達せずにtomcatのエラーページがHTMLでレスポンスされるようになっており、設定による変更が不可能。エラーページを出力する処理をオーバライドしてカスタマイズすることで回避する方法が提案されていた。
参考のGithub issue

エラーページが表示される例

  • URIに使用できない文字が含まれている
    http://localhost:8080/api/get/%aaa
  • ヘッダに使用できない文字が含まれている
    (request): test

実施したいこと

エラーページのカスタマイズは本投稿下部の参考情報をもとに実現できたが、このようなリクエストがあっても必ずしも例外が発生するわけではないようで、エラー時の情報が取得できない。

  • リクエストヘッダに異常がある場合はIllegalArgumentExceptionが発生する。
  • URIの異常は例外が発生せず、ログに何も出力せずにHTMLをレスポンスしてしまう。

リクエストの情報をログへ出力する方法を調べたところ、オーバライドするErrorReportValve.report()の引数のRequestクラスに含まれる情報が使用できることがわかった。

Requestクラス
MimeHeadersクラス

リクエストヘッダ

@Override
protected void report(final Request request, final Response response, final Throwable throwable){
  :
  MimeHeaders headers = request.getCoyoteRequest().getMimeHeaders();
    for(int i = 0; i < headers.size(); i++){
      LOGGER.error(String.format("Request header  %s : %s", headers.getName(i), headers.getValue(i)));
    }

ただしエラーとなったヘッダについては含まれておらず、受け取ることができたもののみが設定されていると思われる。
例外のトレースにはヘッダ情報が含まれているので、別途出力すれば情報は残すことができる。

  if(throwable != null){
    LOGGER.error("Request exception", throwable);
  }

リクエストURIとクエリストリング

  LOGGER.error(String.format("Request URI    : %s", request.getCoyoteRequest().requestURI()));
  LOGGER.error(String.format("Request querys : %s", request.getCoyoteRequest().queryString()));

出力

リクエスト
[22:11:28 ec2-user ~] curl -H '(request): test'  'http://localhost:8080/api/get/aaaa?a=111&b
=abc' -v
> GET /api/get/aaaa?a=111&b=abc HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
> (request): test
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 
< Content-Type: text/html;charset=utf-8
< Content-Length: 85
< Date: Sun, 08 Jan 2023 13:11:39 GMT
< Connection: close
< 
* Closing connection 0
<!doctype html><html lang="ja"><body>Error</body></html>
Spring bootログ
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request exception
java.lang.IllegalArgumentException: The HTTP header line [(request): test] does not conform to RFC 7230 and has been ignored.
        at org.apache.coyote.http11.Http11InputBuffer.skipLine(Http11InputBuffer.java:1093) ~[tomcat-embed-core-10.1.4.jar:10.1.4]
 :
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request header : host : localhost:8080
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request header : user-agent : curl/7.79.1
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request header : accept : */*
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request URI    : /api/get/aaaa
2023-01-08T22:11:39.710+09:00 ERROR 10950 --- [nio-8080-exec-3] c.e.c.c.CustomErrorReportValve           : Request querys : a=111&b=abc

参考にした情報

エラーページのカスタマイズ方法
https://yukihane.github.io/blog/202105/21/spring-boot-avoid-tomcat-error-page/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0