-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade jQuery in Heliosbooth and Heliosverifier #395
Open
laoumh
wants to merge
14
commits into
benadida:master
Choose a base branch
from
laoumh:heliosbooth-upgrade-jquery
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Updates from version 1.1.6 to 1.13.7. Latest minified version was downloaded from Underscore's GitHub repository: https://raw.githubusercontent.com/jashkenas/underscore/refs/heads/master/underscore-min.js
As per the project author, there is no compeling reason to use this plugin: https://github.com/alrusdi/jquery-plugin-query-object
This API is available on all major browsers. Documentation: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
jQuery JSON plugin is marked as deprecated: https://www.npmjs.com/package/jquery-json Author suggests using native JSON API - JSON.stringify() instead of $.toJSON() and and JSON.parse() instead of $.secureEvalJSON().
This plugin website does not exist anymore, but can still be found on the Web Archive: http://web.archive.org/web/20080512013710/http://jtemplates.tpython.com:80/
Underscore.js has templating functionality. Documentation: https://underscorejs.org/#template
Uses native browser APIs fetch() and Promise.all() to get the templates instead of jTemplates' $().setTemplateURL(). Uses Underscore.js _.template() to compile and render templates instead of jTemplates' $().processTemplate()
Latest jQuery version was downloaded from the official website: https://code.jquery.com/jquery-3.7.1.min.js
From the docs: "in 1.4 JSON will yield a JavaScript object" (see https://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings). So, when the raw JSON is actually needed, set 'dataType' to "text". Else, set it to "json" and just use the returned JS object directly instead of manually parsing JSON into the object.
In some instances we should use $().prop() instead of $().attr(), for exemple when disabling an element: $('#my_button').prop('disable', true) instead of attr('disable', 'disable'). Docs: https://api.jquery.com/prop/#prop2
These methods were depreceted, should use $().trigger('select') and $().trigger('submit') instead. Documentation: https://api.jquery.com/select-shorthand/ https://api.jquery.com/submit-shorthand/
Could install but not run 'uglify' (doesn't seems to be maintained). But looking at the source code, 'uglify' seems to call 'grunt-contrib-uglify' which in turn calls 'uglifyjs'. From grunt docs: "will compress and mangle the input files using the default [uglifyjs] options". So, we can use that last package directly, to compress (-c) and mangle (-m): $ uglifyjs <input files> -o <compressed.js> -c -m reserved=['jQuery','$'] This last options tells it not to mangle jQuery. Docs: https://github.com/nanjingboy/uglify https://www.npmjs.com/package/grunt-contrib-uglify https://www.npmjs.com/package/uglify-js
By default, Python's 'json.dumps' method inserts a space after comma an collon characters, which generates a different encrypted ballot hash. So we specify separators without space: json.dumps(d, sort_keys=True, separators=(',', ':'))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
The main aim of this PR is to upgrade jQuery to the latest version, in order to mitigate known vulnerabilities associated with older versions: CVE-2015-9251, CVE-2020-11022 and CVE-2020-11023.
Since each app (sub module) has it's own set of JS libraries, I only tackled
heliosbooth
andheliosverifier
for now.The Voting Booth was chosen first as it is the largest surface of interaction with the system (there are more people voting then administering election).
Documentation links were added to commit messages wherever pertinent.
Major changes
Removal of deprecated JS libraries
Since this PR is security-oriented, beyond upgrading jQuery I also tried to remove technical debt whenever possible, using current Browser API alternatives, that are now widely available.
Hence, the following jQuery plugins were removed:
jquery.query
(replaced by the browser'sURLSearchParams
interface);jquery.json
(replaced byJSON.parse
andJSON.stringify
);jtemplates
(replaced by Underscore.js templates).Switch from jTemplates to Underscore.js templates
By removing jTemplates, we need another way to render the booth templates. Instead of adding a new library to the project, I just used the template functionality available on Underscore.js, which is simple but sufficient for this use case. Underscore.js have three types of delimiters:
<% ...js commands... %>
We can use this to do logic control and loops. So, for instance, instead of jTemplates'
we can substitute it by
I believe that, in a sense, this is easier to maintain because it's just pure JS, instead of having its own syntax like jTemplates.
<%= literal value %>
and<%- HTML-escaped value %>
, which are self-explanatory.Another (better?) solution would have been use Django templates, but that would have been a much bigger change: adding routing and view, changing the client logic of how to show and hide each voting booth step etc.
Finally, Underscore.js was also updated to the latest version, with no breaking changes.
JS libraries compression
I could install but not run
uglify
. It seems this package is not maintained and it now breaks. But, inspecting the package code, it seemsuglify
usesgrunt-contrib-uglify
, which in turn usesuglifyjs
. So, I changedheliosbooth
build command to useuglifyjs
with compression and mangle options (details in the commit message).Tests
The following tests were performed:
min
tomax
answers:min == 0
,min > 0
,max < num. questions
,max == num. questions
. (Note: the system allows to setmin > max
, and it breaks the booth).BigInteger.in_browser = false
)These tests were done on latest versions of Firefox, Chromium and Microsoft Edge.
A Few Considerations
This is a sensitive PR. I tried to test the changes as thoroughly as possible, but edge cases might have escaped me.
For instance, could there be some portion of
jscrypto
that remained uncovered and might break?Please let me know if additional tests are needed.
Here are a few considerations after this upgrade process.
Duplicate JS libraries
A major difficulty with this upgrade was duplication of libraries (is it intentional or a result of bringing each sub module into the main project?).
For example, there are five instances of jQuery through out the project:
I believe it would have been possible to upgrade the whole project if there was a single source for statics.
Build
From the perspective of auditing the Voting Booth, wouldn't it be better to not mangle and compress JS libraries?
The difference between compressed and uncompressed JS is 45.6 kB.
Minifying (without mangling or compression) just
jscrypto
library reduces this difference to just 10.4 kB.Also,
boothworker-single.js
loadsjscrypto
scripts anyway, so if we imported them directly onvote.html
, we could leverage the browser's cache.Small improvement loading templates
jTemplate's
.setTemplateURL()
method fetched templates in a synchronous fashion.The current solution fetches them asynchronously, in parallel, reducing load time:
This change also solved a browser warning:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience
.