├── .github └── ISSUE_TEMPLATE │ └── bug-report-broken-page.md ├── .gitignore ├── .gitmodules ├── .reuse └── dep5 ├── CODING_STYLE ├── CODING_STYLE.license ├── DoxygenLayout.xml ├── DoxygenLayout.xml.license ├── LICENSE.md ├── LICENSES ├── CC-BY-4.0.txt ├── CC-BY-ND-4.0.txt ├── CC0-1.0.txt ├── GFDL-1.3-no-invariants-or-later.txt ├── GPL-3.0-or-later.txt ├── MIT.txt └── MPL-2.0.txt ├── Makefile ├── README.md ├── chrome ├── code_builders.patch ├── http_shield_chrome.js ├── manifest.json ├── manifest.json.license └── service_worker.js ├── code_of_conduct.md ├── common ├── _locales │ ├── cs │ │ └── messages.json │ ├── en │ │ └── messages.json │ └── ru │ │ └── messages.json ├── alea.js ├── background.js ├── code_builders.js ├── common.css ├── crc16.js ├── document_start.js ├── fp_code_builders.js ├── fp_config │ ├── groups-lvl_0.json │ ├── groups-lvl_1.json │ ├── schema │ │ ├── groups-schema.json │ │ └── wrappers-schema.json │ └── wrappers-lvl_0_1.json ├── fp_detect_background.js ├── fp_levels.js ├── fp_report.css ├── fp_report.html ├── fp_report.js ├── helpers.js ├── http_shield_common.js ├── i18n_translate_dom.js ├── img │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-19.png │ ├── icon-256.png │ ├── icon-32.png │ ├── icon-38.png │ ├── icon-48.png │ ├── icon-512.png │ ├── icon-64.png │ ├── icon-96.png │ ├── logo.svg │ └── makeicons.sh ├── level_cache.js ├── levels.js ├── lib │ ├── sha256.js │ └── sha256.js.license ├── options.css ├── options.html ├── options.js ├── options_advanced.html ├── options_advanced.js ├── options_domains.html ├── options_domains.js ├── options_init.js ├── popup.css ├── popup.html ├── popup.js ├── session_hash.js ├── settings_tweaks.js ├── tweaks_gui.js ├── update.js ├── url.js ├── wrapping.js ├── wrappingL-CANVAS.js ├── wrappingL-SENSOR.js ├── wrappingS-AJAX.js ├── wrappingS-BATTERY-CR.js ├── wrappingS-BE.js ├── wrappingS-COOP-SCHEDULING.js ├── wrappingS-DM.js ├── wrappingS-DOM.js ├── wrappingS-ECMA-ARRAY.js ├── wrappingS-ECMA-DATE.js ├── wrappingS-ECMA-SHARED.js ├── wrappingS-EME.js ├── wrappingS-GEO.js ├── wrappingS-GP.js ├── wrappingS-H-C.js ├── wrappingS-HRT.js ├── wrappingS-HTML-LS.js ├── wrappingS-HTML.js ├── wrappingS-HTML5.js ├── wrappingS-IDLE.js ├── wrappingS-MCS.js ├── wrappingS-MEDIA-CAPABILITIES.js ├── wrappingS-NET.js ├── wrappingS-NFC.js ├── wrappingS-NP.js ├── wrappingS-PT2.js ├── wrappingS-SENSOR-ACCEL.js ├── wrappingS-SENSOR-GYRO.js ├── wrappingS-SENSOR-LIGHT.js ├── wrappingS-SENSOR-MAGNET.js ├── wrappingS-SENSOR-ORIENT.js ├── wrappingS-SENSOR.js ├── wrappingS-VR.js ├── wrappingS-WEBA.js ├── wrappingS-WEBGL.js └── wrappingS-XR.js ├── doxyfile ├── firefox ├── http_shield_firefox.js ├── levels_browser.js ├── manifest.json ├── manifest.json.license └── options_nbs.js ├── fix_manifest.sh ├── fix_wasm_farbling.sh ├── generate_fpd.sh ├── logos_images └── store_imgs │ ├── chrome5.png │ ├── chrome5.png.license │ ├── chstore1.png │ ├── chstore1.png.license │ ├── chstore2.png │ ├── chstore2.png.license │ ├── chstore3.png │ ├── chstore3.png.license │ ├── chstore4.png │ ├── chstore4.png.license │ ├── firefox1.png │ ├── firefox1.png.license │ ├── firefox2.png │ ├── firefox2.png.license │ ├── firefox3.png │ ├── firefox3.png.license │ ├── firefox4.png │ ├── firefox4.png.license │ ├── firefox5.png │ ├── firefox5.png.license │ ├── geolocation.png │ ├── geolocation.png.license │ ├── geolocation_resized.png │ ├── geolocation_resized.png.license │ ├── opera1.png │ ├── opera1.png.license │ ├── opera2.png │ ├── opera2.png.license │ ├── opera3.png │ └── opera3.png.license ├── make_release.sh ├── tests ├── benchmark │ ├── avfarbling.html │ └── files │ │ ├── avfarbling.js │ │ ├── global.css │ │ ├── math.js │ │ └── math.js.LICENSE ├── common_files │ ├── scripts │ │ ├── build_JSR_package.ps1 │ │ └── build_JSR_package.sh │ └── webbrowser_drivers │ │ └── DOWNLOAD WEB DRIVERS HERE.md ├── fpd_tests │ ├── README.md │ ├── common │ │ ├── csv_to_wrappers.sh │ │ ├── helpers.js │ │ ├── iframe.html │ │ ├── worker.js │ │ └── wrapper_to_test.sh │ ├── index.html │ ├── start_fpd_tests.sh │ └── tests │ │ └── custom.js ├── integration_tests │ ├── README.md │ ├── start_integration_tests.ps1 │ ├── start_integration_tests.sh │ └── testing │ │ ├── configuration.py │ │ ├── conftest.py │ │ ├── math_operations.py │ │ ├── output.py │ │ ├── start.py │ │ ├── tests_definition │ │ ├── test_01_hw.py │ │ ├── test_02_NBS_setting.py │ │ ├── test_03_domain_level_setting.py │ │ ├── test_04_canvas.py │ │ ├── test_05_navigator.py │ │ ├── test_06_performance.py │ │ ├── test_07_ECMA_arrays.py │ │ ├── test_08_time.py │ │ ├── test_09_toString.py │ │ ├── test_10_webaudio.py │ │ ├── test_11_webgl.py │ │ └── test_12_gps.py │ │ ├── values_expected.py │ │ ├── values_getters.py │ │ ├── values_real.py │ │ ├── values_tested.py │ │ ├── web_browser.py │ │ ├── web_browser_shared.py │ │ └── web_browser_type.py ├── system_tests │ ├── README.md │ ├── analyze_data │ │ ├── cosine_similarity.py │ │ ├── io_funcs.py │ │ ├── levenshtein_distance.py │ │ ├── simple_comparison.py │ │ ├── start_logs_analysis.py │ │ └── start_screenshots_analysis.py │ ├── get_data │ │ ├── configuration.py │ │ ├── driver.py │ │ ├── grid.py │ │ ├── io_funcs.py │ │ ├── start.py │ │ ├── test_type.py │ │ ├── web_browser_type.py │ │ └── website.py │ └── setup_buildJSR_runTests.sh └── unit_tests │ ├── README.md │ ├── config │ ├── global-example.json │ ├── global-schema.json │ ├── global.json │ └── jasmine.json │ ├── package-lock.json │ ├── package.json │ ├── start_unit_tests.sh │ └── tests │ ├── background_tests.js │ ├── browser_tests.js │ ├── code_builders_tests.js │ ├── crc16_tests.js │ ├── helpers_tests.js │ ├── http_shield_common_tests.js │ ├── levels_tests.js │ ├── url_tests.js │ ├── wrappingS-ECMA-ARRAY_tests.js │ ├── wrappingS-ECMA-SHARED_tests.js │ ├── wrappingS-GEO_tests.js │ ├── wrappingS-H-C_tests.js │ ├── wrappingS-WEBA_tests.js │ ├── wrappingS-WEBGL_tests.js │ └── wrapping_tests.js ├── tools └── i18n │ ├── get_translated_strings.sh │ ├── main2weblate.py │ ├── weblate2main.py │ └── weblatelib.py ├── wasm ├── README.md ├── asconfig.json ├── assembly │ ├── farble.ts │ └── tsconfig.json ├── package-lock.json └── package.json └── website ├── .gitignore ├── Makefile ├── README.md ├── content ├── images │ ├── cooperation │ │ ├── almost-passive.png │ │ ├── chrome-weekly-2022-03-17.png │ │ ├── fine-tuning.png │ │ ├── firefox-daily-2022-03-17.png │ │ └── fpd-report.png │ ├── crawling-apis.png │ ├── crawling-architecture.png │ ├── crawling_results │ │ ├── APIs_with_uBlock.png │ │ ├── APIs_with_uBlock_opensource.png │ │ ├── APIs_without_uBlock.png │ │ ├── APIs_without_uBlock_opensource.png │ │ ├── JScalls_with_uBlock.png │ │ ├── JScalls_with_uBlock_opensource.png │ │ ├── JScalls_without_uBlock.png │ │ └── JScalls_without_uBlock_opensource.png │ ├── device_artificial.svg │ ├── device_moving.svg │ ├── device_stationary.svg │ ├── faq │ │ ├── chromium_pintoolbar.png │ │ ├── firefox_pintoolbar.png │ │ ├── fpd_off.png │ │ ├── jss_low.png │ │ ├── jss_off.png │ │ ├── jss_tweak_sorting.png │ │ ├── jss_tweak_start.png │ │ ├── jss_tweaking.png │ │ └── nbs_off.png │ ├── fpdetection │ │ └── notifications.png │ ├── i18n │ │ └── webly.png │ ├── optimizations │ │ ├── firefox_audio_recommended.png │ │ ├── firefox_canvas3d_recommended.png │ │ └── firefox_canvas_recommended.png │ ├── portscan-1_captured_traffic.png │ └── portscan-2_request_blocked.png ├── pages │ ├── build.md │ ├── build.md.license │ ├── coding-style.md │ ├── coding-style.md.license │ ├── credits.md │ ├── credits.md.license │ ├── faq.md │ ├── faq.md.license │ ├── fpd.md │ ├── fpd.md.license │ ├── home.md │ ├── home.md.license │ ├── install.md │ ├── install.md.license │ ├── levels.md │ ├── levels.md.license │ ├── license.md │ ├── license.md.license │ ├── nbs.md │ ├── nbs.md.license │ ├── new-wrapper.md │ ├── new-wrapper.md.license │ ├── permissions.md │ ├── permissions.md.license │ ├── threatmodel.md │ ├── threatmodel.md.license │ ├── versions.md │ └── versions.md.license └── posts │ ├── cooperation.md │ ├── crawling.md │ ├── crawling_results.md │ ├── farbling.md │ ├── fingerprinting.md │ ├── first-mv3-step.md │ ├── fixing-mv3.md │ ├── fpdetection.md │ ├── i18n.md │ ├── i18n_developers.md │ ├── jsrfinal.md │ ├── localportscanning.md │ ├── mv3-jshelter-debut.md │ ├── mv3.md │ ├── optimizations.md │ ├── paper2022.md │ ├── sensorapi.md │ └── support.md ├── extract_comments.py ├── i18n ├── build_po_files.sh ├── download.sh ├── postprocess.py └── translate_content.sh ├── md-templates └── wrapper.md ├── pelicanconf.py ├── plugins ├── i18n_subsites │ ├── README.rst │ ├── __init__.py │ ├── i18n_subsites.py │ ├── implementing_language_buttons.rst │ ├── localizing_using_jinja2.rst │ ├── test_data │ │ ├── content │ │ │ ├── images │ │ │ │ └── img.png │ │ │ ├── pages │ │ │ │ ├── hidden-page-cz.rst │ │ │ │ ├── hidden-page-de.rst │ │ │ │ ├── hidden-page-en.rst │ │ │ │ └── untranslated-page.rst │ │ │ ├── translated_article-cz.rst │ │ │ ├── translated_article-de.rst │ │ │ ├── translated_article-en.rst │ │ │ └── untranslated_article-en.rst │ │ ├── localized_theme │ │ │ ├── babel.cfg │ │ │ ├── messages.pot │ │ │ ├── static │ │ │ │ └── style.css │ │ │ ├── templates │ │ │ │ └── base.html │ │ │ └── translations │ │ │ │ └── de │ │ │ │ └── LC_MESSAGES │ │ │ │ ├── messages.mo │ │ │ │ └── messages.po │ │ ├── output │ │ │ ├── an-untranslated-article.html │ │ │ ├── cz │ │ │ │ ├── an-untranslated-article-en.html │ │ │ │ ├── feeds_all.atom.xml │ │ │ │ ├── index.html │ │ │ │ ├── pages │ │ │ │ │ └── 404.html │ │ │ │ └── translated-article.html │ │ │ ├── de │ │ │ │ ├── drafts │ │ │ │ │ └── an-untranslated-article-en.html │ │ │ │ ├── feeds_all.atom.xml │ │ │ │ ├── index.html │ │ │ │ ├── pages │ │ │ │ │ ├── 404.html │ │ │ │ │ └── untranslated-page-en.html │ │ │ │ └── translated-article.html │ │ │ ├── feeds_all.atom.xml │ │ │ ├── images │ │ │ │ └── img.png │ │ │ ├── index.html │ │ │ ├── pages │ │ │ │ ├── 404.html │ │ │ │ └── untranslated-page.html │ │ │ ├── theme │ │ │ │ └── style.css │ │ │ └── translated-article.html │ │ └── pelicanconf.py │ └── test_i18n_subsites.py └── series │ ├── Readme.md │ ├── __init__.py │ └── series.py ├── publishconf.py ├── requirements.txt └── theme ├── favicon.ico ├── favicon.png ├── security.txt ├── static ├── css │ ├── fork-awesome.min.css │ ├── main.css │ └── minireset.min.css ├── fonts │ ├── Inter-Black.woff │ ├── Inter-Black.woff2 │ ├── Inter-Bold.woff │ ├── Inter-Bold.woff2 │ ├── Inter-Regular.woff │ ├── Inter-Regular.woff2 │ ├── Inter-SemiBold.woff2 │ ├── OxygenMono-Regular.woff │ ├── OxygenMono-Regular.woff2 │ ├── forkawesome-webfont.eot │ ├── forkawesome-webfont.svg │ ├── forkawesome-webfont.ttf │ ├── forkawesome-webfont.woff │ └── forkawesome-webfont.woff2 ├── images │ ├── brno-fit-logo.svg │ ├── brno-fit-logo_color.svg │ ├── crumbled-paper.png │ ├── crumbled-paper_dark.png │ ├── fsf-logo.svg │ ├── icon.png │ ├── icon_48px.png │ ├── jshelter-hero.svg │ ├── jshelter-horizontal.svg │ ├── jshelter-horizontal_dark.svg │ ├── jshelter-logo.svg │ ├── jshelter.svg │ ├── jshelter_preview.png │ └── nlnet-logo.svg └── js │ └── bowser.js └── templates ├── article.html ├── base.html ├── home.html ├── index.html └── page.html /.github/ISSUE_TEMPLATE/bug-report-broken-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report/broken page 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Summary 11 | 12 | [Explain your issues, be concrete, what is wrong and why. Make sure that you explain yourself and 13 | the text is clear and understandable.] 14 | 15 | ## Setup 16 | 17 | [If you want to report a broken page, please fill in details. If you have different issue, some 18 | information might be irrelevant. Try to provide as much relevant information as possible] 19 | 20 | Pages affected: [URL/all pages/URLs] 21 | JShelter Version: 22 | 23 | Popup information (open JShelter popup on affected pages: 24 | 25 | 1. Navigate to a page that you are having trouble with: [URL] 26 | 2. Click on the JShelter badge icon. 27 | 3. Is JavaScript Shield active? [ON/OFF] 28 | 3. Is Network Boundary Shield active? [ON/OFF] 29 | 3. Is Fingerprint Detector active? [ON/OFF] 30 | 4. What fingerprint likelihood does Fingerprint Detector report? 31 | 5. Did Fingerprint Detector produce any notifications, if so, what was the notification? 32 | 6. Click on the `Modify` button next to the JavaScript Shield label. 33 | 7. What is the highlighted level button text? 34 | 8. Click on the `Detail tweaks of JS shield for this site` button. 35 | 9. What wrappers were triggered by the page, list them below: 36 | 37 | 38 | [Optional:] 39 | 40 | OS: 41 | Browser: 42 | Other extensions that might affect JShelter behaviour: 43 | 44 | 45 | ## How to reproduce 46 | 47 | 1. [List steps to reproduce your issue ] 48 | 2. ... 49 | 3. ... 50 | 51 | ## Expected result 52 | 53 | [Fill in what you expected] 54 | 55 | ## Actual result 56 | 57 | [Fill in what happened] 58 | 59 | ## Reproducibility 60 | 61 | [Have you tried another profile/browser/machine/OS?] 62 | 63 | ## Workarounds 64 | 65 | [Have you tried tweaking the extension, e.g. JS Shield (see the setup section above). Please try to chage settings for the triggered wrappers. Were you successful?] 66 | 67 | ## Have you tried other steps to solve the issue? 68 | 69 | 1. I tried X but ... 70 | 2. I tried Y but ... 71 | 3. I tried Z but ... 72 | 73 | [Was there any progress?] 74 | 75 | ## Additional information / notes 76 | 77 | [Other additional notes] 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitignore 3 | !.reuse 4 | *.zip 5 | build/ 6 | ipv4.csv 7 | common/ipv4.dat 8 | ipv6.csv 9 | common/ipv6.dat 10 | common/wrappingX* 11 | doxygen/ 12 | *.crx 13 | *.xpi 14 | *.pyc 15 | *.log 16 | tests/common_files/webbrowser_drivers/chromedriver* 17 | tests/common_files/webbrowser_drivers/geckodriver* 18 | tests/system_tests/data/ 19 | tests/system_tests/get_data/top_sites/*.csv 20 | tests/system_tests/get_data/selenium/*.jar 21 | tests/unit_tests/node_modules/* 22 | tests/unit_tests/tmp/* 23 | tests/fpd_tests/wrappers* 24 | tests/fpd_tests/tests/resources.js 25 | tests/performance_tests/node_modules 26 | 27 | wasm/node_modules 28 | 29 | website/output 30 | website/content/wrappers/* 31 | website/content/pages/*_tests.md 32 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "nscl"] 2 | path = nscl 3 | url = https://github.com/hackademix/nscl.git 4 | -------------------------------------------------------------------------------- /CODING_STYLE: -------------------------------------------------------------------------------- 1 | Indentation: tabulators 2 | Avoid spaces/tabs at the end of the line 3 | 4 | Functions, methods, classes, ifs, cycles etc. have opening braces at the same line. 5 | 6 | Text width preferred less than 80 characters, maximum 100 characters. It is better having readable 7 | code than pursuing this limit. 8 | 9 | Always enclose blocks of expressions into brackets. 10 | 11 | Names are lower case and prefferably explains the purpose of the variable, class etc. 12 | 13 | Comment classes, functions, etc. in Doxygen style, use 'make doc' to generate documentation. 14 | 15 | Correct code example: 16 | 17 | /** 18 | * This is an example function created for the coding style manual. 19 | * 20 | * @param abc The number that will be ... 21 | * @returns The Answer to the Ultimate Question of Life, The Universe, and Everything. 22 | */ 23 | function example(abc) { 24 | var counter = 0; 25 | for (let i = 0; i < 42; i++) { 26 | counter++; 27 | } 28 | return counter; 29 | }; 30 | 31 | Bad code example: 32 | 33 | function example(abc) 34 | { 35 | function method() 36 | { 37 | return 42; 38 | } 39 | return method(); 40 | }; 41 | 42 | However, please do not provide commits dealing with bad coding style. The only exception is if you 43 | want to improve code that does not follow the coding style rules. Preferably provide one commit that 44 | fixes the issues and another (others) that improve the code, add new functionality etc. 45 | 46 | 47 | Create atomic commits, see for example, https://www.freshconsulting.com/atomic-commits/ 48 | 49 | A commit should not contain adding missing semicolons, changes in generated code, a bugfix, and 50 | addition of a new functionality. Each of these changes should go to a separate commit with a message 51 | explaining why is the change necessary (if it is not obvious like in the case of missing 52 | semicolons). 53 | 54 | Provide meaningful commit messages, see, for example, https://chris.beams.io/posts/git-commit/, 55 | especially points 1, 2 a 7. 56 | 57 | Do not fear of changing commits that are not public, yet. If you create a bug and find it before 58 | merge, it is better to fix the bug in the original commit. See `git rebase (-i)`, fixup, squash, 59 | `git push --force`. 60 | 61 | The pull request #39 contains an example of big commits that needed to be refactored. 62 | 63 | Provide merge request more often rather than commiting big changes. If you fix Makefile or other 64 | scripts, provide the change and do not wait. Create code that is understandable and does not repeat 65 | itself. If possible, use variables instead of copying the same code. 66 | -------------------------------------------------------------------------------- /CODING_STYLE.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Libor Polčák 2 | // SPDX-License-Identifier: GFDL-1.3-no-invariants-or-later 3 | -------------------------------------------------------------------------------- /DoxygenLayout.xml.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2021 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining 2 | a copy of this software and associated documentation files (the 3 | "Software"), to deal in the Software without restriction, including 4 | without limitation the rights to use, copy, modify, merge, publish, 5 | distribute, sublicense, and/or sell copies of the Software, and to 6 | permit persons to whom the Software is furnished to do so, subject to 7 | the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be 10 | included in all copies or substantial portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2019 Martin Timko 2 | # SPDX-FileCopyrightText: 2019-2021 Libor Polčák 3 | # SPDX-FileCopyrightText: 2020 Peter Horňák 4 | # SPDX-FileCopyrightText: 2021 Giorgio Maone 5 | # SPDX-FileCopyrightText: 2021 Marek Saloň 6 | # SPDX-FileCopyrightText: 2023 Martin Zmitko 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | 10 | DEBUG=0 11 | 12 | all: firefox chrome 13 | 14 | .PHONY: firefox chrome clean get_csv docs wasm 15 | firefox: jshelter_firefox.zip 16 | chrome: jshelter_chrome.zip 17 | wasm: wasm/build/debug.wasm wasm/build/release.wasm 18 | 19 | COMMON_FILES = $(shell find common/) \ 20 | LICENSES/ \ 21 | Makefile \ 22 | $(shell find firefox/) \ 23 | $(shell find chrome/) 24 | 25 | PROJECT_NAME = $(shell grep ^PROJECT_NAME doxyfile | cut -f2 -d'"') 26 | 27 | debug=1 28 | 29 | wasm/build/%.wasm: wasm/assembly/farble.ts 30 | @cd wasm && npm install && npm run $* 31 | 32 | get_csv: 33 | wget -q -N https://www.iana.org/assignments/locally-served-dns-zones/ipv4.csv 34 | cp ipv4.csv common/ipv4.dat 35 | wget -q -N https://www.iana.org/assignments/locally-served-dns-zones/ipv6.csv 36 | cp ipv6.csv common/ipv6.dat 37 | 38 | submodules: 39 | ifneq (,$(wildcard .git)) 40 | git submodule init 41 | git submodule update 42 | endif 43 | 44 | jshelter_%.zip: $(COMMON_FILES) get_csv submodules wasm 45 | @mkdir -p build/ 46 | @rm -rf build/$*/ $@ 47 | @cp -r common/ build/$*/ 48 | @cp -r $*/* build/$*/ 49 | @cp -r LICENSES build/$*/ 50 | @./generate_fpd.sh build/$*/ 51 | @nscl/include.sh build/$* 52 | @if [ $(DEBUG) -eq 0 ]; \ 53 | then \ 54 | find build/$*/ -type f -name "*.js" -exec sed -i '/console\.debug(.*);/d' {} + ; \ 55 | fi 56 | @./fix_wasm_farbling.sh $(DEBUG) $* 57 | @rm -f build/$*/.*.sw[pno] 58 | @rm -f build/$*/img/makeicons.sh 59 | @find build/$*/ -name '*.license' -delete 60 | @./fix_manifest.sh build/$*/ 61 | @cd build/$*/ && zip -q -r ../../$@ ./* --exclude \*.sw[pno] 62 | @echo "LOG-WARNING: Number of lines in build/$* with console.log:" 63 | @grep -re 'console.log' build/$* | wc -l 64 | 65 | debug: DEBUG=1 66 | debug: all 67 | 68 | docs: 69 | PROJECT_NAME="${PROJECT_NAME}" doxygen < doxyfile 70 | 71 | clean: 72 | rm -rf build/ 73 | rm -rf jsheleter_firefox.zip 74 | rm -rf jshelter_chrome.zip 75 | rm -rf common/ipv4.dat 76 | rm -rf common/ipv6.dat 77 | rm -rf common/wrappingX* 78 | rm -rf ipv4.csv 79 | rm -rf ipv6.csv 80 | rm -rf doxygen/ 81 | cd wasm && npm run clean 82 | -------------------------------------------------------------------------------- /chrome/code_builders.patch: -------------------------------------------------------------------------------- 1 | diff --git a/code_builders.js b/code_builders.js 2 | index 002e2e18..6e82a90e 100644 3 | --- a/code_builders.js 4 | +++ b/code_builders.js 5 | @@ -380,7 +380,12 @@ function insert_wasm_code(code) { 6 | const reserved_offset = 544; 7 | const data_offset = 1024; 8 | 9 | - WebAssembly.instantiateStreaming(fetch("/* WASM_URL */"), {env: {memory: wasm_memory}}).then(result => { 10 | + let wasm_string = atob("__WASM_CODE_DURING_BUILD__"); 11 | + let wasm_bytes = new Uint8Array(wasm_string.length); 12 | + for (let i = 0; i < wasm_string.length; i++) { 13 | + wasm_bytes[i] = wasm_string.charCodeAt(i); 14 | + } 15 | + WebAssembly.instantiate(wasm_bytes, {env: {memory: wasm_memory}}).then(result => { 16 | new Uint16Array(wasm_memory.buffer, crc_offset, crc16_table.length).set(crc16_table); 17 | const xoring = new Uint32Array(wasm_memory.buffer, xoring_offset, 8); 18 | for (let i = 0; i < 64; i += 8) { 19 | @@ -435,7 +440,7 @@ function insert_wasm_code(code) { 20 | }).catch(e => { 21 | console.warn("Failed to instantiate WASM farbling module, falling back to JS implementation", e); 22 | }); 23 | - }).toString().replace("/* WASM_URL */", browser.runtime.getURL("farble.wasm")); 24 | + }).toString(); 25 | 26 | return code.replace("// WASM_CODE //", `(${wasm_code})()`); 27 | } 28 | -------------------------------------------------------------------------------- /chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Libor Polčák, Giorgio Maone, Martin Timko, Pavel Pohner, Peter Horňák, Matúš Švancár, Marek Saloň, Martin Bednář, Radek Hranický, Martin Zmitko", 3 | "background": { 4 | "service_worker": "service_worker.js" 5 | }, 6 | "action": { 7 | "default_icon": { 8 | "16": "img/icon-16.png", 9 | "32": "img/icon-32.png", 10 | "48": "img/icon-48.png", 11 | "64": "img/icon-64.png", 12 | "96": "img/icon-96.png", 13 | "128": "img/icon-128.png", 14 | "256": "img/icon-256.png", 15 | "512": "img/icon-512.png" 16 | }, 17 | "default_title": "JShelter", 18 | "default_popup": "popup.html" 19 | }, 20 | "content_scripts": [ 21 | { 22 | "matches": [""], 23 | "all_frames": true, 24 | "match_about_blank": true, 25 | "match_origin_as_fallback": true, 26 | "js": [ 27 | "nscl/lib/browser-polyfill.js", 28 | "nscl/common/uuid.js", 29 | "nscl/common/SyncMessage.js", 30 | "nscl/content/patchWindow.js", 31 | "lib/sha256.js", 32 | "helpers.js", 33 | "document_start.js" 34 | ], 35 | "run_at": "document_start" 36 | } 37 | ], 38 | "default_locale": "en", 39 | "description": "__MSG_extensionDescription__", 40 | "homepage_url": "https://JShelter.org", 41 | "icons": { 42 | "16": "img/icon-16.png", 43 | "32": "img/icon-32.png", 44 | "48": "img/icon-48.png", 45 | "64": "img/icon-64.png", 46 | "96": "img/icon-96.png", 47 | "128": "img/icon-128.png", 48 | "256": "img/icon-256.png", 49 | "512": "img/icon-512.png" 50 | }, 51 | "manifest_version": 3, 52 | "minimum_chrome_version": "120", 53 | "name": "__MSG_extensionName__", 54 | "options_page": "options.html", 55 | "content_security_policy": { 56 | "extension_pages": "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self';base-uri 'self';form-action 'self'" 57 | }, 58 | "permissions": [ 59 | "storage", 60 | "tabs", 61 | "webRequest", 62 | "declarativeNetRequest", 63 | "webNavigation", 64 | "notifications", 65 | "scripting", 66 | "userScripts" 67 | ], 68 | "host_permissions": [""], 69 | "optional_permissions": ["browsingData"], 70 | "short_name": "JShelter", 71 | "version": "0.20.2" 72 | } 73 | -------------------------------------------------------------------------------- /chrome/manifest.json.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019 Martin Timko 2 | // SPDX-FileCopyrightText: 2021 Giorgio Maone 3 | // 4 | // SPDX-License-Identifier: GPL-3.0-or-later 5 | -------------------------------------------------------------------------------- /chrome/service_worker.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Stub service worker including all the background scripts 3 | * 4 | * \author Copyright (C) 2019 Libor Polcak 5 | * \author Copyright (C) 2019 Martin Timko 6 | * \author Copyright (C) 2023 Martin Zmitko 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | importScripts( 25 | "nscl/lib/browser-polyfill.js", 26 | "lib/sha256.js", 27 | "nscl/common/CachedStorage.js", 28 | "nscl/common/log.js", 29 | "nscl/common/uuid.js", 30 | "nscl/common/SyncMessage.js", 31 | "nscl/common/tld.js", 32 | "nscl/service/DocStartInjection.js", 33 | "nscl/service/TabCache.js", 34 | "nscl/service/NavCache.js", 35 | "helpers.js", 36 | "session_hash.js", 37 | "update.js", 38 | "url.js", 39 | "settings_tweaks.js", 40 | "levels.js", 41 | "fp_levels.js", 42 | "fp_detect_background.js", 43 | "background.js", 44 | "level_cache.js", 45 | WRAPPING, 46 | "alea.js", 47 | "crc16.js", 48 | "code_builders.js", 49 | "fp_code_builders.js", 50 | "nscl/content/patchWindow.js" 51 | //"http_shield_chrome.js", 52 | //"http_shield_common.js" 53 | ); 54 | -------------------------------------------------------------------------------- /common/fp_report.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * SPDX-FileCopyrightText: 2022 2021 Marek Saloň 4 | * 5 | * SPDX-License-Identifier: GPL-3.0-or-later 6 | */ 7 | 8 | body { 9 | padding: 1em; 10 | margin: 1em; 11 | min-width: 38em; 12 | font-family: "Segoe UI", Tahoma, sans-serif; 13 | font-size: 75%; 14 | } 15 | 16 | header { 17 | display: flex; 18 | flex-direction: row; 19 | justify-content: space-between; 20 | align-items: center; 21 | font-size: large; 22 | margin-bottom: 0.5em; 23 | border-bottom: 2px solid #aaa; 24 | } 25 | 26 | header > div { 27 | min-width: 0; 28 | } 29 | 30 | h4 { 31 | color: var(--text-color); 32 | } 33 | 34 | #logo { 35 | width: 48px; 36 | padding-left: 50px; 37 | } 38 | 39 | #titletext { 40 | display: block; 41 | font-size: large; 42 | text-align: center; 43 | margin: 0.2em 0px; 44 | text-align: left; 45 | color: var(--title-color); 46 | } 47 | 48 | .fpd-group .fpd-group { 49 | padding-left: 2em; 50 | border-left: 2px solid #aaa; 51 | } 52 | 53 | .fpd-group > h2 { 54 | display: inline-block; 55 | color: var(--title-color); 56 | margin: 0px 0px; 57 | -webkit-transition: color 0.5s; 58 | -moz-transition: color 0.5s; 59 | -ms-transition: color 0.5s; 60 | -o-transition: color 0.5s; 61 | transition: color 0.5s; 62 | } 63 | 64 | .fpd-group > h2.clickable:hover { 65 | cursor: pointer; 66 | color: var(--text-color); 67 | } 68 | 69 | .dot { 70 | color: var(--title-color); 71 | } 72 | 73 | .hidden { 74 | display: none; 75 | } 76 | 77 | .no-access { 78 | display: none; 79 | } 80 | 81 | #pageFavicon { 82 | height: 18px; 83 | margin-right: 2px; 84 | } 85 | 86 | #pageFavicon:not([src^="data:"]) { 87 | display: none 88 | } 89 | 90 | #page-container { 91 | white-space: nowrap; 92 | } 93 | 94 | #report-url { 95 | display: inline-block; 96 | height: 20px; 97 | max-width: 99%; 98 | white-space: nowrap; 99 | overflow: hidden !important; 100 | text-overflow: ellipsis; 101 | margin: 0px; 102 | color: var(--text-color); 103 | } 104 | 105 | .sticky-button { 106 | float: right; 107 | position: sticky; 108 | top: 10px; 109 | cursor: pointer; 110 | margin-left: 0.5em; 111 | } 112 | 113 | .description { 114 | font-size: x-small; 115 | } 116 | 117 | #unhideAll { 118 | cursor: pointer; 119 | color: var(--title-color); 120 | text-decoration: underline; 121 | } 122 | -------------------------------------------------------------------------------- /common/i18n_translate_dom.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief JS code that retrieves all HTML files with data-localize attributes and localizes them 3 | * 4 | * \author Copyright (C) 2022 TotalCaesar659 5 | * 6 | * See https://github.com/polcak/jsrestrictor/pull/189 for the origins of the code. 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | function localizeHTMLelement(e) { 26 | const translateStringName = e.dataset.localize; 27 | if (translateStringName) { 28 | const translated = browser.i18n.getMessage(translateStringName); 29 | if (translated) { 30 | if (e.hasAttribute("htmltranslation")) { 31 | e.innerHTML = translated; 32 | } 33 | else { 34 | e.innerText = translated; 35 | } 36 | } 37 | } 38 | } 39 | 40 | const textElements = document.querySelectorAll('[data-localize]'); 41 | textElements.forEach(localizeHTMLelement); 42 | 43 | const templates = document.getElementsByTagName("template"); 44 | for (t of templates) { 45 | t.content.querySelectorAll('[data-localize]').forEach(localizeHTMLelement); 46 | } 47 | -------------------------------------------------------------------------------- /common/img/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-128.png -------------------------------------------------------------------------------- /common/img/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-16.png -------------------------------------------------------------------------------- /common/img/icon-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-19.png -------------------------------------------------------------------------------- /common/img/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-256.png -------------------------------------------------------------------------------- /common/img/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-32.png -------------------------------------------------------------------------------- /common/img/icon-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-38.png -------------------------------------------------------------------------------- /common/img/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-48.png -------------------------------------------------------------------------------- /common/img/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-512.png -------------------------------------------------------------------------------- /common/img/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-64.png -------------------------------------------------------------------------------- /common/img/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/common/img/icon-96.png -------------------------------------------------------------------------------- /common/img/makeicons.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2021 Giorgio Maone 4 | # 5 | # SPDX-License-Identifier: GPL-3.0-or-later 6 | 7 | # Run this to regenerate icon-[size].png icons from a modified logo.svg 8 | # (Chrome doesn't support SVG for extensions icons) 9 | 10 | for f in icon-*.png; do 11 | n=$(echo "$f" | sed -re 's/.*-([0-9]+).*/\1/'); 12 | convert +antialias -background none logo.svg -resize "$n"x"$n" "icon-$n.png"; 13 | done 14 | -------------------------------------------------------------------------------- /common/lib/sha256.js.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2014-2017 Chen, Yi-Cyuan 2 | 3 | SPDX-License-Identifier: MIT -------------------------------------------------------------------------------- /common/options_init.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Code that handles initialization in the options pages 3 | * 4 | * \author Copyright (C) 2023 Libor Polcak 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | // Make sure that updateLevels() is called while fp_levels_initialised is set to true 24 | // Note that the options pages do not initialize real FPD. This is needed to call 25 | // callbacks directly 26 | fp_levels_initialised = true; 27 | browser.storage.sync.get(null).then(updateLevels); 28 | -------------------------------------------------------------------------------- /common/session_hash.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief A cache for session and domain hashes, used for Farbling 3 | * 4 | * \author Copyright (C) 2021 Matus Svancar 5 | * \author Copyright (C) 2021 Giorgio Maone 6 | * 7 | * \license SPDX-License-Identifier: GPL-3.0-or-later 8 | */ 9 | // 10 | // This program is free software: you can redistribute it and/or modify 11 | // it under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 3 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will be useful, 16 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with this program. If not, see . 22 | // 23 | 24 | /** 25 | * Object for generating and caching domain/session hashes 26 | * getFor method used to get domain hashes from given url 27 | * 28 | * \note cached visited domains with related keys are only deleted after end of the session 29 | */ 30 | 31 | // depends on /nscl/common/CachedStorage.js 32 | 33 | var Hashes = { 34 | async getFor(url){ 35 | let site = getSiteForURL(url); 36 | let {sessionHash, visitedDomains} = await CachedStorage.init({ 37 | sessionHash: null, 38 | visitedDomains: {} 39 | }, "Hashes"); 40 | this.sessionHash = sessionHash ??= gen_random64().toString(); 41 | let siteHashes = visitedDomains[site]; 42 | if (!siteHashes) { 43 | let hmac = sha256.hmac.create(this.sessionHash); 44 | hmac.update(site); 45 | const domainHash = hmac.hex(); 46 | const hash = sha256.create(); 47 | hash.update(JSON.stringify(domainHash)); 48 | // Redefine the domainHash for incognito context: 49 | // Compute the SHA256 hash of the original hash so that the incognito hash is: 50 | // * significantly different to the original domainHash, 51 | // * computationally difficult to revert, 52 | // * the same for all incognito windows (for the same domain). 53 | const incognitoHash = hash.hex(); 54 | visitedDomains[site] = siteHashes = {domainHash, incognitoHash}; 55 | await CachedStorage.save(this); 56 | } 57 | return siteHashes; 58 | } 59 | }; 60 | 61 | -------------------------------------------------------------------------------- /common/settings_tweaks.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Fine-tuning of the JShelter settings, for example, based on domains 3 | * 4 | * \author Copyright (C) 2023 Libor Polcak 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // This program is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | /// Tweaks for specific domains that are built-in for all users 23 | var tweak_domains_builtin = { 24 | "docs.google.com": { 25 | "explanation": "https://pagure.io/JShelter/webextension/issue/122", 26 | "level_id": ["1", "2"], 27 | "tweaks": { 28 | "webworker": 2 29 | } 30 | }, 31 | "app.mediafire.com": { 32 | "explanation": "https://github.com/polcak/jsrestrictor/issues/207", 33 | "level_id": ["1", "2"], 34 | "tweaks": { 35 | "webworker": 2 36 | } 37 | }, 38 | "pad.riseup.net": { 39 | "explanation": "https://pagure.io/JShelter/webextension/issue/152", 40 | "level_id": ["1", "2"], 41 | "tweaks": { 42 | "webworker": 2 43 | } 44 | }, 45 | "kiwi.com": { 46 | "explanation": "https://pagure.io/JShelter/webextension/issue/153", 47 | "level_id": ["1", "2"], 48 | "tweaks": { 49 | "webworker": 2 50 | } 51 | }, 52 | }; 53 | 54 | // TODO: implement the possibility of community-currated lists of exceptions 55 | // See https://pagure.io/JShelter/webextension/issue/20 56 | 57 | // Merge built-in and community-currated exceptions 58 | /// All domain tweaks that are not created by the local user. Usually, you should 59 | /// work with tweak_domains outside of this file and not the partial content like 60 | /// tweak_domains_builtin. 61 | var tweak_domains = tweak_domains_builtin; 62 | -------------------------------------------------------------------------------- /common/url.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Functions that handles working with URLs 3 | * 4 | * \author Copyright (C) 2018 Zbynek Cervinka 5 | * \author Copyright (C) 2019 Libor Polcak 6 | * \author Copyright (C) 2019 Martin Timko 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | 26 | /** 27 | * Get all sub domains for a domain. 28 | * 29 | * @param thisDomain Domain name string, e.g. www.fit.vutbr.cz 30 | * IPv4 address, e.g. 147.229.9.23 31 | * IPv6 address, e.g. 2001:67c:1220:809::93e5:917 32 | * 33 | * @returns List of strings representing all subdomains, including TLD. The 34 | * list starts with the most generic domain and continues with the more and 35 | * more specific domains. For example, www.fit.vutbr.cz -> [ "cz", "vutbr.cz", 36 | * "fit.vutbr.cz", "www.fit.vutbr.cz" ] 37 | */ 38 | function extractSubDomains(thisDomain) { 39 | var splitArr = thisDomain.split('.'); 40 | var arrLen = splitArr.length; 41 | // Check if the string is an IPv4 address 42 | if (arrLen == 4) { 43 | let correct = true; // initial value 44 | try { 45 | for (num of splitArr) { 46 | let octet = Number(num); 47 | if (octet !== octet /* NaN */ || octet < 0 || octet > 255) { 48 | correct = false; 49 | } 50 | } 51 | } 52 | catch (error) { 53 | correct = false; 54 | } 55 | if (correct === true) { 56 | return [thisDomain]; // It is an IPv4 address 57 | } 58 | } 59 | // Ignore the trailing "." 60 | if (splitArr[arrLen - 1] === "") { 61 | splitArr.pop(); 62 | arrLen -= 1; 63 | } 64 | if (arrLen === 0) { 65 | return [""]; 66 | } 67 | // Create the list of subdomains 68 | let domains = []; 69 | let subDomain = splitArr[arrLen - 1]; 70 | domains.push(subDomain); 71 | for (let i = arrLen - 2; i >= 0; i--) { 72 | subDomain = splitArr[i] + '.' + subDomain; 73 | domains.push(subDomain); 74 | } 75 | return domains; 76 | } 77 | -------------------------------------------------------------------------------- /common/wrappingS-BATTERY-CR.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Wrappers for Battery Status API 3 | * 4 | * \see https://www.w3.org/TR/battery-status/ 5 | * 6 | * \author Copyright (C) 2021 Libor Polčák 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | /** \file 26 | * \ingroup wrappers 27 | * 28 | * The `navigator.getBattery()` reports the state of the battery and can be 29 | * misused to fingerprint users for a short term. The API was removed from 30 | * Firefox, but is still supported in browsers derived from Chromium. 31 | * The wrapper mimics Firefox behaviour. 32 | * 33 | * \see 34 | * 35 | * \bug Because we mimic Firefox behaviour, a Chromium derived browser 36 | * becomes more easily fingerprintable. This can be fixed by properly 37 | * wrapping `BatteryManager.prototype` getters and setters. 38 | */ 39 | 40 | 41 | /* 42 | * Create private namespace 43 | */ 44 | (function() { 45 | var wrappers = [ 46 | { 47 | parent_object: "Navigator.prototype", 48 | parent_object_property: "getBattery", 49 | wrapped_objects: [], 50 | post_wrapping_code: [ 51 | { 52 | code_type: "delete_properties", 53 | parent_object: "Navigator.prototype", 54 | delete_properties: ["getBattery"], 55 | } 56 | ], 57 | }, 58 | { 59 | parent_object: "window", 60 | parent_object_property: "BatteryManager", 61 | wrapped_objects: [], 62 | post_wrapping_code: [ 63 | { 64 | code_type: "delete_properties", 65 | parent_object: "window", 66 | delete_properties: ["BatteryManager"], 67 | } 68 | ], 69 | }, 70 | ]; 71 | add_wrappers(wrappers); 72 | })(); 73 | -------------------------------------------------------------------------------- /common/wrappingS-BE.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Wrappers for that disables the Beacon API. 3 | * 4 | * \see https://www.w3.org/TR/beacon/ 5 | * 6 | * \author Copyright (C) 2021 Libor Polcak 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | /** \file 26 | * \ingroup wrappers 27 | * 28 | * The `navigator.sendBeacon()` method asynchronously sends a small 29 | * amount of data over HTTP to a web server. It is intended to be 30 | * used for sending analytics data to a web server. For more details 31 | * see the MDN docs on the [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API) and 32 | * [sendBeacon](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon). 33 | * 34 | * `navigator.sendBeacon` is the only method currently defined for the 35 | * Beacon API. 36 | */ 37 | 38 | /* 39 | * Create private namespace 40 | */ 41 | (function() { 42 | var wrappers = [ 43 | { 44 | parent_object: "Navigator.prototype", 45 | parent_object_property: "sendBeacon", 46 | wrapped_objects: [], 47 | helping_code: "", 48 | /// Although we should return false, we spoof returning true as ClearURL does 49 | wrapping_function_body: ` 50 | return true; 51 | `, 52 | }, 53 | ] 54 | add_wrappers(wrappers); 55 | })() 56 | -------------------------------------------------------------------------------- /common/wrappingS-HTML.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief This file contains wrapper that clears the window.name property 3 | * 4 | * \see https://developer.mozilla.org/en-US/docs/Web/API/Window/name 5 | * 6 | * \author Copyright (C) 2020 Martin Bednar, Libor Polcak 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | /** \file 26 | * \ingroup wrappers 27 | * 28 | * `window.name` provides a simple cross-origin tracking method of the same tab: 29 | * 30 | * ```js 31 | * window.name = "8pdRoEaQCpsjtC8w07dOy7xwXjXrHDyxxmPWBUxQKrh7xfJ4SYFH8QClp6U9T+Ypa8IEa5AwFw3x" 32 | * ``` 33 | * 34 | * Go to completely different web site and window.name stays the same. 35 | * 36 | * \see https://2019.www.torproject.org/projects/torbrowser/design/ provides a library build on 37 | * top of `window.name`: https://www.thomasfrank.se/sessionvars.html. 38 | * 39 | * \see https://html.spec.whatwg.org/#history-traversal; this feature should not be ncessary 40 | * for Firefox 86 or newer https://bugzilla.mozilla.org/show_bug.cgi?id=444222. 41 | */ 42 | 43 | /* 44 | * Create private namespace 45 | */ 46 | (function() { 47 | var wrappers = [ 48 | { 49 | parent_object: "window", 50 | parent_object_property: "name", 51 | wrapped_objects: [], 52 | helping_code: "/* window.name = ''; */", // we actually do this in level_cache.js on eTLD+1 domain changes 53 | }, 54 | ] 55 | add_wrappers(wrappers); 56 | })() 57 | -------------------------------------------------------------------------------- /common/wrappingS-HTML5.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief This file contains wrappers for HTML Audio and Video elements 3 | * 4 | * \see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType 5 | * 6 | * \author Copyright (C) 2022 Libor Polcak 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | /** \file 26 | * \ingroup wrappers 27 | * 28 | * Supported codecs (multimedia media types) can be misued for fingerprinting, 29 | * see for example the [FPMon paper](https://fpmon.github.io/fingerprinting-monitor/files/FPMON.pdf). 30 | * 31 | * JShelter provides two modes of protection: 32 | * 33 | * 1. Strict approach returns all media types as not supported. 34 | * 2. Modifies the output of probably/maybe supported codecs. 35 | */ 36 | 37 | /* 38 | * Create private namespace 39 | */ 40 | (function() { 41 | var wrappers = [ 42 | { 43 | parent_object: "HTMLMediaElement.prototype", 44 | parent_object_property: "canPlayType", 45 | wrapped_objects: [{ 46 | original_name: "HTMLMediaElement.prototype.canPlayType", 47 | wrapped_name: "origF", 48 | }], 49 | helping_code: `var approach = args[0];`, 50 | wrapping_function_args: "media, ...args", 51 | wrapping_function_body: ` 52 | if ((approach == 2) || (approach == 1)) { 53 | return ""; 54 | } 55 | else { 56 | var normalized = media.replace(/\s|\\n|\\t|\\r/g, ''); 57 | var origVal = origF.call(this, media); 58 | if (origVal === "") { 59 | return origVal; 60 | } 61 | else { 62 | var medcap_prng = alea(domainHash, "MediaCapabilities.prototype.encodingInfo", normalized); 63 | var rnd = medcap_prng.get_bits(1); 64 | if (rnd == 0) { 65 | return "probably"; 66 | } 67 | else { 68 | return "maybe"; 69 | } 70 | } 71 | } 72 | `, 73 | }, 74 | ] 75 | add_wrappers(wrappers); 76 | })() 77 | -------------------------------------------------------------------------------- /common/wrappingS-NET.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Wrappers for NetworkInformation 3 | * 4 | * \see https://wicg.github.io/netinfo/#networkinformation-interface 5 | * 6 | * \author Copyright (C) 2022 Libor Polcak 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | 26 | /** \file 27 | * This file contains a wrapper for [NetworkInformation](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation#specifications). 28 | * \ingroup wrappers 29 | * 30 | * NetworkInformation allows sites to learn about local network conditions by querying `navigator.connection`. 31 | * Fingerprinters can misuse the feature. Long-term observers may learn about traveling patterns 32 | * through observation of repeated values (for example a network at work, home, travel, etc.). 33 | * 34 | * We implement the same protection as Brave: https://github.com/brave/brave-browser/issues/20122. 35 | * 36 | * ``` 37 | * navigator.connection === undefined 38 | * "connection" in window.navigator === false 39 | * ``` 40 | */ 41 | 42 | /* 43 | * Create private namespace 44 | */ 45 | (function() { 46 | var wrappers = [ 47 | { 48 | parent_object: "Navigator.prototype", 49 | parent_object_property: "connection", 50 | wrapped_objects: [], 51 | post_wrapping_code: [ 52 | { 53 | code_type: "delete_properties", 54 | parent_object: "Navigator.prototype", 55 | delete_properties: ["connection"], 56 | } 57 | ], 58 | }, 59 | { 60 | parent_object: "window", 61 | parent_object_property: "NetworkInformation", 62 | wrapped_objects: [], 63 | post_wrapping_code: [ 64 | { 65 | code_type: "delete_properties", 66 | parent_object: "window", 67 | delete_properties: ["NetworkInformation"], 68 | } 69 | ], 70 | }, 71 | ]; 72 | add_wrappers(wrappers); 73 | })(); 74 | -------------------------------------------------------------------------------- /common/wrappingS-NFC.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Wrappers for Web NFC API 3 | * 4 | * \see https://w3c.github.io/web-nfc/ 5 | * 6 | * \author Copyright (C) 2022 Libor Polcak 7 | * 8 | * \license SPDX-License-Identifier: GPL-3.0-or-later 9 | */ 10 | // 11 | // This program is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | // 24 | 25 | 26 | /** \file 27 | * This file contains a wrapper for [Web NFC API](https://developer.mozilla.org/en-US/docs/Web/API/Web_NFC_API). 28 | * \ingroup wrappers 29 | * 30 | * This API is not broadly supported and we just disable all objects. 31 | */ 32 | 33 | /* 34 | * Create private namespace 35 | */ 36 | (function() { 37 | var wrappers = [ 38 | { 39 | parent_object: "window", 40 | parent_object_property: "NDEFMessage", 41 | wrapped_objects: [], 42 | post_wrapping_code: [ 43 | { 44 | code_type: "delete_properties", 45 | parent_object: "window", 46 | delete_properties: ["NDEFMessage"], 47 | } 48 | ], 49 | }, 50 | { 51 | parent_object: "window", 52 | parent_object_property: "NDEFReader", 53 | wrapped_objects: [], 54 | post_wrapping_code: [ 55 | { 56 | code_type: "delete_properties", 57 | parent_object: "window", 58 | delete_properties: ["NDEFReader"], 59 | } 60 | ], 61 | }, 62 | { 63 | parent_object: "window", 64 | parent_object_property: "NDEFRecord", 65 | wrapped_objects: [], 66 | post_wrapping_code: [ 67 | { 68 | code_type: "delete_properties", 69 | parent_object: "window", 70 | delete_properties: ["NDEFRecord"], 71 | } 72 | ], 73 | }, 74 | ]; 75 | add_wrappers(wrappers); 76 | })(); 77 | -------------------------------------------------------------------------------- /common/wrappingS-XR.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief This file contains wrappers for the current Virtual/Augmented Reality API (WebXR) 3 | * 4 | * \see https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API 5 | * \see https://immersive-web.github.io/webxr/ 6 | * 7 | * \author Copyright (C) 2021 Libor Polcak 8 | * 9 | * \license SPDX-License-Identifier: GPL-3.0-or-later 10 | */ 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | 26 | /** \file 27 | * \ingroup wrappers 28 | * 29 | * navigator.xr allows any page script to learn the VR displays attached 30 | * to the computer and more. 31 | * 32 | * U. Iqbal, S. Englehardt and Z. Shafiq, "Fingerprinting the 33 | * Fingerprinters: Learning to Detect Browser Fingerprinting Behaviors," 34 | * in 2021 2021 IEEE Symposium on Security and Privacy (SP), San Francisco, 35 | * CA, US, 2021 pp. 283-301 observed 36 | * (https://github.com/uiowa-irl/FP-Inspector/blob/master/Data/potential_fingerprinting_APIs.md) 37 | * that the orginal WebVR API is used in the wild to fingerprint users. As it is 38 | * likely that only a minority of users have a VR display connected and the API 39 | * provides additional information on the HW, it is likely that users with 40 | * a VR display connected are easily fingerprintable. 41 | * 42 | * As all the API calls are accessible through the navigator.xr API, we provide 43 | * a single mitigation. We disable the API completely. This might need to be 44 | * revised once this API is commonly enabled in browsers. 45 | */ 46 | 47 | (function() { 48 | var wrappers = [ 49 | { 50 | parent_object: "Navigator.prototype", 51 | parent_object_property: "xr", 52 | wrapped_objects: [], 53 | helping_code: "", 54 | post_wrapping_code: [ 55 | { 56 | code_type: "delete_properties", 57 | parent_object: "Navigator.prototype", 58 | delete_properties: ["xr"], 59 | } 60 | ], 61 | }, 62 | ] 63 | add_wrappers(wrappers); 64 | })() 65 | -------------------------------------------------------------------------------- /firefox/levels_browser.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Modifies the levels.js data structures to accomodate for Firefox-specific configuration 3 | * 4 | * \author Copyright (C) 2022 Libor Polcak 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // This program is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | var modify_wrapping_groups = function() { 23 | wrapping_groups.groups.forEach(function (group) { 24 | if (group.name === "windowname") { 25 | group.description2.push(browser.i18n.getMessage("jssgroupPersistentIdentifierOfTheBrowserTabFirefox88")) 26 | } 27 | else if (group.name === "wasm") { 28 | group.params = [ 29 | { 30 | short: browser.i18n.getMessage("jssgroupWASMDisabled"), 31 | description: browser.i18n.getMessage("jssgroupWASMDisabledDescription"), 32 | config: [0], 33 | }, 34 | { 35 | short: browser.i18n.getMessage("jssgroupWASMEnabled"), 36 | description: browser.i18n.getMessage("jssgroupWASMEnabledDescription"), 37 | config: [1], 38 | }, 39 | ]; 40 | } 41 | }); 42 | }; 43 | var modify_builtin_levels = function() { 44 | delete level_2.windowname; 45 | delete level_3.windowname; 46 | } 47 | -------------------------------------------------------------------------------- /firefox/manifest.json.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019 Martin Timko 2 | // SPDX-FileCopyrightText: 2021 Giorgio Maone 3 | // 4 | // SPDX-License-Identifier: GPL-3.0-or-later 5 | -------------------------------------------------------------------------------- /firefox/options_nbs.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Code that handles NBS options specific to Firefox 3 | * 4 | * \author Copyright (C) 2023 Libor Polcak 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | var fragment = document.createRange().createContextualFragment(` 24 |

${browser.i18n.getMessage("NBSHttpProxyDNSAPINote")}

25 | `); 26 | var nbs_description_div = document.querySelector("#proxy-protection-config .nbs_description:last-of-type"); 27 | nbs_description_div.appendChild(fragment); 28 | -------------------------------------------------------------------------------- /fix_manifest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # JavaScript Restrictor is a browser extension which increases level 4 | # of security, anonymity and privacy of the user while browsing the 5 | # internet. 6 | # 7 | # Copyright (C) 2019-2022 Libor Polcak 8 | # 9 | # SPDX-License-Identifier: GPL-3.0-or-later 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | # 24 | 25 | pushd $1 26 | WRAPPING=`ls wrapping*.js | sort | awk '{ print "\"" $0 "\"" }' | tr '\n' ',' | sed 's/,$//'` 27 | sed -i -e "s/WRAPPING/${WRAPPING}/" manifest.json service_worker.js 28 | popd 29 | 30 | -------------------------------------------------------------------------------- /fix_wasm_farbling.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # JavaScript Restrictor is a browser extension which increases level 4 | # of security, anonymity and privacy of the user while browsing the 5 | # internet. 6 | # 7 | # Copyright (C) 2025 Libor Polcak 8 | # 9 | # SPDX-License-Identifier: GPL-3.0-or-later 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | # 24 | 25 | DEBUG="$1" 26 | BROWSER="$2" 27 | 28 | if [ "$DEBUG" -eq 0 ] 29 | then 30 | WASM_FILE=wasm/build/release.wasm 31 | else 32 | WASM_FILE=wasm/build/debug.wasm 33 | fi 34 | 35 | if [ "$BROWSER" = "firefox" ] 36 | then 37 | cp "$WASM_FILE" build/firefox/farble.wasm 38 | else 39 | pushd build/chrome 40 | patch -p1 < code_builders.patch 41 | rm code_builders.patch 42 | popd 43 | sed --in-place "s~__WASM_CODE_DURING_BUILD__~`base64 --wrap=0 $WASM_FILE `~" build/chrome/code_builders.js 44 | fi 45 | -------------------------------------------------------------------------------- /generate_fpd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # JavaScript Restrictor is a browser extension which increases level 4 | # of security, anonymity and privacy of the user while browsing the 5 | # internet. 6 | # 7 | # Copyright (C) 2021 Marek Salon 8 | # 9 | # SPDX-License-Identifier: GPL-3.0-or-later 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | # 24 | 25 | SED=`command -v gsed` 26 | if [ -z "$SED" ] 27 | then 28 | if [ "$(uname)" == "Darwin" -o "$(uname)" == "FreeBSD" ]; then 29 | echo "WARNING: Please install GNU sed if this script fails" 30 | fi 31 | SED=`command -v sed` 32 | fi 33 | 34 | $SED -i "/.*\/\/DEF_FPD_FILES_S.*/,/.*\/\/DEF_FPD_FILES_E.*/{/.*\/\/DEF_FPD_FILES_S.*/!{/.*\/\/DEF_FPD_FILES_E.*/!d}}" $1/fp_levels.js 35 | 36 | CONFIG_FILES=`find common/fp_config/* -maxdepth 0 -name "*.json"` 37 | ACC="" 38 | for FILE in $CONFIG_FILES 39 | do 40 | ACC="${ACC}\"`basename ${FILE} .json`\"" 41 | ACC="${ACC}, " 42 | done 43 | 44 | $SED -i "/.*\/\/DEF_FPD_FILES_S.*/a var fp_config_files = [${ACC::-2}]" $1/fp_levels.js 45 | -------------------------------------------------------------------------------- /logos_images/store_imgs/chrome5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/chrome5.png -------------------------------------------------------------------------------- /logos_images/store_imgs/chrome5.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/chstore1.png -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore1.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/chstore2.png -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore2.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/chstore3.png -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore3.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/chstore4.png -------------------------------------------------------------------------------- /logos_images/store_imgs/chstore4.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/firefox1.png -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox1.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/firefox2.png -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox2.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/firefox3.png -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox3.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/firefox4.png -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox4.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/firefox5.png -------------------------------------------------------------------------------- /logos_images/store_imgs/firefox5.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/geolocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/geolocation.png -------------------------------------------------------------------------------- /logos_images/store_imgs/geolocation.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/geolocation_resized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/geolocation_resized.png -------------------------------------------------------------------------------- /logos_images/store_imgs/geolocation_resized.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Libor Polčák 2 | // SPDX-FileCopyrightText: 2020 Martin Bednář 3 | // 4 | // SPDX-License-Identifier: GPL-3.0-or-later 5 | -------------------------------------------------------------------------------- /logos_images/store_imgs/opera1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/opera1.png -------------------------------------------------------------------------------- /logos_images/store_imgs/opera1.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/opera2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/opera2.png -------------------------------------------------------------------------------- /logos_images/store_imgs/opera2.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /logos_images/store_imgs/opera3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/logos_images/store_imgs/opera3.png -------------------------------------------------------------------------------- /logos_images/store_imgs/opera3.png.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Libor Polčák 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /make_release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # JavaScript Restrictor is a browser extension which increases level 4 | # of security, anonymity and privacy of the user while browsing the 5 | # internet. 6 | # 7 | # Copyright (C) 2023 Libor Polcak 8 | # 9 | # SPDX-License-Identifier: GPL-3.0-or-later 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | # 24 | 25 | 26 | # This file deals with the issue raised in: 27 | # https://pagure.io/JShelter/webextension/issue/82 28 | # and further discussed in https://pagure.io/pagure/issue/5378 29 | # 30 | # This file expects a single parameter - the tag 31 | 32 | if [ $# -ne 1 ]; 33 | then 34 | echo "Please provide a single argument that is the tag in the JShelter repository" 35 | exit 1 36 | fi 37 | 38 | DIR=jshelter-$1 39 | 40 | git clone https://pagure.io/JShelter/webextension.git --branch $1 --depth 1 --recurse-submodules --shallow-submodules "$DIR" 41 | rm -rf $DIR/.git* $DIR/*/.git* 42 | zip -r jshelter-$1.zip $DIR 43 | tar czf jshelter-$1.tar.gz $DIR 44 | pushd "$DIR" 45 | make 46 | popd 47 | mv "$DIR/jshelter_firefox.zip" jshelter-$1-firefox.zip 48 | mv "$DIR/jshelter_chrome.zip" jshelter-$1-chrome.zip 49 | -------------------------------------------------------------------------------- /tests/benchmark/avfarbling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Benchmark 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Benchmark

13 |
14 | 15 |

Canvas fingerprinting

16 | 17 |

Make sure to disable Time precision wrappers of JSS to receive valid results in the 18 | console.

19 | 20 |
21 |

Canvas frame

22 | 23 |
24 | 25 |
26 | 27 |

Audio

28 | 29 | 30 |
31 |

3D canvas

32 | 33 |
34 | 35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/benchmark/files/global.css: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019 Martin Timko 3 | * SPDX-FileCopyrightText: 2021 Matúš Švancár 4 | * 5 | * SPDX-License-Identifier: GPL-3.0-or-later 6 | */ 7 | 8 | body { 9 | font-family: Arial, Helvetica, sans-serif; 10 | } 11 | 12 | h1 { 13 | font-size: 36px; 14 | } 15 | 16 | button { 17 | font-size: 14px; 18 | font-weight: bold; 19 | cursor: pointer; 20 | } 21 | 22 | #canvas-wrap-1 button, 23 | #canvas-wrap-2 button { 24 | width: 300px; 25 | height: 28px; 26 | float: right; 27 | clear: both; 28 | } 29 | 30 | #getData { 31 | height: 28px; 32 | } 33 | 34 | .bottom-buttons-wrap button { 35 | width: 400px; 36 | height: 50px; 37 | } 38 | 39 | #demo-image , #fp-image{ 40 | display: none; 41 | } 42 | 43 | canvas { 44 | border: 1px solid #000000; 45 | } 46 | 47 | .flex { 48 | display: flex; 49 | } 50 | .flex *{ 51 | padding-right: 10px; 52 | } 53 | .hide{ 54 | display:none; 55 | } 56 | #precisionList li span { 57 | float: left; 58 | width: 320px; 59 | } 60 | #audio_results div { 61 | overflow: hidden; 62 | } 63 | -------------------------------------------------------------------------------- /tests/common_files/scripts/build_JSR_package.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2021 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | # Go to root directory of JShelter project. 25 | cd ..\..\..\ 26 | 27 | # Create directory for JShelter package if does not exists. Like "touch" on Linux. 28 | New-Item -ItemType Directory -Path ".\tests\common_files\JShelter" -Force 29 | 30 | # Create xpi package of JShelter for Mozilla Firefox from zip archive created by make. 31 | Copy-Item ".\jshelter_firefox.zip" -Destination ".\tests\common_files\JShelter\firefox.xpi" -Force 32 | 33 | $JShelterPath = Get-Location 34 | 35 | # Get path to chrome.exe. 36 | $Chrome = "C:\Program Files\Google\Chrome\Application" 37 | if (-Not (Test-Path $Chrome\chrome.exe -PathType Leaf)) { 38 | Write-Host 39 | $Chrome = Read-Host -Prompt 'Enter path into directory, where is chrome.exe stored' 40 | if (-Not (Test-Path $Chrome\chrome.exe -PathType Leaf)) { 41 | Write-Error -Message "Entered path ${Chrome} is not valid path into directory." 42 | } 43 | } 44 | cd $Chrome 45 | 46 | # Create crx package of JShelter for Google Chrome from source files. 47 | # | Out-Null force PowerShell to wait when packaging by Chorme is completed. 48 | .\chrome.exe --pack-extension=$JShelterPath\build\chrome | Out-Null 49 | cd $JShelterPath 50 | 51 | # Remove unnecessary file created during crx package creating. 52 | Remove-Item ".\build\chrome.pem" -Recurse -Force 53 | 54 | # Move crx package of JSR to right location (same as xpi package of JShelter). 55 | Move-Item ".\build\chrome.crx" -Destination .\tests\common_files\JShelter\chrome.crx -Force 56 | 57 | # Go back to common scripts directory. 58 | cd .\tests\common_files\scripts 59 | -------------------------------------------------------------------------------- /tests/common_files/scripts/build_JSR_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # JShelter is a browser extension which increases level 5 | # of security, anonymity and privacy of the user while browsing the 6 | # internet. 7 | # 8 | # Copyright (C) 2020 Martin Bednar 9 | # 10 | # SPDX-License-Identifier: GPL-3.0-or-later 11 | # 12 | # This program is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # This program is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with this program. If not, see . 24 | # 25 | 26 | FIREFOX_XPI_PATH="./tests/common_files/JShelter/firefox.xpi" 27 | CHROME_CRX_PATH="./tests/common_files/JShelter/chrome.crx" 28 | 29 | # Go to root directory of JShelter project. 30 | cd ../../../ 31 | 32 | # Set executable permission. 33 | chmod +x ./fix_manifest.sh 34 | 35 | # Clean previous build. 36 | make clean 37 | 38 | # Build. 39 | make 40 | 41 | # Create directory for JShelter package if does not exists. 42 | mkdir -p ./tests/common_files/JShelter 43 | rm -f "$FIREFOX_XPI_PATH" "$CHROME_CRX_PATH" 44 | 45 | # Create xpi package of JShelter for Mozilla Firefox from zip archive created by make. 46 | cp -f ./jshelter_firefox.zip "$FIREFOX_XPI_PATH" 47 | 48 | # Create crx package of JShelter for Google Chrome from source files. 49 | if command -v google-chrome &> /dev/null 50 | then 51 | google-chrome --pack-extension=./build/chrome >/dev/null 2>&1 52 | EXIT="$?" 53 | if [ "$EXIT" != "0" ]; then 54 | echo "ERROR!!! Cannot pack extension" >&2 55 | exit $EXIT 56 | fi 57 | else 58 | chromium --pack-extension=./build/chrome >/dev/null 2>&1 59 | EXIT="$?" 60 | if [ "$EXIT" != "0" ]; then 61 | echo "ERROR!!! Cannot pack extension" >&2 62 | exit $EXIT 63 | fi 64 | fi 65 | 66 | # Remove unnecessary file created during crx package creating. 67 | rm -rf ./build/chrome.pem 68 | 69 | # Move crx package of JShelter to right location (same as xpi package of JShelter). 70 | mv -f ./build/chrome.crx "$CHROME_CRX_PATH" 71 | 72 | # Go back to common scripts directory. 73 | cd ./tests/common_files/scripts 74 | -------------------------------------------------------------------------------- /tests/common_files/webbrowser_drivers/DOWNLOAD WEB DRIVERS HERE.md: -------------------------------------------------------------------------------- 1 | ## Download web browser drivers 2 | 3 | For Google Chrome download the ChromeDriver from [download page](https://chromedriver.chromium.org/downloads). 4 | Select the version coresponding to the version of your Google Chrome web browser. If you download an incompatible version, you will see an error during starting tests. 5 | Download the correct ChromeDriver to folder `../common_files/webbrowser_drivers` with name `chromedriver.exe` (for Windows) or `chromedriver` (for Linux). 6 | 7 | For Mozilla Firefox download the GeckoDriver from [download page](https://github.com/mozilla/geckodriver/releases). 8 | Select the version coresponding to the version of your Mozilla Firefox web browser (typically the newest version). If you download an incompatible version, you will see an error during starting tests. 9 | Download the correct GeckoDriver to folder `../common_files/webbrowser_drivers` with name `geckodriver.exe` (for Windows) or `geckodriver` (for Linux). -------------------------------------------------------------------------------- /tests/fpd_tests/common/helpers.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Contains helping methods for FPD test suite 3 | * 4 | * \author Copyright (C) 2021 Marek Salon 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | function updateDoc(result) { 24 | var parent = document.getElementById("result"); 25 | for (let resource of Object.keys(result)) { 26 | var html = "

" + resource + ""; 27 | for (let method of Object.keys(result[resource])) { 28 | html += "
" + method +": " + result[resource][method] + ""; 29 | } 30 | html += "

"; 31 | 32 | var element = document.createElement('div'); 33 | element.id = resource.replaceAll('.', ''); 34 | element.innerHTML += html; 35 | parent.appendChild(element); 36 | } 37 | } 38 | 39 | function addWrapper(wrappers, resource, method, number) { 40 | wrappers[resource] = wrappers[resource] || {}; 41 | wrappers[resource][method] = wrappers[resource][method] || 0; 42 | wrappers[resource][method] += number; 43 | } 44 | 45 | function messageExtension(test) { 46 | window.top.postMessage({ 47 | fpdTest: test 48 | }, "*"); 49 | } -------------------------------------------------------------------------------- /tests/fpd_tests/common/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Fingerprint Detector 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /tests/fpd_tests/common/worker.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Web worker code used in FPD test 3 | * 4 | * \author Copyright (C) 2021 Marek Salon 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | importScripts('helpers.js'); 24 | //SCRIPTS_S 25 | //SCRIPTS_E 26 | 27 | var resultsAcc = {}; 28 | //CALL_S 29 | //CALL_E 30 | postMessage(resultsAcc); -------------------------------------------------------------------------------- /tests/fpd_tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Fingerprint Detector Tests 10 | 11 | 12 | 13 | 58 | 59 | 60 |

Choose test variant

61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 |

70 |
71 | 72 |
73 |
74 | 75 | -------------------------------------------------------------------------------- /tests/fpd_tests/tests/custom.js: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Example of custom FPD test file 3 | * 4 | * \author Copyright (C) 2021 Marek Salon 5 | * 6 | * \license SPDX-License-Identifier: GPL-3.0-or-later 7 | */ 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | // definition of test function must have "test_" prefix and "wrappers" parameter 24 | function test_canvasFp(wrappers) { 25 | // wrap function body to try-catch construction - count only successful accesses 26 | try { 27 | var canvas = document.createElement('canvas'); 28 | canvas.height = 60; 29 | canvas.width = 400; 30 | var canvasContext = canvas.getContext('2d'); 31 | canvas.style.display = 'inline'; 32 | canvasContext.textBaseline = 'alphabetic'; 33 | canvasContext.fillStyle = '#f60'; 34 | canvasContext.fillRect(125, 1, 62, 20); 35 | canvasContext.fillStyle = '#069'; 36 | canvasContext.font = '11pt no-real-font-123'; 37 | canvasContext.fillText("co ja viem, \uD83D\uDE03", 2, 15); 38 | canvasContext.font = 'bold 48px serif'; 39 | 40 | // end of function - have to specify all function accesses to resources that supposed to be wrapped and tested 41 | // use 'addWrapper' method like here: 42 | addWrapper(wrappers, "CanvasRenderingContext2D.prototype.fillStyle", "set", 2); 43 | addWrapper(wrappers, "CanvasRenderingContext2D.prototype.fillText", "call", 1); 44 | addWrapper(wrappers, "CanvasRenderingContext2D.prototype.font", "set", 2); 45 | addWrapper(wrappers, "CanvasRenderingContext2D.prototype.textBaseline", "set", 1); 46 | addWrapper(wrappers, "CanvasRenderingContext2D.prototype.fillRect", "call", 1); 47 | } 48 | catch {} 49 | } -------------------------------------------------------------------------------- /tests/integration_tests/testing/conftest.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # Copyright (C) 2021 Matus Svancar 8 | # 9 | # SPDX-License-Identifier: GPL-3.0-or-later 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with this program. If not, see . 23 | # 24 | 25 | import pytest 26 | 27 | from web_browser_shared import get_shared_browser 28 | import values_expected 29 | 30 | 31 | ## This module is automatically called by pytest before start executing tests. 32 | # 33 | # It contains setup method that are called before tests executing. 34 | # Here is defined variables browser and expected that are given to tests as a parameter. 35 | 36 | 37 | ## Setup method. browser provide shared browser to all tests. 38 | @pytest.fixture(scope="session", autouse=True) 39 | def browser(): 40 | return get_shared_browser() 41 | 42 | ## Setup method: expected provide expected values to all tests. 43 | # 44 | # expected values are selected based on testing jsr_level. 45 | @pytest.fixture(scope="session", autouse=True) 46 | def expected(): 47 | if get_shared_browser().jsr_level == 0: 48 | return values_expected.level0 49 | elif get_shared_browser().jsr_level == 1: 50 | return values_expected.level1 51 | elif get_shared_browser().jsr_level == 2: 52 | return values_expected.level2 53 | elif get_shared_browser().jsr_level == 3: 54 | return values_expected.level3 55 | elif get_shared_browser().jsr_level == "Experiment": 56 | return values_expected.level3 57 | else: 58 | return values_expected.level3 59 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/output.py: -------------------------------------------------------------------------------- 1 | # 2 | # JavaScript Restrictor is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from web_browser_type import BrowserType 25 | 26 | 27 | ## Print outputs during testing - called from start.py. 28 | 29 | 30 | def print_testing_header(browser_type, jsr_level): 31 | extra_dash = '' 32 | if browser_type == BrowserType.CHROME: 33 | extra_dash = '-' 34 | print() 35 | print("--------------------------------------------------------------------------") 36 | print("--------------------------------------------------------------------------") 37 | print("--------------- TESTING <" + browser_type.name + ", JShelter level = " + str(jsr_level) + "> STARTED --------------" + extra_dash) 38 | print() 39 | 40 | 41 | def print_testing_footer(browser_type, jsr_level): 42 | extra_dash = '' 43 | if browser_type == BrowserType.CHROME: 44 | extra_dash = '-' 45 | print() 46 | print("--------------- TESTING <" + browser_type.name + ", JShelter level = " + str(jsr_level) + "> FINISHED --------------" + extra_dash) 47 | print("--------------------------------------------------------------------------") 48 | print("--------------------------------------------------------------------------") 49 | print() 50 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/start.py: -------------------------------------------------------------------------------- 1 | # 2 | # JavaScript Restrictor is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import pytest 25 | import output 26 | 27 | from web_browser import Browser 28 | from web_browser_type import BrowserType 29 | from web_browser_shared import set_shared_browser 30 | from configuration import get_config 31 | 32 | 33 | ## Main module - it starts and control testing. 34 | # 35 | # To start testing call this module from PowerShell, CommandPrompt, Terminal or Bash: python start.py 36 | # For every browser and for every jsr_level defined in configuration.py set of all tests is run. 37 | def main(): 38 | # For every browser from configuration.py run set of test. 39 | for browser_type in get_config("tested_browsers"): 40 | # create new browser of given type (Chrome, Firefox, etc.) 41 | my_browser = Browser(browser_type) 42 | # set current browser as shared browser for all testing levels (do not create new browser 43 | # for every JShelter_level) 44 | set_shared_browser(my_browser) 45 | # for every browser from configuration.py run set of test. 46 | for jsr_level in get_config("tested_jsr_levels"): 47 | output.print_testing_header(browser_type, jsr_level) 48 | # set jsr_level to given level 49 | my_browser.jsr_level = jsr_level 50 | # run set of tests 51 | pytest.main(['-s']) 52 | output.print_testing_footer(browser_type, jsr_level) 53 | # Close browser. 54 | my_browser.quit() 55 | 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/tests_definition/test_02_NBS_setting.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2022 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import pytest 25 | from selenium.webdriver.common.by import By 26 | from time import sleep 27 | from web_browser_type import BrowserType 28 | 29 | 30 | def switch_NBS_setting(browser): 31 | browser.driver.get(browser._jsr_options_page.replace("/options.html", "/popup.html")) 32 | sleep(1) 33 | browser.driver.find_elements(By.CLASS_NAME, 'slider')[1].click() 34 | sleep(1) 35 | 36 | 37 | def get_NBS_setting(browser): 38 | browser.driver.get(browser._jsr_options_page.replace("/options.html", "/popup.html")) 39 | sleep(2) 40 | return(browser.driver.execute_script("return window.getComputedStyle(document.querySelector('#nbs_whitelist .switch_wrapper .switch .slider'),':before').getPropertyValue('content')")) 41 | 42 | 43 | ## Test turnning NBS off in popup. 44 | ## Sleep 0.5 second to changes take effect. 45 | def test_switching_NBS(browser): 46 | if browser.type == BrowserType.CHROME: 47 | # Not able to test NBS switch in Google Chrome. 48 | # Can not show popup.html in Chrome. Popup.html is not accesible and testable. 49 | return 50 | NBS_setting_values = ['"ON"', '"OFF"'] 51 | 52 | original_setting = get_NBS_setting(browser) 53 | original_setting_index = NBS_setting_values.index(original_setting) 54 | 55 | # Range is saing how many times should NBS be switched. 56 | for i in range(4): 57 | switch_NBS_setting(browser) 58 | assert get_NBS_setting(browser) == NBS_setting_values[(i + 1 + original_setting_index) % 2] 59 | 60 | # Return original value 61 | if get_NBS_setting(browser) != original_setting: 62 | switch_NBS_setting(browser) 63 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/tests_definition/test_06_performance.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import time 25 | import random 26 | 27 | from math_operations import is_in_accuracy 28 | 29 | 30 | ## Test performance. 31 | def test_performance(browser, expected): 32 | is_performance_rounded = True 33 | # Make 3 measurement. 34 | for _ in range(3): 35 | # Wait a while to value of performance will be changed. 36 | time.sleep(random.randint(1, 3)) 37 | performance = browser.driver.execute_script("return window.performance.now()") 38 | if expected.performance['accuracy'] == 'EXACTLY': 39 | if int(performance / 10) * 10 != performance: 40 | # Performance was not rounded. At least one of three measurement has to say value was not rounded. 41 | is_performance_rounded = False 42 | else: 43 | assert is_in_accuracy(performance, expected.performance['accuracy']) 44 | 45 | if expected.performance['accuracy'] == 'EXACTLY': 46 | # At least one of three measurement has to say value was not rounded. 47 | # is_performance_rounded should be false if EXACTLY value is required. 48 | assert not is_performance_rounded 49 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/tests_definition/test_09_toString.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2021 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import pytest 25 | 26 | from values_getters import get_methods_toString 27 | 28 | 29 | ## Setup method - it is run before toString tests execution starts. 30 | # 31 | # This setup method initialize variable methods_toString that contains methods.toString() and 32 | # this variable is provided to methods_toString test and the methods.toString() in the variable are compared with real values. 33 | @pytest.fixture(scope='module', autouse=True) 34 | def methods_toString(browser): 35 | return get_methods_toString(browser.driver) 36 | 37 | 38 | ## Test methods.toString(). They should be always unchanged by JShelter. 39 | def test_methods_toString(browser, methods_toString): 40 | for method in methods_toString: 41 | assert methods_toString[method] == browser.real.methods_toString[method] 42 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/web_browser_shared.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from web_browser_type import BrowserType 25 | from web_browser import Browser 26 | 27 | 28 | ## During testing multiple levels of JShelter are tested. 29 | # Variable _shared_browser is for testing all levels of JShelter in one browser. 30 | # If _shared_browser would not exists, a new browser for every tests set has to be created. 31 | # Shared browser can save time of creating new browser because one browser is reused for more tested JST levels. 32 | # Use getter and setter. Do not acces directly private variable _shared_browser. 33 | _shared_browser = None 34 | 35 | 36 | ## Setter for _shared_browser. 37 | def set_shared_browser(browser): 38 | global _shared_browser 39 | _shared_browser = browser 40 | 41 | 42 | ## Getter for _shared_browser. 43 | def get_shared_browser(): 44 | global _shared_browser 45 | return _shared_browser 46 | -------------------------------------------------------------------------------- /tests/integration_tests/testing/web_browser_type.py: -------------------------------------------------------------------------------- 1 | # 2 | # JavaScript Restrictor is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from enum import Enum 25 | 26 | 27 | ## Types of browser in which tests can be run. 28 | class BrowserType(Enum): 29 | FIREFOX = 1 30 | CHROME = 2 31 | -------------------------------------------------------------------------------- /tests/system_tests/analyze_data/io_funcs.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import os 25 | import json 26 | 27 | 28 | ## Delete file given by path if exists. 29 | def delete_file_if_exists(path): 30 | if os.path.exists(path): 31 | os.remove(path) 32 | 33 | 34 | ## Test if given name belongs to directory. Return True or False. 35 | def is_dir(folder_name): 36 | path_prefix = "../data/screenshots" 37 | folder_path = os.path.join(path_prefix, folder_name) 38 | if os.path.isdir(folder_path): 39 | return True 40 | 41 | 42 | ## Read and loads JSON file. Return dictionary with loaded data. 43 | def get_json_file_content(path): 44 | data = [] 45 | try: 46 | f = open(path, 'r', newline='') 47 | data = json.loads(f.read()) 48 | f.close() 49 | except: 50 | print("File " + path + " not exists or it is not accessible for reading. If you are trying analyze logs, you have to generate them first.") 51 | finally: 52 | return data 53 | 54 | 55 | ## Write string content to file given by path. 56 | def write_file(path, content): 57 | with open(path, 'w', newline='') as f: 58 | f.write(content) 59 | -------------------------------------------------------------------------------- /tests/system_tests/analyze_data/levenshtein_distance.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | import Levenshtein 25 | 26 | ## Check if log was added by JShelter. Check with Levenshtein distance method. 27 | def was_log_added(log, logs_without_jsr): 28 | for log_without_jsr in logs_without_jsr: 29 | if log_without_jsr['level'] == log['level']: 30 | if log_without_jsr['source'] == log['source']: 31 | # When logs have the same level and the same source, let's check if they have similar message too. 32 | # This check is based on Levenshtein distance. 33 | # It tells how many characters is needed to change to convert first string to second one. 34 | levenshtein_dst = Levenshtein.distance(log_without_jsr['message'], log['message']) 35 | # Get length of longer message because of calculating percentage similarity. 36 | message_length = max(len(log_without_jsr['message']), len(log['message'])) 37 | # How many percent of strings are similar 38 | percentage_similarity = (message_length - levenshtein_dst) / message_length 39 | if percentage_similarity > 0.6: 40 | # If similarity of logs is too high, tested log was not added by JShelter. 41 | # It is issue already existing in page even without JShelter. 42 | return False 43 | return True 44 | -------------------------------------------------------------------------------- /tests/system_tests/analyze_data/simple_comparison.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | ## Check if log was added by JShelter. Check with Simple method (equality of text strings). 25 | def was_log_added(log, logs_without_jsr): 26 | for log_without_jsr in logs_without_jsr: 27 | if log_without_jsr['level'] == log['level']: 28 | if log_without_jsr['source'] == log['source']: 29 | if log_without_jsr['message'] == log['message']: 30 | return False 31 | return True 32 | -------------------------------------------------------------------------------- /tests/system_tests/get_data/grid.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from subprocess import Popen 25 | from time import sleep 26 | 27 | from configuration import Config 28 | 29 | 30 | ## Start Selenium Grid server as a new process on background. 31 | def start_server(): 32 | start_server_command = ['java', '-jar', Config.selenium_server_jar_path, 'hub'] 33 | server = Popen(start_server_command) 34 | sleep(6) 35 | return server 36 | 37 | 38 | ## Start Selenium Grid Nodes as a new processes. 39 | def start_nodes(): 40 | start_node_command = ['java', '-Dwebdriver.chrome.driver=' + Config.chrome_driver_path, '-jar', Config.selenium_server_jar_path, 'node', '--hub', 'https://' + Config.grid_server_ip_address + ':4444/grid/register/'] 41 | nodes = [] 42 | if Config.number_of_grid_nodes_on_this_device == 0: 43 | # Waiting on distributed environment when all Selenium Grid nodes will be running. 44 | input("When all testing nodes will be running, press Enter to start JShelter system testing.") 45 | else: 46 | for node_number in range(Config.number_of_grid_nodes_on_this_device): 47 | nodes.append(Popen(start_node_command)) 48 | sleep(7) 49 | return nodes 50 | 51 | 52 | ## End nodes when testing is finished. 53 | def end_nodes(nodes, manually): 54 | if manually: 55 | input("After testing, press Enter to end the nodes.") 56 | for node in nodes: 57 | node.kill() 58 | 59 | 60 | ## End Selenium Grid server when testing is finished and all nodes are terminated. 61 | def end_server(server): 62 | server.kill() 63 | -------------------------------------------------------------------------------- /tests/system_tests/get_data/test_type.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from enum import Enum 25 | 26 | 27 | ## Types of tests in which tests can be perform. 28 | class TestType(Enum): 29 | LOGS = 1 30 | SCREENSHOTS = 2 31 | -------------------------------------------------------------------------------- /tests/system_tests/get_data/web_browser_type.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from enum import Enum 25 | 26 | 27 | ## Types of browsers in which tests can be perform. 28 | class BrowserType(Enum): 29 | def __str__(self): 30 | return str(self.name).title() 31 | 32 | CHROME = 1 33 | -------------------------------------------------------------------------------- /tests/system_tests/get_data/website.py: -------------------------------------------------------------------------------- 1 | # 2 | # JShelter is a browser extension which increases level 3 | # of security, anonymity and privacy of the user while browsing the 4 | # internet. 5 | # 6 | # Copyright (C) 2020 Martin Bednar 7 | # 8 | # SPDX-License-Identifier: GPL-3.0-or-later 9 | # 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | # 23 | 24 | from json import dumps 25 | 26 | 27 | ## From the class Logs object for every website is created. One object contains logs from browsers 28 | with and without JShelter 29 | # when the same page is loaded. 30 | class Logs: 31 | site = '' 32 | logs_without_jsr = [] 33 | logs_with_jsr = [] 34 | 35 | def __init__(self, site, logs_without_jsr, logs_with_jsr): 36 | self.site = site 37 | self.logs_without_jsr = logs_without_jsr 38 | self.logs_with_jsr = logs_with_jsr 39 | 40 | def to_json(self): 41 | return '{"site": "' + self.site + '", "logs_without_jsr": ' + dumps(self.logs_without_jsr) + ', "logs_with_jsr": ' + dumps(self.logs_with_jsr) + '}' 42 | -------------------------------------------------------------------------------- /tests/system_tests/setup_buildJSR_runTests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # JShelter is a browser extension which increases level 5 | # of security, anonymity and privacy of the user while browsing the 6 | # internet. 7 | # 8 | # Copyright (C) 2020 Martin Bednar 9 | # 10 | # SPDX-License-Identifier: GPL-3.0-or-later 11 | # 12 | # This program is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # This program is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with this program. If not, see . 24 | # 25 | 26 | # Handle errors. 27 | # Function called by trap before exit caused by error. 28 | function beforeExit { 29 | if [ $retVal -ne 0 ]; then 30 | echo "\"${last_command}\" command failed with exit code $?." 31 | echo 32 | echo "An error noticed during setup the test environment. System tests can not be started. Look at the README file and follow instructions to run the setup again." 33 | fi 34 | exit $retVal 35 | } 36 | # exit when any command fails 37 | set -euo pipefail 38 | # Call function before exit caused by error. 39 | trap beforeExit EXIT 40 | 41 | # Go to common scripts directory. 42 | cd ../common_files/scripts 43 | 44 | # Set executable permissions. 45 | chmod +x ./build_JSR_package.sh 46 | chmod +x ../webbrowser_drivers/chromedriver 47 | 48 | # Run script build_JSR_package.sh 49 | ./build_JSR_package.sh 50 | 51 | # Go back to integration_tests directory. 52 | cd ../../system_tests 53 | 54 | # Start testing if everything ok. 55 | # Stop handling errors. 56 | set +euo pipefail 57 | echo 58 | echo "No error noticed during setup the test environment. System tests are starting..." 59 | cd ./get_data 60 | python3 ./start.py 61 | cd ../analyze_data 62 | python3 ./start_screenshots_analysis.py 63 | python3 ./start_logs_analysis.py 64 | cd ../ 65 | -------------------------------------------------------------------------------- /tests/unit_tests/config/global-example.json: -------------------------------------------------------------------------------- 1 | "One entry (one new script) in array 'scripts' in global.json": 2 | 3 | { 4 | "name": "name of the source script without file extension (.js)", 5 | "remove_custom_namespace": true "or" false, 6 | "let_to_var": true "or" false, 7 | "src_script_requirements": [ 8 | { 9 | "type": "const or var or ...", 10 | "requirements": [ 11 | { 12 | "from": "file or library", 13 | "objects": [ 14 | "array of names of objects to be imported from file or library" 15 | ] 16 | }, 17 | { 18 | "import": "file or library", 19 | "as": "name for whole imported file or library" 20 | }, 21 | { 22 | "files": [ 23 | "array of names of required non script files" 24 | ] 25 | } 26 | ] 27 | } 28 | ], 29 | "test_script_requirements": [ 30 | { 31 | "type": "const or var or ...", 32 | "requirements": [ 33 | { 34 | "from": "file or library", 35 | "objects": [ 36 | "array of names of objects to be imported from file or library" 37 | ] 38 | }, 39 | { 40 | "import": "file or library", 41 | "as": "name for whole imported file or library" 42 | }, 43 | { 44 | "files": [ 45 | "array of names of required non script files" 46 | ] 47 | } 48 | ] 49 | } 50 | ], 51 | "replace_in_src": [ 52 | { 53 | "origin": "browser.storage.sync.get(null).then(updateLevels);", 54 | "new": "browser.storage.sync.get(null);" 55 | } 56 | ], 57 | "inject_code_to_src": 58 | { 59 | "begin": "code to be injected at the begging of source script after requirements", 60 | "end": "code to be injected at the end of source script before exports" 61 | }, 62 | "extra_exports": [ 63 | "Names of objects to be exported from source file (separated by comma).", 64 | "Global functions and vars should be exported automatically and it is not necessary to introduce them here.", 65 | "This is only for special cases when standart automatical export is insufficient." 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit_tests/config/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "tmp", 3 | "spec_files": [ 4 | <> 5 | ], 6 | "helpers": [ 7 | ], 8 | "stopSpecOnExpectationFailure": false, 9 | "random": true 10 | } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/unit_tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unit_tests", 3 | "version": "1.0.0", 4 | "description": "JShelter unit tests.", 5 | "main": "", 6 | "scripts": { 7 | "test": "./start_unit_tests.sh", 8 | "start": "./start_unit_tests.sh" 9 | }, 10 | "author": "Martin Bednar, ibednar@fit.vutbr.cz", 11 | "license": "GNU General Public License 3 or later", 12 | "dependencies": { 13 | "jasmine": "^3.6.4", 14 | "navigator": "^1.0.1", 15 | "sinon-chrome": "^3.0.1", 16 | "window": "^4.2.7" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit_tests/tests/background_tests.js: -------------------------------------------------------------------------------- 1 | // 2 | // JShelter is a browser extension which increases level 3 | // of security, anonymity and privacy of the user while browsing the 4 | // internet. 5 | // 6 | // Copyright (C) 2020 Martin Bednar 7 | // 8 | // SPDX-License-Identifier: GPL-3.0-or-later 9 | // 10 | // This program is free software: you can redistribute it and/or modify 11 | // it under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 3 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will be useful, 16 | // but WITHOUT ANY WARRANTY; without ev1267027en the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with this program. If not, see . 22 | // 23 | 24 | /// 25 | 26 | const { tab_levels, tab_urls, current_level, updateBadge, queryInfo, tabUpdate, tabActivate, connected } = require('../tmp/background.js'); 27 | 28 | const { levels, default_level } = require('../tmp/levels.js'); 29 | 30 | describe("Background", function() { 31 | describe("Function updateBadge", function() { 32 | it("should be defined.",function() { 33 | expect(updateBadge).toBeDefined(); 34 | }); 35 | }); 36 | describe("Function tabUpdate", function() { 37 | it("should be defined.",function() { 38 | expect(tabUpdate).toBeDefined(); 39 | }); 40 | it("should return default level.",function() { 41 | expect(tabUpdate(5,{'url':'https://www.jshelter.org/'})).toBe(default_level); 42 | }); 43 | it("should not throw error when argument changeInfo['url'] is undefined.",function() { 44 | expect(function() {tabUpdate(5,{'url':undefined})}).not.toThrowError(); 45 | }); 46 | it("should throw error when parametr changeInfo is undefined.",function() { 47 | expect(function() {tabUpdate(5,undefined)}).toThrowError(); 48 | }); 49 | it("should throw error when no parametr is given.",function() { 50 | expect(function() {tabUpdate()}).toThrowError(); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /tests/unit_tests/tests/browser_tests.js: -------------------------------------------------------------------------------- 1 | // 2 | // JShelter is a browser extension which increases level 3 | // of security, anonymity and privacy of the user while browsing the 4 | // internet. 5 | // 6 | // Copyright (C) 2020 Martin Bednar 7 | // 8 | // SPDX-License-Identifier: GPL-3.0-or-later 9 | // 10 | // This program is free software: you can redistribute it and/or modify 11 | // it under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 3 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will be useful, 16 | // but WITHOUT ANY WARRANTY; without ev1267027en the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with this program. If not, see . 22 | // 23 | 24 | /// 25 | 26 | describe("Browser", function() { 27 | it("should be defined.",function() { 28 | expect(browser).toBeDefined(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/unit_tests/tests/http_shield_common_tests.js: -------------------------------------------------------------------------------- 1 | // 2 | // JShelter is a browser extension which increases level 3 | // of security, anonymity and privacy of the user while browsing the 4 | // internet. 5 | // 6 | // Copyright (C) 2021 Martin Bednar 7 | // 8 | // SPDX-License-Identifier: GPL-3.0-or-later 9 | // 10 | // This program is free software: you can redistribute it and/or modify 11 | // it under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 3 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will be useful, 16 | // but WITHOUT ANY WARRANTY; without ev1267027en the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with this program. If not, see . 22 | // 23 | 24 | /// 25 | 26 | describe("HTTP Shield", function() { 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit_tests/tests/wrappingS-ECMA-SHARED_tests.js: -------------------------------------------------------------------------------- 1 | // 2 | // JavaScript Restrictor is a browser extension which increases level 3 | // of security, anonymity and privacy of the user while browsing the 4 | // internet. 5 | // 6 | // Copyright (C) 2022 Martin Bednar 7 | // 8 | // SPDX-License-Identifier: GPL-3.0-or-later 9 | // 10 | // This program is free software: you can redistribute it and/or modify 11 | // it under the terms of the GNU General Public License as published by 12 | // the Free Software Foundation, either version 3 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will be useful, 16 | // but WITHOUT ANY WARRANTY; without ev1267027en the implied warranty of 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | // GNU General Public License for more details. 19 | // 20 | // You should have received a copy of the GNU General Public License 21 | // along with this program. If not, see . 22 | // 23 | 24 | /// 25 | 26 | describe("ECMA-SHARED", function() { 27 | describe("proxyHandler", function() { 28 | it("should be defined.",function() { 29 | expect(proxyHandler).toBeDefined(); 30 | }); 31 | }); 32 | describe("wrappingFunctionBody", function() { 33 | it("should be defined.",function() { 34 | expect(wrappingFunctionBody).toBeDefined(); 35 | }); 36 | }); 37 | describe("wrappers", function() { 38 | it("should be defined.",function() { 39 | expect(wrappers).toBeDefined(); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /tools/i18n/get_translated_strings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Extracts all translated strings, for example to allwo spell checking 4 | # 5 | # Run from the base directory of the repository with one argument - the identification of the 6 | # language 7 | 8 | LANG="$1" 9 | 10 | grep '"\(message\|content\)"' common/_locales/$LANG/messages.json | sed 's/[^:]*://' | grep '"' | grep -v '"$[[:digit:]]"' 11 | -------------------------------------------------------------------------------- /tools/i18n/weblatelib.py: -------------------------------------------------------------------------------- 1 | # A library that contains common functions used in scripts that process Weblate translations 2 | # 3 | # Copyright (C) 2023 Libor Polčák 4 | # 5 | # SPDX-License-Identifier: GPL-3.0-or-later 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | LOCALES_PATH="common/_locales" 22 | base_branch = "main" 23 | PLACEHOLDERS_DELIMITER = "###placeholders###" 24 | EXAMPLE_DELIMITER = " ###EXAMPLE### " 25 | 26 | import json 27 | import os 28 | 29 | def get_current_locale_dirs(): 30 | return os.listdir(LOCALES_PATH) 31 | 32 | def load_locales_from_json(locale_names, db): 33 | for locale in locale_names: 34 | f = open("%s/%s/messages.json" % (LOCALES_PATH, locale)) 35 | db[locale] = json.load(f) 36 | -------------------------------------------------------------------------------- /wasm/README.md: -------------------------------------------------------------------------------- 1 | # AssemblyScript farbling implementation 2 | This package contains a small and efficient image and audio data farbling implementation in AssemblyScript. 3 | The compiled WebAssembly module has around 1kB, which is efficient enough to inject into every page. 4 | This implementation will result in the same farbling outcome as the original JavaScript implementation under the same conditions, which is neccessary to prevent fingerprinting as the WebAssembly module injection isn't completely reliable and the JS implementation must be used as a fallback. 5 | 6 | ## Prerequisites 7 | * NodeJS 8 | 9 | ## Compiling 10 | First, initialize the node module and download dependencies by running: 11 | ``` 12 | npm install 13 | ``` 14 | 15 | After initialization, the module can be compiled by running: 16 | ``` 17 | npm run debug 18 | npm run release 19 | ``` 20 | 21 | The Makefile supplied with JShelter will take care of all steps required for this module's compilation and correct inclusion during the build process. 22 | -------------------------------------------------------------------------------- /wasm/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": { 3 | "debug": { 4 | "outFile": "build/debug.wasm", 5 | "textFile": "build/debug.wat", 6 | "debug": true 7 | }, 8 | "release": { 9 | "outFile": "build/release.wasm", 10 | "textFile": "build/release.wat", 11 | "optimize": "speed", 12 | "converge": true, 13 | "noAssert": true 14 | } 15 | }, 16 | "options": { 17 | "importMemory": true, 18 | "noExportMemory": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wasm/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /wasm/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wasm_farble", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "wasm_farble", 9 | "version": "1.0.0", 10 | "license": "GNU General Public License 3 or later", 11 | "devDependencies": { 12 | "assemblyscript": "^0.27.1" 13 | } 14 | }, 15 | "node_modules/assemblyscript": { 16 | "version": "0.27.1", 17 | "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.1.tgz", 18 | "integrity": "sha512-0ZS9ujdoSAjuwc+qdZ4PeZy32wFh3U2GVy7/G2dfDr/5i0jOmWY29AaFsiNxDQ7z6MOeTo9YpNLfIqZ1WWzh8A==", 19 | "dev": true, 20 | "dependencies": { 21 | "binaryen": "111.0.0-nightly.20230202", 22 | "long": "^5.2.1" 23 | }, 24 | "bin": { 25 | "asc": "bin/asc.js", 26 | "asinit": "bin/asinit.js" 27 | }, 28 | "engines": { 29 | "node": ">=16", 30 | "npm": ">=7" 31 | }, 32 | "funding": { 33 | "type": "opencollective", 34 | "url": "https://opencollective.com/assemblyscript" 35 | } 36 | }, 37 | "node_modules/binaryen": { 38 | "version": "111.0.0-nightly.20230202", 39 | "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-111.0.0-nightly.20230202.tgz", 40 | "integrity": "sha512-aGMDtxmc8zQHzAamyOBvO38n2e/GuXM0dZCJg+IuG2YUQODTqI37XSkAixS8c0wXn2dgLntDMk1VDblKCsy0GA==", 41 | "dev": true, 42 | "bin": { 43 | "wasm-opt": "bin/wasm-opt", 44 | "wasm2js": "bin/wasm2js" 45 | } 46 | }, 47 | "node_modules/long": { 48 | "version": "5.2.1", 49 | "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", 50 | "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", 51 | "dev": true 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /wasm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wasm_farble", 3 | "version": "1.0.0", 4 | "description": "AssemblyScript fast farbling implementation", 5 | "scripts": { 6 | "debug": "asc assembly/farble.ts --target debug", 7 | "release": "asc assembly/farble.ts --target release", 8 | "build": "npm run debug && npm run release", 9 | "clean": "rm -rf build/debug* build/release*" 10 | }, 11 | "author": "Martin Zmitko ", 12 | "license": "GNU General Public License 3 or later", 13 | "devDependencies": { 14 | "assemblyscript": "^0.27.1" 15 | }, 16 | "type": "module" 17 | } 18 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # ignore auto-generated translations 2 | content/pages/*/* 3 | content/posts/*/* 4 | content/wrappers/*/* 5 | i18n/*/ 6 | -------------------------------------------------------------------------------- /website/content/images/cooperation/almost-passive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/cooperation/almost-passive.png -------------------------------------------------------------------------------- /website/content/images/cooperation/chrome-weekly-2022-03-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/cooperation/chrome-weekly-2022-03-17.png -------------------------------------------------------------------------------- /website/content/images/cooperation/fine-tuning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/cooperation/fine-tuning.png -------------------------------------------------------------------------------- /website/content/images/cooperation/firefox-daily-2022-03-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/cooperation/firefox-daily-2022-03-17.png -------------------------------------------------------------------------------- /website/content/images/cooperation/fpd-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/cooperation/fpd-report.png -------------------------------------------------------------------------------- /website/content/images/crawling-apis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling-apis.png -------------------------------------------------------------------------------- /website/content/images/crawling-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling-architecture.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/APIs_with_uBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/APIs_with_uBlock.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/APIs_with_uBlock_opensource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/APIs_with_uBlock_opensource.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/APIs_without_uBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/APIs_without_uBlock.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/APIs_without_uBlock_opensource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/APIs_without_uBlock_opensource.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/JScalls_with_uBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/JScalls_with_uBlock.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/JScalls_with_uBlock_opensource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/JScalls_with_uBlock_opensource.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/JScalls_without_uBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/JScalls_without_uBlock.png -------------------------------------------------------------------------------- /website/content/images/crawling_results/JScalls_without_uBlock_opensource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/crawling_results/JScalls_without_uBlock_opensource.png -------------------------------------------------------------------------------- /website/content/images/faq/chromium_pintoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/chromium_pintoolbar.png -------------------------------------------------------------------------------- /website/content/images/faq/firefox_pintoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/firefox_pintoolbar.png -------------------------------------------------------------------------------- /website/content/images/faq/fpd_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/fpd_off.png -------------------------------------------------------------------------------- /website/content/images/faq/jss_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/jss_low.png -------------------------------------------------------------------------------- /website/content/images/faq/jss_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/jss_off.png -------------------------------------------------------------------------------- /website/content/images/faq/jss_tweak_sorting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/jss_tweak_sorting.png -------------------------------------------------------------------------------- /website/content/images/faq/jss_tweak_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/jss_tweak_start.png -------------------------------------------------------------------------------- /website/content/images/faq/jss_tweaking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/jss_tweaking.png -------------------------------------------------------------------------------- /website/content/images/faq/nbs_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/faq/nbs_off.png -------------------------------------------------------------------------------- /website/content/images/fpdetection/notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/fpdetection/notifications.png -------------------------------------------------------------------------------- /website/content/images/i18n/webly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/i18n/webly.png -------------------------------------------------------------------------------- /website/content/images/optimizations/firefox_audio_recommended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/optimizations/firefox_audio_recommended.png -------------------------------------------------------------------------------- /website/content/images/optimizations/firefox_canvas3d_recommended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/optimizations/firefox_canvas3d_recommended.png -------------------------------------------------------------------------------- /website/content/images/optimizations/firefox_canvas_recommended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/optimizations/firefox_canvas_recommended.png -------------------------------------------------------------------------------- /website/content/images/portscan-1_captured_traffic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/portscan-1_captured_traffic.png -------------------------------------------------------------------------------- /website/content/images/portscan-2_request_blocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/content/images/portscan-2_request_blocked.png -------------------------------------------------------------------------------- /website/content/pages/build.md: -------------------------------------------------------------------------------- 1 | Title: Building from scratch 2 | 3 | ### GNU/Linux and Mac OS 4 | 5 | 1. Go to the project repository: [https://pagure.io/JShelter/webextension](https://pagure.io/JShelter/webextension). 6 | 2. Download the desired branch, e.g. as zip archive. 7 | 3. Unpack the zip archive. 8 | 4. Run `make`. 9 | * You will need common software, such as `zip`, `wget`, `bash`, `awk`, `sed`. 10 | * Note that running `make` removes all `console.debug` calls. If you want to keep such calls, run 11 | `make debug`. 12 | 5. Import the extension to the browser. 13 | * [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#installing) 14 | 1. Open `about:debugging`. 15 | 2. Click the *This Firefox* option 16 | 3. Click the *Load Temporary Add-on* button 17 | 4. Select the file `jshelter_firefox.zip` created by `make`. 18 | * Chromium-based browsers: 19 | 1. Open `chrome://extensions`. 20 | 2. Enable developper mode. 21 | 3. Click `Load unpacked`. 22 | 4. Import the `jshelter_chrome/` directory created by `make`. 23 | 24 | ### Windows 25 | 26 | 1. Install Windows Subsystem for Linux (WSL): [https://docs.microsoft.com/en-us/windows/wsl/install-win10](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 27 | 2. Go to the project repository: [https://pagure.io/JShelter/webextension](https://pagure.io/JShelter/webextension). 28 | 3. Download the desired branch, e.g. as zip archive. 29 | 4. Unpack the zip archive. 30 | 5. Open the JShelter project folder in WSL, run `make`. 31 | * Make sure that `zip` and all other necessary tools are installed. 32 | * Note that EOL in `fix_manifest.sh` must be set to `LF` (you can use the tool `dos2unix` in WSL to convert `CR LF` to `LF`). 33 | 6. On Windows, import the extension to the browser according to the instructions for Linux (above). 34 | -------------------------------------------------------------------------------- /website/content/pages/build.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/coding-style.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2021 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/credits.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/faq.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/fpd.md: -------------------------------------------------------------------------------- 1 | Title: Fingerprint Detector 2 | 3 | Fingerprint Detector (FPD) provides heuristic analysis of fingerprinting 4 | behaviour. FPD monitors APIs that are commonly used by fingerprinters and 5 | applies a heuristic approach to detect fingerprinting behaviour in real-time. 6 | When a fingerprinting attempt is detected, FPD notifies the user. The user can 7 | configure JShelter to reactively block subsequent asynchronous HTTP requests 8 | initiated by the fingerprinting page and clear the storage facilities where the 9 | page could have stored a (partial) fingerprint. However, this behaviour may 10 | break the page. The goal of the aggressive mode is to prevent the page from 11 | uploading the full fingerprint to a server. However, the fingerprinter can 12 | gradually upload detected values and a partial fingerprint can leak from the 13 | browser. 14 | 15 | The heuristic approach was chosen as many prior studies proved it to be a 16 | viable approach with a very low false-positive rate. The most challenging part 17 | of this approach is a careful selection of detection conditions. The heuristics 18 | contain two basic types of entries: 19 | 20 | 1. JavaScript API endpoints, which are relevant for fingerprinting detection 21 | and 22 | 2. a hierarchy of groups of related endpoints. 23 | 24 | For example, FPD groups endpoints according to their semantic properties. 25 | Imagine that there are two different endpoints. Both provide hardware 26 | information about the device. FPD can assign both endpoints to a group that 27 | covers access to the same hardware properties. The heuristics allow clustering 28 | groups to other groups and creating a hierarchy of groups. Ultimately, the 29 | heuristics are a tree-like structure that computes the threat that a webpage 30 | tried to obtain enough information to compute a unique fingerprint. 31 | 32 | The whole evaluation process dynamically observes the API calls performed by a 33 | web page. FPD analyses the calls themselves. Hence, the dynamic analysis 34 | overcomes any obfuscation of fingerprinting scripts. 35 | 36 | FPD provides a report that explains why FPD evaluated a visited page as a 37 | fingerprinter. The report aims to educate users about fingerprinting and report 38 | why FPD notified the user and optionally blocked the page. Additionally, the 39 | report can be generated from passive observation of web page calls without any 40 | JShelter interaction with the page (no API blocking). 41 | 42 | ![FPD report shows the reasoning to claim that a page is fingerprinting the browser]({attach}/images/cooperation/fpd-report.png) 43 | -------------------------------------------------------------------------------- /website/content/pages/fpd.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2021-2022 Marek Saloň, Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/home.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2021-2022 Ricardo Lafuente, Ana Isabel Carvalho, Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/install.md: -------------------------------------------------------------------------------- 1 | Title: Installing 2 | 3 | JShelter can be installed directly through each browser's extension repository: 4 | 5 | - [Firefox](https://addons.mozilla.org/firefox/addon/javascript-restrictor/) 6 | - [Chrome](https://chrome.google.com/webstore/detail/javascript-restrictor/ammoloihpcbognfddfjcljgembpibcmb) 7 | - [Opera](https://addons.opera.com/extensions/details/javascript-restrictor/) 8 | 9 | To compile the extension from the source code, see the [building from 10 | scratch](/build/) documentation. 11 | -------------------------------------------------------------------------------- /website/content/pages/install.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2021 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/levels.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/license.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2007 Free Software Foundation, Inc. 2 | // SPDX-License-Identifier: CC-BY-ND-4.0 3 | -------------------------------------------------------------------------------- /website/content/pages/nbs.md: -------------------------------------------------------------------------------- 1 | Title: Network Boundary Shield 2 | 3 | The Network Boundary Shield (NBS) is a protection against attacks from an 4 | external network (the Internet) to an internal network - especially against a 5 | reconnaissance attack where a web browser is abused as a proxy. See, for 6 | example, [our blog post on port scanning](/localportscanning/) or the [ForcePoint 7 | report](https://www.forcepoint.com/blog/x-labs/attacking-internal-network-public-internet-using-browser-proxy). 8 | 9 | It works by filtering HTTP requests by means of the blocking webRequest API to 10 | handle HTTP requests. This means that the processing of each HTTP request is 11 | paused before it is analyzed and allowed (if it seems benign) or blocked (if it 12 | is suspicious). 13 | 14 | The main goal of NBS is to prevent attacks where a public website requests a 15 | resource from the internal network (e.g. the logo of the manufacturer of the 16 | local router); NBS will detect that a web page hosted on the public Internet is 17 | trying to connect to a local IP address. NBS only blocks HTTP requests from a 18 | web page hosted on a public IP address to a private network resource; the user 19 | can allow specific web pages to access local resources (e.g. when using 20 | Intranet services). 21 | 22 | NBS uses [CSV files provided by 23 | IANA](https://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xml) 24 | to determine public and local IP address prefixes. Both IPv4 and IPv6 is 25 | supported. The CSV files are downloaded during the JShelter building process. 26 | 27 | The NBS has a small performance footprint, which differs for each browser 28 | implementation. 29 | 30 | More information about the Network Boundary Shield can be obtained from the 31 | [master thesis by Pavel 32 | Pohner](https://www.vutbr.cz/studenti/zav-prace/detail/129272) (in Czech). 33 | -------------------------------------------------------------------------------- /website/content/pages/nbs.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/new-wrapper.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák, Giorgio Maone 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/permissions.md: -------------------------------------------------------------------------------- 1 | Title: Permissions 2 | 3 | JShelter requires these permissions: 4 | 5 | * **storage**: for storing extension configuration and user options 6 | * **tabs**: for updating the extension's icon badge on tab change 7 | * **webRequest, webRequestBlocking, all_urls**: for modifying JavaScript objects and APIs on all pages, and for capturing and blocking malicious HTTP requests 8 | * **dns**: for resolving DNS queries in Firefox version of HTTP request shield 9 | * **notifications**: for notifying users on blocked HTTP requests/hosts 10 | * **browsingData**: Fingerprint Detector needs to remove data from any storage that can save the 11 | fingerprint 12 | * **webNavigation**: for deploying wrappers as early as possible to avoid page scripts accessing 13 | unwrapped objects. NSCL use a different approch for this purpose in Chromium-based browsers. All 14 | brosers need the permission to apply `window.name` protection 15 | 16 | jShelter stores all configuration data in the browser or in the user account. It does not upload any data to our servers. 17 | -------------------------------------------------------------------------------- /website/content/pages/permissions.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/threatmodel.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/pages/versions.md.license: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2019-2022 Libor Polčák 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /website/content/posts/first-mv3-step.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First step towards MV3 3 | date: 2024-04-19 17:00 4 | Series: Manifest v3 5 | --- 6 | 7 | We have been working on migration to Manifest v3 (MV3) for some time and today we are shipping a 8 | JShelter version 0.18 that implements stateless replacement for background pages which is a first step towards MV3. 9 | 10 | MV2 extensions were allowed to create background pages. These pages allow running JavaScript code 11 | and keep state like variables for the whole browser session. Essentially, all background pages 12 | started with the browser and lasted until the user closed the browser. Hence, we could utilize 13 | background pages to safe all information needed to be kept in memory. For instance, JShelter needs 14 | to store: 15 | 16 | * hashes used as a seed for JavaScript shield anti-fingerprinting protection, 17 | * number of API calls needed for Fingerprint detector, which the user can see in the pop up and 18 | fingerprinting report, 19 | * information needed to keep pop up icon dynamic, 20 | * etc. 21 | 22 | We needed to solve issues related to the migration of all these information from regular JavaScript 23 | variables to Web Storage. As we expect that other extensions need to solve the same problem, we created 24 | a [stateless NSCL branch](https://github.com/hackademix/nscl/tree/stateless). Among others, we 25 | needed to solve the issue of writing to the storage too frequently. As the core of JShelter is 26 | heavily stateful, we needed to rewrite important parts that were in the code base for years and were 27 | proven to work. 28 | 29 | JShelter has repeatable tests and we run additional testing, especially under circumstances like 30 | this change. Everything should run the same as it used to work in 0.17. However, please be cautious 31 | and report back any odd behavior that you encounter with 0.18 and later versions. 32 | 33 | Migration to stateless or non-persistent background pages is needed for MV3 but it is still not a 34 | final step. Expect other major changes in JShelter core code including removal of Network Boundary 35 | Shield for Chromium-based browsers soon. Hence, keep cautious also in the following months and 36 | report back any issues that you encounter. Have a look at our [Release page](/versions/) for more 37 | information about the changes in JShelter. 38 | -------------------------------------------------------------------------------- /website/i18n/build_po_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Generates .po files from the original Markdown source files. 4 | # 5 | 6 | mkdir -p en 7 | 8 | for f in ../content/pages/*.md; do 9 | md2po --quiet \ 10 | --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/pages.po \ 11 | -d "Content-Type: text/plain; charset=utf-8" 12 | # -d ”Language: es” 13 | done 14 | 15 | for f in ../content/posts/*.md; do 16 | md2po --quiet \ 17 | --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/posts.po \ 18 | -d "Content-Type: text/plain; charset=utf-8" 19 | # -d ”Language: es” 20 | done 21 | 22 | for f in ../content/wrappers/*.md; do 23 | md2po --quiet \ 24 | --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/wrappers.po \ 25 | -d "Content-Type: text/plain; charset=utf-8" 26 | # -d ”Language: es” 27 | done 28 | -------------------------------------------------------------------------------- /website/i18n/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Updates the local translation files with the most recent Weblate versions. 4 | # 5 | 6 | for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do 7 | echo $lang 8 | wlc download jshelter/website/$lang >| $lang/pages.po 9 | wlc download jshelter/website-posts/$lang >| $lang/posts.po 10 | wlc download jshelter/website-wrappers/$lang >| $lang/wrappers.po 11 | done 12 | -------------------------------------------------------------------------------- /website/i18n/postprocess.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Apply some post-processing to deal with broken 5 | # lines in the Markdown frontmatter in the Weblate 6 | # translated files. Accepts a file as argument and 7 | # overwrites it with the processed version. 8 | 9 | import sys 10 | 11 | FIELDNAMES = ["Series", "series_index", "Date", "Modified"] 12 | 13 | with open(sys.argv[1], 'r') as f: 14 | lines = f.readlines() 15 | 16 | # first pass: join all lines 17 | raw_frontmatter = "" 18 | for line in lines: 19 | if not line.strip(): 20 | break 21 | raw_frontmatter += line.strip() + ' ' 22 | 23 | # remove header markup if present 24 | if raw_frontmatter.startswith('# '): 25 | raw_frontmatter = raw_frontmatter.replace('# ', '', 1) 26 | if raw_frontmatter.startswith('## '): 27 | raw_frontmatter = raw_frontmatter.replace('## ', '', 1) 28 | if raw_frontmatter.startswith('### '): 29 | raw_frontmatter = raw_frontmatter.replace('### ', '', 1) 30 | 31 | # second pass: break lines on field names 32 | output = raw_frontmatter 33 | for name in FIELDNAMES: 34 | tag = name + ": " 35 | if tag in raw_frontmatter: 36 | output = output.replace(tag, '\n' + tag) 37 | 38 | # now combine frontmatter and content 39 | output += '\n' 40 | frontmatter_ended = False 41 | for line in lines: 42 | if not line.strip(): 43 | frontmatter_ended = True 44 | if not frontmatter_ended: 45 | continue 46 | output += line 47 | 48 | with open(sys.argv[1], 'w') as f: 49 | f.write(output) 50 | -------------------------------------------------------------------------------- /website/i18n/translate_content.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Generates translated content files from the .po sources 4 | 5 | for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do 6 | for section in 'pages' 'posts' 'wrappers'; do 7 | mkdir -p ../content/$section/$lang # /content/pages/pt 8 | echo "Translating $section for language $lang..." 9 | for f in `ls ../content/$section/*.md`; do 10 | # echo $f 11 | po2md $f -p $lang/$section.po >| ${f/$section/$section\/$lang} 12 | done 13 | done 14 | done 15 | -------------------------------------------------------------------------------- /website/md-templates/wrapper.md: -------------------------------------------------------------------------------- 1 | Title: {{ title }} 2 | Filename: {{ filename }} 3 | 4 | {{ description }} 5 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/__init__.py: -------------------------------------------------------------------------------- 1 | from .i18n_subsites import * 2 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/images/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/plugins/i18n_subsites/test_data/content/images/img.png -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/pages/hidden-page-cz.rst: -------------------------------------------------------------------------------- 1 | 404 stránka 2 | =========== 3 | :slug: 404 4 | :lang: cz 5 | :status: hidden 6 | 7 | Jednoduchá 404 stránka. 8 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/pages/hidden-page-de.rst: -------------------------------------------------------------------------------- 1 | Eine 404 Seite 2 | ============== 3 | :slug: 404 4 | :lang: de 5 | :status: hidden 6 | 7 | Eine einfache 404 Seite. 8 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/pages/hidden-page-en.rst: -------------------------------------------------------------------------------- 1 | A 404 page 2 | ========== 3 | :slug: 404 4 | :lang: en 5 | :status: hidden 6 | 7 | A simple 404 page. 8 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/pages/untranslated-page.rst: -------------------------------------------------------------------------------- 1 | Untranslated page 2 | ================= 3 | :lang: en 4 | 5 | This page has no translation. 6 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/translated_article-cz.rst: -------------------------------------------------------------------------------- 1 | Přeložený článek 2 | ================ 3 | :slug: translated-article 4 | :lang: cz 5 | :date: 2014-09-15 6 | 7 | Jednoduchý článek s překlady. 8 | Zde je odkaz na `nějaký obrázek <{filename}/images/img.png>`_. 9 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/translated_article-de.rst: -------------------------------------------------------------------------------- 1 | Ein übersetzter Artikel 2 | ======================= 3 | :slug: translated-article 4 | :lang: de 5 | :date: 2014-09-14 6 | 7 | Ein einfacher Artikel mit einer Übersetzung. 8 | Hier ist ein Link zur `einigem Bild <{filename}/images/img.png>`_. 9 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/translated_article-en.rst: -------------------------------------------------------------------------------- 1 | A translated article 2 | ==================== 3 | :slug: translated-article 4 | :lang: en 5 | :date: 2014-09-13 6 | 7 | A simple article with a translation. 8 | Here is a link to `some image <{filename}/images/img.png>`_. 9 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/content/untranslated_article-en.rst: -------------------------------------------------------------------------------- 1 | An untranslated article 2 | ======================= 3 | :date: 2014-07-14 4 | :lang: en 5 | 6 | An article without a translation. 7 | Here is a link to an `untranslated page`_ 8 | 9 | .. _`untranslated page`: {filename}/pages/untranslated-page.rst 10 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/babel.cfg: -------------------------------------------------------------------------------- 1 | [jinja2: templates/**.html] 2 | 3 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/messages.pot: -------------------------------------------------------------------------------- 1 | # Translations template for PROJECT. 2 | # Copyright (C) 2014 ORGANIZATION 3 | # This file is distributed under the same license as the PROJECT project. 4 | # FIRST AUTHOR , 2014. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PROJECT VERSION\n" 10 | "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" 11 | "POT-Creation-Date: 2014-07-13 12:25+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 1.3\n" 19 | 20 | #: templates/base.html:3 21 | msgid "Welcome to our" 22 | msgstr "" 23 | 24 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/static/style.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/plugins/i18n_subsites/test_data/localized_theme/static/style.css -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/templates/base.html: -------------------------------------------------------------------------------- 1 | {% extends "!simple/base.html" %} 2 | 3 | {% block title %}{% trans %}Welcome to our{% endtrans %} {{ SITENAME }}{% endblock %} 4 | {% block head %} 5 | {{ super() }} 6 | 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/translations/de/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/plugins/i18n_subsites/test_data/localized_theme/translations/de/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/localized_theme/translations/de/LC_MESSAGES/messages.po: -------------------------------------------------------------------------------- 1 | # German translations for PROJECT. 2 | # Copyright (C) 2014 ORGANIZATION 3 | # This file is distributed under the same license as the PROJECT project. 4 | # FIRST AUTHOR , 2014. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: PROJECT VERSION\n" 9 | "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" 10 | "POT-Creation-Date: 2014-07-13 12:25+0200\n" 11 | "PO-Revision-Date: 2014-07-13 12:26+0200\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: de \n" 14 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=utf-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Generated-By: Babel 1.3\n" 19 | 20 | #: templates/base.html:3 21 | msgid "Welcome to our" 22 | msgstr "Willkommen Sie zur unserer" 23 | 24 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/an-untranslated-article.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testing site - An untranslated article 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 25 |
26 |
27 |

28 | An untranslated article

30 | 31 |
32 |
33 | 36 |
37 | By The Tester 38 |
39 |
40 | Category: misc 41 |
42 |
43 |
44 |

An article without a translation. 45 | Here is a link to an untranslated page

46 | 47 |
48 |
49 |
50 |
51 | Proudly powered by Pelican, 52 | which takes great advantage of Python. 53 |
54 |
55 | 56 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/cz/an-untranslated-article-en.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testovací stránka - An untranslated article 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 |
25 |
26 |

27 | An untranslated article

29 | 30 |
31 |
32 | 35 |
36 | By Test Testovič 37 |
38 |
39 | Category: misc 40 |
41 |
42 |
43 |

An article without a translation. 44 | Here is a link to an untranslated page

45 | 46 |
47 |
48 |
49 |
50 | Proudly powered by Pelican, 51 | which takes great advantage of Python. 52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/cz/feeds_all.atom.xml: -------------------------------------------------------------------------------- 1 | 2 | Testovací stránkahttp://example.com/test/cz/2014-09-15T00:00:00+00:00Přeložený článek2014-09-15T00:00:00+00:002014-09-15T00:00:00+00:00Test Testovičtag:example.com,2014-09-15:/test/cz/translated-article.html<p>Jednoduchý článek s překlady. 3 | Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p> 4 | Ein übersetzter Artikel2014-09-14T00:00:00+00:002014-09-14T00:00:00+00:00Test Testovičtag:example.com,2014-09-14:/test/de/translated-article.html<p>Ein einfacher Artikel mit einer Übersetzung. 5 | Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p> 6 | A translated article2014-09-13T00:00:00+00:002014-09-13T00:00:00+00:00Test Testovičtag:example.com,2014-09-13:/test/translated-article.html<p>A simple article with a translation. 7 | Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p> 8 | An untranslated article2014-07-14T00:00:00+00:002014-07-14T00:00:00+00:00Test Testovičtag:example.com,2014-07-14:/test/cz/an-untranslated-article-en.html<p>An article without a translation. 9 | Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p> 10 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/cz/pages/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testovací stránka - 404 stránka 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 |

404 stránka

25 | Translations: 26 | de 27 | en 28 | 29 | 30 |

Jednoduchá 404 stránka.

31 | 32 | 33 |
34 |
35 | Proudly powered by Pelican, 36 | which takes great advantage of Python. 37 |
38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/cz/translated-article.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testovací stránka - Přeložený článek 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 27 |
28 |
29 |

30 | Přeložený článek

32 | Translations: 33 | de 34 | en 35 | 36 |
37 |
38 | 41 |
42 | By Test Testovič 43 |
44 |
45 | Category: misc 46 |
47 |
48 |
49 |

Jednoduchý článek s překlady. 50 | Zde je odkaz na nějaký obrázek.

51 | 52 |
53 |
54 |
55 |
56 | Proudly powered by Pelican, 57 | which takes great advantage of Python. 58 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/drafts/an-untranslated-article-en.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testseite - An untranslated article 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 |
25 |
26 |

27 | An untranslated article

29 | 30 |
31 |
32 | 35 |
36 | By Der Tester 37 |
38 |
39 | Category: misc 40 |
41 |
42 |
43 |

An article without a translation. 44 | Here is a link to an untranslated page

45 | 46 |
47 |
48 |
49 |
50 | Proudly powered by Pelican, 51 | which takes great advantage of Python. 52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/feeds_all.atom.xml: -------------------------------------------------------------------------------- 1 | 2 | Testseitehttp://example.com/test/de/2014-09-15T00:00:00+00:00Přeložený článek2014-09-15T00:00:00+00:002014-09-15T00:00:00+00:00Der Testertag:example.com,2014-09-15:/test/cz/translated-article.html<p>Jednoduchý článek s překlady. 3 | Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p> 4 | Ein übersetzter Artikel2014-09-14T00:00:00+00:002014-09-14T00:00:00+00:00Der Testertag:example.com,2014-09-14:/test/de/translated-article.html<p>Ein einfacher Artikel mit einer Übersetzung. 5 | Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p> 6 | A translated article2014-09-13T00:00:00+00:002014-09-13T00:00:00+00:00Der Testertag:example.com,2014-09-13:/test/translated-article.html<p>A simple article with a translation. 7 | Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p> 8 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Willkommen Sie zur unserer Testseite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 19 |
20 |

All articles

21 | 22 |
    23 |
  1. 35 |
36 |
37 |
38 |
39 | Proudly powered by Pelican, 40 | which takes great advantage of Python. 41 |
42 |
43 | 44 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/pages/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testseite - Eine 404 Seite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 |

Eine 404 Seite

25 | Translations: 26 | cz 27 | en 28 | 29 | 30 |

Eine einfache 404 Seite.

31 | 32 | 33 |
34 |
35 | Proudly powered by Pelican, 36 | which takes great advantage of Python. 37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/pages/untranslated-page-en.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testseite - Untranslated page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 21 |

Untranslated page

22 | 23 | 24 |

This page has no translation.

25 | 26 | 27 |
28 |
29 | Proudly powered by Pelican, 30 | which takes great advantage of Python. 31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/de/translated-article.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testseite - Ein übersetzter Artikel 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 27 |
28 |
29 |

30 | Ein übersetzter Artikel

32 | Translations: 33 | cz 34 | en 35 | 36 |
37 |
38 | 41 |
42 | By Der Tester 43 |
44 |
45 | Category: misc 46 |
47 |
48 |
49 |

Ein einfacher Artikel mit einer Übersetzung. 50 | Hier ist ein Link zur einigem Bild.

51 | 52 |
53 |
54 |
55 |
56 | Proudly powered by Pelican, 57 | which takes great advantage of Python. 58 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/feeds_all.atom.xml: -------------------------------------------------------------------------------- 1 | 2 | Testing sitehttp://example.com/test/2014-09-15T00:00:00+00:00Přeložený článek2014-09-15T00:00:00+00:002014-09-15T00:00:00+00:00The Testertag:example.com,2014-09-15:/test/cz/translated-article.html<p>Jednoduchý článek s překlady. 3 | Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p> 4 | Ein übersetzter Artikel2014-09-14T00:00:00+00:002014-09-14T00:00:00+00:00The Testertag:example.com,2014-09-14:/test/de/translated-article.html<p>Ein einfacher Artikel mit einer Übersetzung. 5 | Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p> 6 | A translated article2014-09-13T00:00:00+00:002014-09-13T00:00:00+00:00The Testertag:example.com,2014-09-13:/test/translated-article.html<p>A simple article with a translation. 7 | Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p> 8 | An untranslated article2014-07-14T00:00:00+00:002014-07-14T00:00:00+00:00The Testertag:example.com,2014-07-14:/test/an-untranslated-article.html<p>An article without a translation. 9 | Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p> 10 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/images/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/plugins/i18n_subsites/test_data/output/images/img.png -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/pages/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testing site - A 404 page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 25 |

A 404 page

26 | Translations: 27 | cz 28 | de 29 | 30 | 31 |

A simple 404 page.

32 | 33 | 34 |
35 |
36 | Proudly powered by Pelican, 37 | which takes great advantage of Python. 38 |
39 |
40 | 41 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/pages/untranslated-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testing site - Untranslated page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 22 |

Untranslated page

23 | 24 | 25 |

This page has no translation.

26 | 27 | 28 |
29 |
30 | Proudly powered by Pelican, 31 | which takes great advantage of Python. 32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/output/theme/style.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/plugins/i18n_subsites/test_data/output/theme/style.css -------------------------------------------------------------------------------- /website/plugins/i18n_subsites/test_data/pelicanconf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- # 3 | from __future__ import unicode_literals 4 | 5 | AUTHOR = 'The Tester' 6 | SITENAME = 'Testing site' 7 | SITEURL = 'http://example.com/test' 8 | 9 | # to make the test suite portable 10 | TIMEZONE = 'UTC' 11 | 12 | DEFAULT_LANG = 'en' 13 | LOCALE = 'en_US.UTF-8' 14 | 15 | # Generate only one feed 16 | FEED_ALL_ATOM = 'feeds_all.atom.xml' 17 | CATEGORY_FEED_ATOM = None 18 | TRANSLATION_FEED_ATOM = None 19 | AUTHOR_FEED_ATOM = None 20 | AUTHOR_FEED_RSS = None 21 | 22 | # Disable unnecessary pages 23 | CATEGORY_SAVE_AS = '' 24 | TAG_SAVE_AS = '' 25 | AUTHOR_SAVE_AS = '' 26 | ARCHIVES_SAVE_AS = '' 27 | AUTHORS_SAVE_AS = '' 28 | CATEGORIES_SAVE_AS = '' 29 | TAGS_SAVE_AS = '' 30 | 31 | PLUGIN_PATHS = ['../../'] 32 | PLUGINS = ['i18n_subsites'] 33 | 34 | THEME = 'localized_theme' 35 | JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']} 36 | 37 | from blinker import signal 38 | tmpsig = signal('tmpsig') 39 | I18N_FILTER_SIGNALS = [tmpsig] 40 | 41 | I18N_SUBSITES = { 42 | 'de': { 43 | 'SITENAME': 'Testseite', 44 | 'AUTHOR': 'Der Tester', 45 | 'LOCALE': 'de_DE.UTF-8', 46 | }, 47 | 'cz': { 48 | 'SITENAME': 'Testovací stránka', 49 | 'AUTHOR': 'Test Testovič', 50 | 'I18N_UNTRANSLATED_PAGES': 'remove', 51 | 'I18N_UNTRANSLATED_ARTICLES': 'keep', 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /website/plugins/series/Readme.md: -------------------------------------------------------------------------------- 1 | Series plugin 2 | ------------- 3 | 4 | **NOTE:** [This plugin has been moved to its own repository](https://github.com/pelican-plugins/series). Please file any issues/PRs there. Once all plugins have been migrated to the [new Pelican Plugins organization](https://github.com/pelican-plugins), this monolithic repository will be archived. 5 | 6 | The series plugin allows you to join different posts into a series. 7 | 8 | In order to mark posts as part of a series, use the `:series:` metadata: 9 | 10 | :series: NAME_OF_THIS_SERIES 11 | 12 | or, in Markdown syntax 13 | 14 | Series: NAME_OF_THIS_SERIES 15 | 16 | The plugin collects all articles belonging to the same series and provides 17 | series-related variables that you can use in your template. 18 | 19 | #### Indexing 20 | By default articles in a series are ordered by date and then automatically numbered. 21 | 22 | If you want to force a given order just specify the `:series_index:` metadata or in Markdown `series_index:`, 23 | starting from 1. All articles with this enforced index are put at the beginning of 24 | the series and ordered according to the index itself. All the remaining articles 25 | come after them, ordered by date. 26 | 27 | The plugin provides the following variables to your templates 28 | 29 | * `article.series.name` is the name of the series as specified in the article metadata 30 | * `article.series.index` is the index of the current article inside the series 31 | * `article.series.all` is an ordered list of all articles in the series (including the current one) 32 | * `article.series.all_previous` is an ordered list of the articles published before the current one 33 | * `article.series.all_next` is an ordered list of the articles published after the current one 34 | * `article.series.previous` is the previous article in the series (a shortcut to `article.series.all_previous[-1]`) 35 | * `article.series.next` is the next article in the series (a shortcut to `article.series.all_next[0]`) 36 | 37 | For example: 38 | 39 | {% if article.series %} 40 |

This post is part {{ article.series.index }} of the "{{ article.series.name }}" series:

41 |
    42 | {% for part_article in article.series.all %} 43 |
  1. 44 | {{ part_article.title }} 45 |
  2. 46 | {% endfor %} 47 |
48 | {% endif %} 49 | -------------------------------------------------------------------------------- /website/plugins/series/__init__.py: -------------------------------------------------------------------------------- 1 | from .series import * 2 | -------------------------------------------------------------------------------- /website/plugins/series/series.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | This plugin extends the original series plugin 4 | by FELD Boris 5 | 6 | Copyright (c) Leonardo Giordani 7 | 8 | Joins articles in a series and provides variables to 9 | manage the series in the template. 10 | """ 11 | 12 | from collections import defaultdict 13 | from operator import itemgetter 14 | 15 | from pelican import signals 16 | 17 | 18 | def aggregate_series(generator): 19 | series = defaultdict(list) 20 | 21 | # This cycles through all articles in the given generator 22 | # and collects the 'series' metadata, if present. 23 | # The 'series_index' metadata is also stored, if specified 24 | for article in generator.articles: 25 | if 'series' in article.metadata: 26 | article_entry = ( 27 | article.metadata.get('series_index', None), 28 | article.metadata['date'], 29 | article 30 | ) 31 | 32 | series[article.metadata['series']].append(article_entry) 33 | 34 | # This uses items() which on Python2 is not a generator 35 | # but we are dealing with a small amount of data so 36 | # there shouldn't be performance issues =) 37 | for series_name, series_articles in series.items(): 38 | # This is not DRY but very simple to understand 39 | forced_order_articles = [ 40 | art_tup for art_tup in series_articles if art_tup[0] is not None] 41 | 42 | date_order_articles = [ 43 | art_tup for art_tup in series_articles if art_tup[0] is None] 44 | 45 | forced_order_articles.sort(key=itemgetter(0)) 46 | date_order_articles.sort(key=itemgetter(1)) 47 | 48 | all_articles = forced_order_articles + date_order_articles 49 | ordered_articles = [art_tup[2] for art_tup in all_articles] 50 | enumerated_articles = enumerate(ordered_articles) 51 | 52 | for index, article in enumerated_articles: 53 | article.series = dict() 54 | article.series['name'] = series_name 55 | article.series['index'] = index + 1 56 | article.series['all'] = ordered_articles 57 | article.series['all_previous'] = ordered_articles[0: index] 58 | article.series['all_next'] = ordered_articles[index + 1:] 59 | 60 | if index > 0: 61 | article.series['previous'] = ordered_articles[index - 1] 62 | else: 63 | article.series['previous'] = None 64 | 65 | try: 66 | article.series['next'] = ordered_articles[index + 1] 67 | except IndexError: 68 | article.series['next'] = None 69 | 70 | 71 | def register(): 72 | signals.article_generator_finalized.connect(aggregate_series) 73 | -------------------------------------------------------------------------------- /website/publishconf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- # 3 | 4 | # This file is only used if you use `make publish` or 5 | # explicitly specify it as your config file. 6 | 7 | import os 8 | import sys 9 | 10 | sys.path.append(os.curdir) 11 | from pelicanconf import * 12 | 13 | # If your site is available via HTTPS, make sure SITEURL begins with https:// 14 | SITEURL = "https://jshelter.org" 15 | RELATIVE_URLS = False 16 | 17 | FEED_ALL_ATOM = "feeds/all.atom.xml" 18 | CATEGORY_FEED_ATOM = "feeds/{slug}.atom.xml" 19 | 20 | DELETE_OUTPUT_DIRECTORY = True 21 | -------------------------------------------------------------------------------- /website/requirements.txt: -------------------------------------------------------------------------------- 1 | pelican>=4.6.0 2 | Markdown>=3.3.4 3 | comment-parser>=1.2.3 4 | jinja2>=3.0 5 | pelican-series>=2.1.0 6 | mdpo==1.1.4 7 | wlc==1.13 8 | -------------------------------------------------------------------------------- /website/theme/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/favicon.ico -------------------------------------------------------------------------------- /website/theme/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/favicon.png -------------------------------------------------------------------------------- /website/theme/security.txt: -------------------------------------------------------------------------------- 1 | Contact: mailto:jshelter@gnu.org 2 | Expires: 2032-12-31T22:59:59.000Z 3 | Preferred-Languages: en, cs, it, sk 4 | -------------------------------------------------------------------------------- /website/theme/static/css/minireset.min.css: -------------------------------------------------------------------------------- 1 | /*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} 2 | -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Black.woff -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Black.woff2 -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Bold.woff -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Bold.woff2 -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Regular.woff -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-Regular.woff2 -------------------------------------------------------------------------------- /website/theme/static/fonts/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /website/theme/static/fonts/OxygenMono-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/OxygenMono-Regular.woff -------------------------------------------------------------------------------- /website/theme/static/fonts/OxygenMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/OxygenMono-Regular.woff2 -------------------------------------------------------------------------------- /website/theme/static/fonts/forkawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/forkawesome-webfont.eot -------------------------------------------------------------------------------- /website/theme/static/fonts/forkawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/forkawesome-webfont.ttf -------------------------------------------------------------------------------- /website/theme/static/fonts/forkawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/forkawesome-webfont.woff -------------------------------------------------------------------------------- /website/theme/static/fonts/forkawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/fonts/forkawesome-webfont.woff2 -------------------------------------------------------------------------------- /website/theme/static/images/crumbled-paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/images/crumbled-paper.png -------------------------------------------------------------------------------- /website/theme/static/images/crumbled-paper_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/images/crumbled-paper_dark.png -------------------------------------------------------------------------------- /website/theme/static/images/fsf-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /website/theme/static/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/images/icon.png -------------------------------------------------------------------------------- /website/theme/static/images/icon_48px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/images/icon_48px.png -------------------------------------------------------------------------------- /website/theme/static/images/jshelter_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polcak/jsrestrictor/aa989608bc6930c6c584dd32b5b2dd861e30962a/website/theme/static/images/jshelter_preview.png -------------------------------------------------------------------------------- /website/theme/templates/article.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 | {% set title = article.title %} 6 |
7 | {% block title %} 8 |

{{ article.title }}

9 | 12 | {% endblock %} 13 |
14 | 15 |
16 | {{ article.content }} 17 | 18 | {# source link #} 19 | {#

{{ tr.gotoSourceCode }}

#} 20 |
21 | 22 | {% if article.series %} 23 |
24 |

This post is part {{ article.series.index }} of the "{{ article.series.name }}" series:

25 |
    26 | {% for part_article in article.series.all %} 27 |
  1. 28 | {{ part_article.title }} 29 |
  2. 30 | {% endfor %} 31 |
32 |
33 | {% endif %} 34 |
35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /website/theme/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% set title = page.title %} 4 | 5 | {% block extrascripts %} 6 | 7 | 8 | 27 | {% endblock %} 28 | 29 | {% block content %} 30 | 31 | {{ page.content }} 32 | 33 | {# source link #} 34 | {#

{{ tr.gotoSourceCode }}

#} 35 | 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /website/theme/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% set title = "Blog posts" %} 4 | 5 | {% block content %} 6 |
7 |
8 |

Blogposts

9 | 10 |
11 |
12 |

Recommended blog series

13 | 17 |
18 | 19 |
20 |

Recent posts

21 | {% for article in articles_page.object_list %} 22 | 35 | {% endfor %} 36 |
37 | 38 | {% if articles_page.has_other_pages() %} 39 | {% include 'pagination.html' %} 40 | {% endif %} 41 | 42 |
43 | {% endblock content %} 44 | -------------------------------------------------------------------------------- /website/theme/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% set title = page.title %} 4 | 5 | {% block content %} 6 |
7 |
8 | {% block title %} 9 |

{{ page.title }}

10 | {% endblock %} 11 |
12 | 13 |
14 | {{ page.content }} 15 |
16 | 17 | {% if page.slug == 'levels' %} 18 |
    19 |

    Available wrappers

    20 | {% for p in pages if p.category == "wrappers" %} 21 | {% if p.url.strip('/') == slug %} 22 |
  • 23 | {% else %} 24 |
  • 25 | {% endif %} 26 | {{ p.title }} 27 |
  • 28 | {% endfor %} 29 |
30 | {% endif %} 31 | 32 | {# source link #} 33 | {% if page.category == "wrappers" %} 34 | 37 | {% endif %} 38 |
39 | {% endblock %} 40 | --------------------------------------------------------------------------------