
이 LAB은 유저의 입력을 canonical link tag에 반영하고 꺽쇠기호(<,>)를 이스케이프 처리합니다.
이 LAB을 해결하기 위해서는 XSS를 이용해 웹 사이트에 속성 값을 삽입해 alert() 함수를 호출해야 한다.
공격을 돕기 위한 팁.
당신은 가상의 유저가 아래의 key 조합을 누를 것이라고 추정할 수 있다.
- ALT+SHIFT+X
- CTRL+ALT+X
- ALT+X
해당 LAB에서 의도한 해결법은 오로지 Chrome에서만 가능합니다.
💡 canonical link tag란?
Canonical Tag는 2개 이상의 중복된 웹 페이지가 존재할 때, 이 중 원본 페이지를 지정하는 태그입니다.
http://web.com/board
http://web.com/baord?type=free위 처럼 동일한 웹 페이지지만 제공받는 파라미터 값이 달라 URL이 차이가 있는 경우 검색 엔진은 이를 서로 다른 웹 페이지로 판단합니다. 이 경우 검색 엔진은 이 둘중 어느 것이 원본 페이지인지 알 수 없기 때문에 마음대로 원본 페이지를 지정하게 됩니다. 이는 검색 노출도를 낮추는 원인이 됩니다.
<link rel="canonical" href="http://web.com/board">때문에 위 처럼 canonical link tag를 사용해 원본 페이지를 지정합니다.

이전과 다르게 블로그 검색창이 존재하지 않습니다.
사용자의 입력값을 canonical의 값으로 입력한다고 했으니 URL에 아무런 값이나 덫붙여서 전송해보겠습니다.
https://0ac000cf0301665f822c06a700b60050.web-security-academy.net/?test

소스 코드에서 canonical tag를 확인해보면 방금 입력한 값이 그대로 들어가있는 것을 확인할 수 있습니다.
지금까지 해온 것들을 생각하면 이 점을 이용해 속성값을 추가할 수 있겠다는 생각이 듭니다.
여기서 href의 값이 더블쿼터(")로 덮여있기 때문에 더블쿼터로 닫고 속성을 입력하면 쉽게 추가할 수 있을 것이라 생각할 수 있습니다.
https://0ac000cf0301665f822c06a700b60050.web-security-academy.net/?"test

그런데 예상과 다르게 더블쿼터(")가 인코딩이 돼버려 입력 값이 문자열로 해석되는 것을 볼 수 있습니다.
그럼 더블쿼터(")를 싱글쿼터(')로 변경해서 입력해보겠습니다.
https://0ac000cf0301665f822c06a700b60050.web-security-academy.net/?'test

이제는 속성으로 인식하게 됩니다.
HTML은 속성의 값을 지정할 때 더블쿼터(")와 싱글쿼터(')를 둘 다 사용합니다. 그런데 지금 웹 사이트에서는 더블쿼터(")만 이스케이핑 처리를 했기 때문에 싱글쿼터(')는 그대로 입력되어 구분자로서 인식이 되고 그로인해 싱글쿼터(') 이후의 값이 새로운 속성으로 인식되는 상황입니다.
그럼 이제 이 점을 이용해 속성 값을 추가해서 공격을 수행해보도록 하겠습니다.
우선 기본적으로 onclick="alert(1)"과 같이 JS 코드를 실행할 수 있는 속성을 추가하는데, 문제는 <head>의 <link> 태그이기 때문에 클릭을 하거나, 마우스를 갖다대거나 할 수가 없다는 점입니다.
이를 위해 accesskey 속성을 추가합니다. 해당 속성은 특정 값을 단축키로서 사용할 수 있도록 해주는 속성인데, accesskey로 등록된 단축키를 입력하면 마우스로 클릭한 것과 같은 판정이 돼서 onclick 이벤트가 실행되게 됩니다.
문제에서 사용자가 ALT + X, CTRL+ALT+X, ALT+SHIFT+X를 입력할 수 있다고 했기 때문에 X 값을 단축키로 등록하면 위 단축키를 입력했을 때 경고창이 출력되게 됩니다.
https://0ac000cf0301665f822c06a700b60050.web-security-academy.net/?'accesskey='x'onclick='alert(1)'

URL을 입력하면 바로 성공 구문이 나타나고, ALT+X를 누르면 경고창이 나타납니다.

끝
이번 LAB은 인코딩의 허점을 찾아 새로운 속성을 추가해 JS코드를 실행하는 법을 배웠습니다. 이를 막기 위해서는 더블쿼터(")뿐만 아니라 싱글쿼터(')까지 인코딩을 확실하게 수행해야 합니다.