티스토리 뷰

결론

  • maven(gradle)사용시 webjar를 이용하면 js파일을 일일이 추가하지 않아도 된다.

 

개요

  • 프로젝트에서 PDF.js라는 라이브러리를 이용하여 PDF를 출력하고 있었는데 오래된 버전이라 취약점이 보고되었다.
  • 취약점은CVE-2024-4367와 CVE-2024-34342인데 둘 다 자바스크립트가 실행되는 것으로 보인다.
  • 버전업을 하여 취약점을 없애고자 한다.

 

상황

  • 해당 코드는 2024년 12월에 만들어졌는데 Ver.3.5.141을 사용하고 있었다.
  • PDF.js Ver.3.5.141은 2023년 4월에 릴리즈 된 것 같은데 왜지?
  • js파일은 pdf.min.js와 pdf.worker.min.js이 저장되어 있다.
  • 코드에서 사용은 pdf.min.js라는 파일을 html에서 불러오고 있고,
    pdf.worker.min.js라는 파일은 직접 부르지는 않지만 pdf.min.js가 구동되는 데 필요한 파일로 보인다.

 

기존 코드 동작 확인

  • 현장의 코드를 올릴 수 없어서 필수 부분만 복사하여 동작확인을 하였다.
  • 같은 PDF파일을 표시하기 때문에 Viewer 뒤에 js를 추가하여 코드의 구분을 하였다.

 

기존 코드(실제 필요한 부분만)

<head>
    <script type="text/javascript" src="/js/pdf/3.5.141/pdf.min.js">
    </script>
</head>

<body>
<div id="container">
    <div id="header">
        <h1>PDF.js Viewer js</h1>
        <a href="/">Back to Home</a>
    </div>
    <div id="viewer">
        <canvas id="pdf-viewer"></canvas>
    </div>
</div>
<script>
    const pdfUri = `/pdf/dummy.pdf`;
    pdfjsLib.getDocument(pdfUri).promise.then(function (pdf) {
        pdf.getPage(1).then(function (page) {
            const scale = 1;
            const viewport = page.getViewport({scale: scale});

            const canvas = document.getElementById("pdf-viewer");
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            const context = canvas.getContext('2d');
            page.render({
                canvasContext: context, viewport: viewport
            });
        });
    }).catch(function (error) {
        throw new Error('Error loading PDF document: ' + error.message);
    });
</script>
</body>

 

새로운 버전 확인

  • 이제 어떤 버전으로 버전업을 할 지 정하기 위해 버전 정보를 찾아본다.
  • js를 직접 사용하는 방식 중 마지막 버전은 Ver.3.11.174인데 어떤 건지 확인은 안해도 취약점이 있으니 패스한다.

  • 2025년 6월 26일 현재 최신 버전은 Ver.5.3.31이다. 취약점도 지금은 없다.

 

 

새로운 버전을 적용하기(js파일만 변경하기) : 실패

  • 단순히 해당되는 파일(pdf.min.mjs, pdf.worker.min.mjs)의 확장자를 js로 바꿔 넣고 돌려보니 동작하지 않는다.
  • js쪽은 약해서 mjs라는 확장자는 처음 접한다. 모듈을 사용하는 js라 한다.

 

Webjar의 발견

  • 좀 더 찾아보니 js를 직접 넣지 않아도 webjar라는 것으로 대체할 수 있다고 한다.
  • maven에서 pdf.js를 검색해본다.

  • 1번은 2018년이 마지막이니까 2025년 6월이 마지막인 2번으로 들어가본다.

 

 

Webjar를 maven 프로젝트에 반영하기

  • maven에서 복사한 내용을 의존성에 추가해준다.

  • 라이브러리를 가져오고난 다음에 해당 jar를 확인해보면 mjs파일이 있는 것을 볼 수 있다. 하지만 이것을 직접 사용하는 것 같진 않다.

  • 좀 더 정확한 정보를 얻기 위해 pom.xml에 가보면 sourceUrl과 destDir이 보이는데 sourceUrl이 내부가 아닌 github를 향해있다.

  • 그래도 destDir에 대한 정보를 얻었으니 webjars/pdf-js/5.3.31/build/pdf.mjs이라는 경로에서 mjs를 읽을 수 있다는 것을 확인하였다.

  • 그 다음은 PDF.js의 예제파일을 통해 mjs버전 html을 고쳤다.
<body>
<div id="container">
    <div id="header">
        <h1>PDF.js Viewer mjs</h1>
        <a href="/">Back to Home</a>
    </div>
    <div id="viewer">
        <canvas id="pdf-viewer"></canvas>
    </div>
</div>

<script src="webjars/pdf-js/5.3.31/build/pdf.mjs" type="module"></script>
<script type="module">
    // Set the workerSrc to the location of pdf.worker.js
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'webjars/pdf-js/5.3.31/build/pdf.worker.mjs';

    const pdfUri = '/pdf/dummy.pdf'; // Replace with your PDF URL or path

    const loadingTask = pdfjsLib.getDocument(pdfUri);

    const pdf = await loadingTask.promise;

    //
    // Fetch the first page
    //
    const page = await pdf.getPage(1);
    const scale = 1;
    const viewport = page.getViewport({ scale });

    // Support HiDPI-screens.
    const outputScale = window.devicePixelRatio || 1;

    //
    // Prepare canvas using PDF page dimensions
    //
    const canvas = document.getElementById("pdf-viewer");
    const context = canvas.getContext("2d");

    canvas.width = Math.floor(viewport.width * outputScale);
    canvas.height = Math.floor(viewport.height * outputScale);
    canvas.style.width = Math.floor(viewport.width) + "px";
    canvas.style.height = Math.floor(viewport.height) + "px";

    const transform = outputScale !== 1
        ? [outputScale, 0, 0, outputScale, 0, 0]
        : null;

    //
    // Render PDF page into canvas context
    //
    const renderContext = {
        canvasContext: context,
        transform,
        viewport,
    };
    page.render(renderContext);
</script>
</body>

 

  • 결과는...

 

전체코드

https://github.com/MinseongNa/example_pdf.js