From 9003d26beeb01a3865332f4a0c7e44a35908dc5d Mon Sep 17 00:00:00 2001 From: MrChuckomo Date: Fri, 16 Jul 2021 15:33:35 +0200 Subject: [PATCH 1/2] Update favorite.js # refactor code # add todos for cleaning html strings --- app/js/favorite.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/js/favorite.js b/app/js/favorite.js index 6ecd33b..2cf2bc9 100644 --- a/app/js/favorite.js +++ b/app/js/favorite.js @@ -1,16 +1,17 @@ +'use strict' -function setFavorite(_Self, _ArtistName, _CollectionName, _Artwork30, _Artwork60, _Artwork100, _FeedUrl) -{ - var Feed = - { - "artistName": _ArtistName, - "collectionName": _CollectionName, - "artworkUrl30": _Artwork30, - "artworkUrl60": _Artwork60, - "artworkUrl100": _Artwork100, - "feedUrl": _FeedUrl, - "addToInbox": true, - "feedUrlStatus": 200 // Set default URL status to 200 +function setFavorite(_Self, _ArtistName, _CollectionName, _Artwork30, _Artwork60, _Artwork100, _FeedUrl) { + // TODO: Clean feed information before pushing to save file + + let Feed = { + 'artistName': _ArtistName, + 'collectionName': _CollectionName, + 'artworkUrl30': _Artwork30, + 'artworkUrl60': _Artwork60, + 'artworkUrl100': _Artwork100, + 'feedUrl': _FeedUrl, + 'addToInbox': true, + 'feedUrlStatus': 200 // Set default URL status to 200 } _Self.innerHTML = s_HeartFilled From d074277d7e65644e19340b41fec449e5f34ba6ae Mon Sep 17 00:00:00 2001 From: MrChuckomo Date: Fri, 16 Jul 2021 17:05:20 +0200 Subject: [PATCH 2/2] Sanitize strings # sanitize strings as much as possible to avoid code injection # refactor code --- app/js/favorite.js | 12 +++---- app/js/feed.js | 15 ++++---- app/js/helper/helper_global.js | 62 ++++++++++++++++++++++------------ app/js/list_item.js | 12 +++---- 4 files changed, 58 insertions(+), 43 deletions(-) diff --git a/app/js/favorite.js b/app/js/favorite.js index 2cf2bc9..d595204 100644 --- a/app/js/favorite.js +++ b/app/js/favorite.js @@ -1,14 +1,12 @@ 'use strict' function setFavorite(_Self, _ArtistName, _CollectionName, _Artwork30, _Artwork60, _Artwork100, _FeedUrl) { - // TODO: Clean feed information before pushing to save file - let Feed = { - 'artistName': _ArtistName, - 'collectionName': _CollectionName, - 'artworkUrl30': _Artwork30, - 'artworkUrl60': _Artwork60, - 'artworkUrl100': _Artwork100, + 'artistName': sanitizeString(_ArtistName), + 'collectionName': sanitizeString(_CollectionName), + 'artworkUrl30': sanitizeString(_Artwork30), + 'artworkUrl60': sanitizeString(_Artwork60), + 'artworkUrl100': sanitizeString(_Artwork100), 'feedUrl': _FeedUrl, 'addToInbox': true, 'feedUrlStatus': 200 // Set default URL status to 200 diff --git a/app/js/feed.js b/app/js/feed.js index 5ea9b0c..a71e7a7 100644 --- a/app/js/feed.js +++ b/app/js/feed.js @@ -281,8 +281,8 @@ function processEpisodes(_Content) { // NOTE: set settings information - document.getElementsByClassName('settings-image')[0].src = Artwork - document.getElementsByClassName('settings-header')[0].innerHTML = ChannelName + document.getElementsByClassName('settings-image')[0].src = sanitizeString(Artwork) + document.getElementsByClassName('settings-header')[0].innerHTML = sanitizeString(ChannelName) document.getElementsByClassName('settings-count')[0].innerHTML = xmlDoc.getElementsByTagName('item').length let List = document.getElementById('list') @@ -292,8 +292,7 @@ function processEpisodes(_Content) { // NOTE: Just enter if the current item contains an enclosure tag - if (Item.getElementsByTagName("enclosure").length > 0) - { + if (Item.getElementsByTagName("enclosure").length > 0) { var EpisodeTitle = Item.getElementsByTagName("title")[0].childNodes[0].nodeValue var EpisodeLength = Item.getElementsByTagName("enclosure")[0].getAttribute("length") var EpisodeType = Item.getElementsByTagName("enclosure")[0].getAttribute("type") @@ -341,13 +340,13 @@ function processEpisodes(_Content) { } ListElement.setAttribute('onclick', 'playNow(this)') - ListElement.setAttribute('channel', ChannelName) - ListElement.setAttribute('title', EpisodeTitle) + ListElement.setAttribute('channel', sanitizeString(ChannelName)) + ListElement.setAttribute('title', sanitizeString(EpisodeTitle)) ListElement.setAttribute('type', EpisodeType) - ListElement.setAttribute('url', EpisodeUrl) + ListElement.setAttribute('url', sanitizeString(EpisodeUrl)) ListElement.setAttribute('length', EpisodeLength) ListElement.setAttribute('duration', Duration) - ListElement.setAttribute('description', EpisodeDescription) + ListElement.setAttribute('description', sanitizeString(EpisodeDescription)) ListElement.setAttribute('artworkUrl', Artwork) List.append(ListElement) diff --git a/app/js/helper/helper_global.js b/app/js/helper/helper_global.js index a67da50..eb06615 100644 --- a/app/js/helper/helper_global.js +++ b/app/js/helper/helper_global.js @@ -69,8 +69,7 @@ function init() { } // check if user has old settings file - if (fs.existsSync(getSettingsFilePath())) - { + if (fs.existsSync(getSettingsFilePath())) { upgradeSettingsFile() } @@ -86,49 +85,68 @@ function init() { darkMode() - document.getElementById("volume").value = getPreference('volume') - document.getElementById("volume").dispatchEvent(new Event("input")) + document.getElementById('volume').value = getPreference('volume') + document.getElementById('volume').dispatchEvent(new Event('input')) document.querySelector('#content-right-player-speed-indicator').innerHTML = getPreference('playspeed').toFixed(1) + "x" - document.getElementById("player").playbackRate = parseFloat(getPreference('playspeed')) - document.getElementById("player").defaultPlaybackRate = parseFloat(getPreference('playspeed')) + document.getElementById('player').playbackRate = parseFloat(getPreference('playspeed')) + document.getElementById('player').defaultPlaybackRate = parseFloat(getPreference('playspeed')) } function fileExistsAndIsNotEmpty(_File) { return (fs.existsSync(_File) && fs.readFileSync(_File, 'utf-8') !== '') } -function upgradeSettingsFile() -{ +function sanitizeString(input) { + // https://owasp.org/www-community/xss-filter-evasion-cheatsheet + // TODO: Whitelist malicious code + // TODO: remove and cleanup code (using regex) + // TODO: return clean string + + // const patterns = [ + // /img/im, + // /src=/im, + // /sript/im + // ] + + // for (let index = 0; index < patterns.length; index++) { + // const pattern = patterns[index]; + + // console.log(input.match(pattern)) + // } + + let temp = document.createElement('div'); + temp.innerHTML = input; + let sanitized = temp.textContent || temp.innerText; + + return sanitized +} + +function upgradeSettingsFile() { var oldFilePath = getSettingsFilePath() var newFilePath = getSaveFilePath() - + // sync addToInbox values from old settings file - if (fs.existsSync(oldFilePath) && fs.readFileSync(oldFilePath, "utf-8") != "") - { - var JsonContent = JSON.parse(fs.readFileSync(oldFilePath, "utf-8")) + if (fs.existsSync(oldFilePath) && fs.readFileSync(oldFilePath, 'utf-8') != '') { + var JsonContent = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8')) - for (var i = 0; i < JsonContent.length; i++) - { + for (let i = 0; i < JsonContent.length; i++) { setIsAddedToInbox(JsonContent[i].feedUrl, JsonContent[i].addToInbox) } } // create addToInbox value to any remaining items in the favorites file - if (fs.existsSync(newFilePath) && fs.readFileSync(newFilePath, "utf-8") != "") - { - var JsonContent = JSON.parse(fs.readFileSync(newFilePath, "utf-8")) + if (fs.existsSync(newFilePath) && fs.readFileSync(newFilePath, 'utf-8') != '') { + var JsonContent = JSON.parse(fs.readFileSync(newFilePath, 'utf-8')) - for (var i = 0; i < JsonContent.length; i++) - { - if (!JsonContent[i].hasOwnProperty('addToInbox')) - { + for (var i = 0; i < JsonContent.length; i++) { + if (!JsonContent[i].hasOwnProperty('addToInbox')) { setIsAddedToInbox(JsonContent[i].feedUrl, true) } } } // rename old settings file so that it is not processed again in the future - fs.renameSync(oldFilePath, oldFilePath + ".old") + fs.renameSync(oldFilePath, oldFilePath + '.old') } function isAlreadySaved(_FeedUrl) diff --git a/app/js/list_item.js b/app/js/list_item.js index 13d4c84..cf29b31 100644 --- a/app/js/list_item.js +++ b/app/js/list_item.js @@ -42,7 +42,7 @@ function getImagePart(_Artwork) { function getBoldTextPart(_Text) { let TextElement = document.createElement('div') - TextElement.innerHTML = _Text + TextElement.innerHTML = sanitizeString(_Text) TextElement.classList.add('list-item-bold-text') return TextElement @@ -51,7 +51,7 @@ function getBoldTextPart(_Text) { function getTextPart(_Text) { let TextElement = document.createElement('div') - TextElement.innerHTML = _Text + TextElement.innerHTML = sanitizeString(_Text) TextElement.classList.add('list-item-text') return TextElement @@ -61,7 +61,7 @@ function getDescriptionPart(_Icon, _Text) { let TextElement = document.createElement('div') TextElement.innerHTML = _Icon - TextElement.title = _Text + TextElement.title = sanitizeString(_Text) TextElement.classList.add('list-item-description') TextElement.classList.add('list-item-icon') @@ -71,7 +71,7 @@ function getDescriptionPart(_Icon, _Text) { function getSubTextPart(_Text) { let TextElement = document.createElement('div') - TextElement.innerHTML = _Text + TextElement.innerHTML = sanitizeString(_Text) TextElement.classList.add('list-item-sub-text') return TextElement @@ -80,7 +80,7 @@ function getSubTextPart(_Text) { function getFlagPart(_Text, _Color, _BackgroundColor) { let FlagElement = document.createElement('div') - FlagElement.innerHTML = _Text + FlagElement.innerHTML = sanitizeString(_Text) FlagElement.style.color = _Color FlagElement.style.backgroundColor = _BackgroundColor FlagElement.classList.add('list-item-flag') @@ -91,7 +91,7 @@ function getFlagPart(_Text, _Color, _BackgroundColor) { function getTextButtonPart(_Text) { let ButtonElement = document.createElement('button') - ButtonElement.text = _Text + ButtonElement.text = sanitizeString(_Text) return ButtonElement }