CVE-2022-0352 (Other, published 2022-01-28T22:15Z)
Description: value: Cross-site Scripting (XSS) - Reflected in Pypi calibreweb prior to 0.6.16.
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/janeczku/calibre-web
Files changed:
cps/templates/author.html
test/Calibre-Web TestSummary_Linux.html	
Commit message: Prevent wrong use of safe statement


Vulnerable code:
  <img title="{{author.name|safe}}" src="{{author.image_url}}" alt="{{author.name|safe}}" class="author-photo pull-left">
  <p>{{author.about|safe}}</p>
            <span class="img" title="{{entry.title|safe}}">
  <h3>{{_("More by")}} {{ author.name.replace('|',',')|safe }}</h3>
            <p class='text-justify attribute'><strong>Start Time: </strong>2022-01-16 21:58:58</p>
            <p class='text-justify attribute'><strong>Stop Time: </strong>2022-01-17 01:49:28</p>
           <p class='text-justify attribute'><strong>Duration: </strong>3h 10 min</p>
    <tr id="su" class="failClass">
        <td class="text-center">14</td>
        <td class="text-center">1</td>
        <tr id="ft6.7" class="none bg-danger">
            <td colspan='6'>
                <div class="text-center">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft6.7')">FAIL</a>
                </div>
                <!--css div popup start-->
                <div id="div_ft6.7" class="popup_window test_output" style="display:block;">
                    <div class='close_button pull-right'>
                        <button type="button" class="close" aria-label="Close" onfocus="this.blur();"
                                onclick="document.getElementById('div_ft6.7').style.display='none'"><span
                                aria-hidden="true">&times;</span></button>
                    </div>
                    <div class="text-left pull-left">
                        <pre class="text-left">Traceback (most recent call last):
  File &#34;/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py&#34;, line 164, in test_convert_parameter
    self.assertEqual(ret[-1][&#39;result&#39;], &#39;Finished&#39;)
AssertionError: &#39;Failed&#39; != &#39;Finished&#39;
- Failed
+ Finished</pre>
                    </div>
                    <div class="clearfix"></div>
                </div>
                <!--css div popup end-->
            </td>
        <td class="text-center">16</td>
        <td class="text-center">14</td>
            <a onclick="showClassDetail('c10', 16)">Detail</a>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier_capital</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier_standard</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_special_book_identifier</div>
                <div class='testcase'>TestEditAdditionalBooks - test_title_sort</div>
                <div class='testcase'>TestEditAdditionalBooks - test_upload_edit_role</div>
                <div class='testcase'>TestEditAdditionalBooks - test_upload_metadata_cbr</div>
        <tr id="st10.12" class="none bg-warning">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_st10.12')">SKIP</a>
                <div id="div_st10.12" class="popup_window test_output" style="display:none;">
                                onclick="document.getElementById('div_st10.12').style.display='none'"><span
        <tr id='pt10.13' class='hiddenRow bg-success'>
        <tr id='st10.14' class='none bg-warning'>
        <tr id='pt10.15' class='hiddenRow bg-success'>
        <tr id='pt10.16' class='hiddenRow bg-success'>
    <tr id="su" class="failClass">
        <td class="text-center">0</td>
        <tr id="ft13.1" class="none bg-danger">
            <td colspan='6'>
                <div class="text-center">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft13.1')">FAIL</a>
                </div>
                <!--css div popup start-->
                <div id="div_ft13.1" class="popup_window test_output" style="display:block;">
                    <div class='close_button pull-right'>
                        <button type="button" class="close" aria-label="Close" onfocus="this.blur();"
                                onclick="document.getElementById('div_ft13.1').style.display='none'"><span
                                aria-hidden="true">&times;</span></button>
                    </div>
                    <div class="text-left pull-left">
                        <pre class="text-left">Traceback (most recent call last):
  File &#34;/home/ozzie/Development/calibre-web-test/test/test_edit_books_metadata.py&#34;, line 136, in test_load_metadata
    self.assertGreaterEqual(diff(BytesIO(cover), BytesIO(original_cover), delete_diff_file=True), 0.05)
AssertionError: 0.0 not greater than or equal to 0.05</pre>
                    </div>
                    <div class="clearfix"></div>
                </div>
                <!--css div popup end-->
            </td>
    <tr id="su" class="failClass">
        <td class="text-center">1</td>
        <tr id='pt14.16' class='hiddenRow bg-success'>
            <td colspan='6' align='center'>PASS</td>
        <tr id="ft14.20" class="none bg-danger">
            <td colspan='6'>
                <div class="text-center">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft14.20')">FAIL</a>
                </div>
                <!--css div popup start-->
                <div id="div_ft14.20" class="popup_window test_output" style="display:block;">
                    <div class='close_button pull-right'>
                        <button type="button" class="close" aria-label="Close" onfocus="this.blur();"
                                onclick="document.getElementById('div_ft14.20').style.display='none'"><span
                                aria-hidden="true">&times;</span></button>
                    </div>
                    <div class="text-left pull-left">
                        <pre class="text-left">Traceback (most recent call last):
  File &#34;/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py&#34;, line 940, in test_watch_metadata
    self.assertNotIn(&#39;series&#39;, book)
AssertionError: &#39;series&#39; unexpectedly found in {&#39;id&#39;: 5, &#39;reader&#39;: [], &#39;title&#39;: &#39;testbook&#39;, &#39;author&#39;: [&#39;John Döe&#39;], &#39;rating&#39;: 0, &#39;languages&#39;: [&#39;English&#39;], &#39;identifier&#39;: [], &#39;cover&#39;: &#39;/cover/5?edit=4e213e83-fe57-4648-9e75-8e2176fe7773&#39;, &#39;tag&#39;: [], &#39;publisher&#39;: [&#39;Randomhäus&#39;], &#39;pubdate&#39;: &#39;Jan 19, 2017&#39;, &#39;comment&#39;: &#39;Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate&#39;, &#39;add_shelf&#39;: [], &#39;del_shelf&#39;: [], &#39;edit_enable&#39;: True, &#39;kindle&#39;: None, &#39;kindlebtn&#39;: None, &#39;download&#39;: [&#39;EPUB (6.7 kB)&#39;], &#39;read&#39;: False, &#39;archived&#39;: False, &#39;series_all&#39;: &#39;Book 1 of test&#39;, &#39;series_index&#39;: &#39;1&#39;, &#39;series&#39;: &#39;test&#39;, &#39;cust_columns&#39;: []}</pre>
                    </div>
                    <div class="clearfix"></div>
                </div>
                <!--css div popup end-->
            </td>
        <td class="text-center">1</td>
        <td class="text-center">1</td>
            <a onclick="showClassDetail('c19', 1)">Detail</a>
        <td>383</td>
        <td>372</td>
        <td>3</td>
    drawCircle(372, 3, 0, 8);

Fixed code:
  <img title="{{author.name}}" src="{{author.image_url}}" alt="{{author.name}}" class="author-photo pull-left">
  <p>{{author.about}}</p>
            <span class="img" title="{{entry.title}}">
  <h3>{{_("More by")}} {{ author.name.replace('|',',') }}</h3>
            <p class='text-justify attribute'><strong>Start Time: </strong>2022-01-17 18:51:33</p>
            <p class='text-justify attribute'><strong>Stop Time: </strong>2022-01-18 07:49:35</p>
           <p class='text-justify attribute'><strong>Duration: </strong>12h 17 min</p>
    <tr id="su" class="passClass">
        <td class="text-center">15</td>
        <td class="text-center">0</td>
        <tr id='pt6.7' class='hiddenRow bg-success'>
            <td colspan='6' align='center'>PASS</td>
        <td class="text-center">17</td>
        <td class="text-center">15</td>
            <a onclick="showClassDetail('c10', 17)">Detail</a>
                <div class='testcase'>TestEditAdditionalBooks - test_details_popup</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier_capital</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_book_identifier_standard</div>
                <div class='testcase'>TestEditAdditionalBooks - test_edit_special_book_identifier</div>
                <div class='testcase'>TestEditAdditionalBooks - test_title_sort</div>
                <div class='testcase'>TestEditAdditionalBooks - test_upload_edit_role</div>
            <td>
                <div class='testcase'>TestEditAdditionalBooks - test_upload_metadata_cbr</div>
            </td>
            <td colspan='6' align='center'>PASS</td>
        </tr>
    
    
    
        <tr id='pt10.12' class='hiddenRow bg-success'>
        <tr id="st10.13" class="none bg-warning">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_st10.13')">SKIP</a>
                <div id="div_st10.13" class="popup_window test_output" style="display:none;">
                                onclick="document.getElementById('div_st10.13').style.display='none'"><span
        <tr id='pt10.14' class='hiddenRow bg-success'>
        <tr id='st10.15' class='none bg-warning'>
        <tr id='pt10.16' class='hiddenRow bg-success'>
        <tr id='pt10.17' class='hiddenRow bg-success'>
    <tr id="su" class="passClass">
        <td class="text-center">0</td>
        <tr id='pt13.1' class='hiddenRow bg-success'>
            <td colspan='6' align='center'>PASS</td>
    <tr id="su" class="errorClass">
        <td class="text-center">1</td>
        <tr id="et14.16" class="none bg-info">
            <td colspan='6'>
                <div class="text-center">
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et14.16')">ERROR</a>
                </div>
                <!--css div popup start-->
                <div id="div_et14.16" class="popup_window test_output" style="display:block;">
                    <div class='close_button pull-right'>
                        <button type="button" class="close" aria-label="Close" onfocus="this.blur();"
                                onclick="document.getElementById('div_et14.16').style.display='none'"><span
                                aria-hidden="true">&times;</span></button>
                    </div>
                    <div class="text-left pull-left">
                        <pre class="text-left">Traceback (most recent call last):
  File &#34;/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py&#34;, line 250, in test_edit_title
    self.fill_basic_config({&#34;config_unicode_filename&#34;: 0})
  File &#34;/home/ozzie/Development/calibre-web-test/test/helper_ui.py&#34;, line 358, in fill_basic_config
    cls._fill_basic_config(elements)
  File &#34;/home/ozzie/Development/calibre-web-test/test/helper_ui.py&#34;, line 268, in _fill_basic_config
    WebDriverWait(cls.driver, 5).until(EC.presence_of_element_located((By.ID, &#34;config_port&#34;)))
  File &#34;/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/support/wait.py&#34;, line 89, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 
Stacktrace:
WebDriverError@chrome://remote/content/shared/webdriver/Errors.jsm:183:5
NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.jsm:395:5
element.find/&lt;/&lt;@chrome://remote/content/marionette/element.js:300:16</pre>
                    </div>
                    <div class="clearfix"></div>
                </div>
                <!--css div popup end-->
            </td>
        <tr id='pt14.20' class='hiddenRow bg-success'>
            <td colspan='6' align='center'>PASS</td>
        <td class="text-center">2</td>
        <td class="text-center">2</td>
            <a onclick="showClassDetail('c19', 2)">Detail</a>
    
        <tr id='pt19.2' class='hiddenRow bg-success'>
            <td>
                <div class='testcase'>TestErrorReadColumn - test_invalid_custom_read_column</div>
            </td>
            <td colspan='6' align='center'>PASS</td>
        </tr>
    
    
        <td>385</td>
        <td>376</td>
        <td>1</td>
    drawCircle(376, 0, 1, 8);