개발

라라벨 보안 측면에서의 nl2br 함수에 대한 고찰

라라벨 보안 측면에서의 nl2br 함수에 대한 고찰
목차
라라벨을 이용해서 웹 서비스를 하다보면 사용자의 textarea 입력을 보여주는 용도로써 우리는 nl2br() 함수를 자주 사용한다.

nl2br 함수란 함수명에서도 유추할수 있듯이 nl(줄바꿈, New Line, Line Feed) 값을 <br> 태그로 바꿔주는 역할을 수행한다.
이를 좀더 풀어서 설명해보자면 아래 처럼 표현할 수 있다.

> nl2br("One\nTwo\nThree");
= """
  One<br />\n
  Two<br />\n
  Three
  """

# 최종적으로 화면에 보이는 형태
One
Two
ThreeCopy

주어진 문자열에서 줄바꿈 구문을 찾아 <br>태그로 바꿔주는 역할을 수행한다.
이를 이용해 정규식이나 별도의 처리없이 쉽게 뷰단에서 줄바꿈을 제공해줄 수 있다.

다만 이렇게 생성된 데이터는 <br> 태그가 들어있으므로 라라벨 블레이드의 경우 아래와 같이 {!! !!} 괄호로 묶어서 출력해줘야 <br>이 진짜 줄바꿈 태그 처럼 적용이된다.

라라벨 보안 측면에서의 nl2br 함수에 대한 고찰위가 {{ }} 출력, 아래가 {!! !!} 출력


1. 문제: XSS 취약점

그래서 보통 자연스럽게 textarea로 받은 정보는 그대로 DB에 저장해두고 나중에 출력단에서 아래처럼 사용하는 경우가 많다.

{!! nl2br($text) !!}Copy

근데 만약에 사용자가 textarea에 아래와 같은 데이터를 입력한다면 어떨까?

One
Two
<img src=x onerror="alert('히히!')">
ThreeCopy

우리가 흔히아는 크로사이트 공격, XSS의 공격이 이런느낌이다.
보내는 정보에 HTML 태그형식의 코드를 보내고, 그 태그가 랜더링되어 작동되는 타이밍에 사용자가 원하는 행동을 할 수 있게 만들어 버리는 코드다.

이 코드를 그냥 평소에 하던것처럼 {{ }}로 감싸서 반환하면 아무일도 일어나지않는다.
말그대로 이런 경우를 처리하기위한 이스케이프니까 말이다.

근데 만약에 위 데이터를 줄바꿈과 곁들이기위해서 nl2br 처리후 {!! !!} 로 감싸면 어떻게 될까?

본문 이미지{{ }} 처리는 전혀 문제가 발생하지않지만 {!! !!} 처리는 문제가 발생한다

바로 위의 처리처럼 이미지 태그가 랜더링되게되고 그 내부의 onerror 스크립트에의해 alert이 작동되고 만다.
이게 테스트상에선 단순히 alert이지 여기에 악성 스크립트를 심으면 말그대로 그게 XSS 공격이라 할 수 있다.



2. 해결방법

자 여기까지 문제를 바탕으로 그럼 우리는 textarea로 받은 줄바꿈을 이쁘게 보여주고싶은데 nl2br을 쓰면 안된다는 사실을 알게되었다.

그럼 어떤 해결방법이 있을까?

2-1. e( ) escape

사실상 가장 간단한 방법이다.
nl2br 처리전에 내부의 태그를 전부 이스케이프 처리하면 될것이다.

{!! nl2br(e($input)) !!}Copy

본문 이미지

그러면 태그는 전부 예외처리고 br또한 의도대로 작동시킬 수 있다.


2-2. white-space: pre-line

반대로 백단에서 처리하는게 아니라 스타일에서도 이를 원활하게 처리할 수 있다.

<div style="white-space: pre-line;">{{ $input }}</div>Copy

본문 이미지

이렇게 스타일을 적용하면 위와 같은 결과를 얻을 수 있다.
이 방식의 장점은 출력문의 형식이 {{ }} 다보니 차마 놓치는 부분없이 제대로 이스케이프 처리가 된다는 것이다.

사실 nl2br을 조심히써야한다기보다 {!! !!} 를 조심히 써야하는데, pre-line 방식을 채용한다면 만에 하나의 경우라도 발생하지 않기때문이다.




나는 이런 문제상황을 분석하고 해결방법으로 2번 방식을 이용해 댓글 출력부분을 변경했다!



#Laravel
0 개의 댓글
×