Verify sticker data in getDataFromLink
This commit is contained in:
parent
333feaa81e
commit
aaed0db2e5
5 changed files with 178 additions and 13 deletions
2
js/modules/stickers.d.ts
vendored
2
js/modules/stickers.d.ts
vendored
|
@ -10,4 +10,6 @@ export function downloadStickerPack(
|
||||||
}
|
}
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
|
export function isPackIdValid(packId: unknown): packId is string;
|
||||||
|
|
||||||
export function redactPackId(packId: string): string;
|
export function redactPackId(packId: string): string;
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
navigator,
|
navigator,
|
||||||
reduxStore,
|
reduxStore,
|
||||||
reduxActions,
|
reduxActions,
|
||||||
URL
|
URL,
|
||||||
|
URLSearchParams
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const BLESSED_PACKS = {
|
const BLESSED_PACKS = {
|
||||||
|
@ -27,10 +28,11 @@ const BLESSED_PACKS = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const VALID_PACK_ID_REGEXP = /^[0-9a-f]{32}$/i;
|
||||||
|
|
||||||
const { isNumber, pick, reject, groupBy, values } = require('lodash');
|
const { isNumber, pick, reject, groupBy, values } = require('lodash');
|
||||||
const pMap = require('p-map');
|
const pMap = require('p-map');
|
||||||
const Queue = require('p-queue').default;
|
const Queue = require('p-queue').default;
|
||||||
const qs = require('qs');
|
|
||||||
|
|
||||||
const { makeLookup } = require('../../ts/util/makeLookup');
|
const { makeLookup } = require('../../ts/util/makeLookup');
|
||||||
const {
|
const {
|
||||||
|
@ -65,6 +67,7 @@ module.exports = {
|
||||||
load,
|
load,
|
||||||
maybeDeletePack,
|
maybeDeletePack,
|
||||||
downloadQueuedPacks,
|
downloadQueuedPacks,
|
||||||
|
isPackIdValid,
|
||||||
redactPackId,
|
redactPackId,
|
||||||
removeEphemeralPack,
|
removeEphemeralPack,
|
||||||
savePackMetadata,
|
savePackMetadata,
|
||||||
|
@ -90,18 +93,36 @@ async function load() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataFromLink(link) {
|
function getDataFromLink(link) {
|
||||||
const { hash } = new URL(link);
|
let url;
|
||||||
|
try {
|
||||||
|
url = new URL(link);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { hash } = url;
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = hash.slice(1);
|
let params;
|
||||||
const params = qs.parse(data);
|
try {
|
||||||
|
params = new URLSearchParams(hash.slice(1));
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
const id = params.get('pack_id');
|
||||||
id: params.pack_id,
|
if (!isPackIdValid(id)) {
|
||||||
key: params.pack_key,
|
return null;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
const key = params.get('pack_key');
|
||||||
|
if (!key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { id, key };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInstalledStickerPacks() {
|
function getInstalledStickerPacks() {
|
||||||
|
@ -231,6 +252,10 @@ function getInitialState() {
|
||||||
return initialState;
|
return initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPackIdValid(packId) {
|
||||||
|
return typeof packId === 'string' && VALID_PACK_ID_REGEXP.test(packId);
|
||||||
|
}
|
||||||
|
|
||||||
function redactPackId(packId) {
|
function redactPackId(packId) {
|
||||||
return `[REDACTED]${packId.slice(-3)}`;
|
return `[REDACTED]${packId.slice(-3)}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2963,11 +2963,13 @@
|
||||||
pack.status === 'downloaded' ||
|
pack.status === 'downloaded' ||
|
||||||
pack.status === 'installed');
|
pack.status === 'installed');
|
||||||
|
|
||||||
let id;
|
const dataFromLink = window.Signal.Stickers.getDataFromLink(url);
|
||||||
let key;
|
if (!dataFromLink) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { id, key } = dataFromLink;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
({ id, key } = window.Signal.Stickers.getDataFromLink(url));
|
|
||||||
const keyBytes = window.Signal.Crypto.bytesFromHexString(key);
|
const keyBytes = window.Signal.Crypto.bytesFromHexString(key);
|
||||||
const keyBase64 = window.Signal.Crypto.arrayBufferToBase64(keyBytes);
|
const keyBase64 = window.Signal.Crypto.arrayBufferToBase64(keyBytes);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,142 @@
|
||||||
const { Stickers } = Signal;
|
const { Stickers } = Signal;
|
||||||
|
|
||||||
describe('Stickers', () => {
|
describe('Stickers', () => {
|
||||||
|
describe('getDataFromLink', () => {
|
||||||
|
it('returns null for invalid URLs', () => {
|
||||||
|
assert.isNull(Stickers.getDataFromLink('https://'));
|
||||||
|
assert.isNull(Stickers.getDataFromLink('signal.art/addstickers/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null for URLs that don't have a hash", () => {
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink('https://signal.art/addstickers/')
|
||||||
|
);
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink('https://signal.art/addstickers/#')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when no key or pack ID is found', () => {
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a&pack_key='
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e&pack_id='
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when the pack ID is invalid', () => {
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=garbage&pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null if the ID or key are passed as arrays', () => {
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id[]=c8c83285b547872ac4c589d64a6edd6a&pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert.isNull(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a&pack_key[]=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses the ID and key from the hash', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a&pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e'
|
||||||
|
),
|
||||||
|
{
|
||||||
|
id: 'c8c83285b547872ac4c589d64a6edd6a',
|
||||||
|
key:
|
||||||
|
'59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores additional hash parameters', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a&pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e&pack_foo=bar'
|
||||||
|
),
|
||||||
|
{
|
||||||
|
id: 'c8c83285b547872ac4c589d64a6edd6a',
|
||||||
|
key:
|
||||||
|
'59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only parses the first ID and key from the hash if more than one is supplied', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
Stickers.getDataFromLink(
|
||||||
|
'https://signal.art/addstickers/#pack_id=c8c83285b547872ac4c589d64a6edd6a&pack_key=59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e&pack_id=extra&pack_key=extra'
|
||||||
|
),
|
||||||
|
{
|
||||||
|
id: 'c8c83285b547872ac4c589d64a6edd6a',
|
||||||
|
key:
|
||||||
|
'59bb3a8860f0e6a5a83a5337a015c8d55ecd2193f82d77202f3b8112a845636e',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isPackIdValid', () => {
|
||||||
|
it('returns false for non-strings', () => {
|
||||||
|
assert.isFalse(Stickers.isPackIdValid(undefined));
|
||||||
|
assert.isFalse(Stickers.isPackIdValid(null));
|
||||||
|
assert.isFalse(Stickers.isPackIdValid(123));
|
||||||
|
assert.isFalse(Stickers.isPackIdValid(123));
|
||||||
|
assert.isFalse(
|
||||||
|
Stickers.isPackIdValid(['b9439fa5fdc8b9873fe64f01b88b8ccf'])
|
||||||
|
);
|
||||||
|
assert.isFalse(
|
||||||
|
// eslint-disable-next-line no-new-wrappers
|
||||||
|
Stickers.isPackIdValid(new String('b9439fa5fdc8b9873fe64f01b88b8ccf'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for invalid pack IDs', () => {
|
||||||
|
assert.isFalse(Stickers.isPackIdValid(''));
|
||||||
|
assert.isFalse(
|
||||||
|
Stickers.isPackIdValid('x9439fa5fdc8b9873fe64f01b88b8ccf')
|
||||||
|
);
|
||||||
|
assert.isFalse(
|
||||||
|
// This is one character too short.
|
||||||
|
Stickers.isPackIdValid('b9439fa5fdc8b9873fe64f01b88b8cc')
|
||||||
|
);
|
||||||
|
assert.isFalse(
|
||||||
|
// This is one character too long.
|
||||||
|
Stickers.isPackIdValid('b9439fa5fdc8b9873fe64f01b88b8ccfa')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns true for valid pack IDs', () => {
|
||||||
|
assert.isTrue(Stickers.isPackIdValid('b9439fa5fdc8b9873fe64f01b88b8ccf'));
|
||||||
|
assert.isTrue(Stickers.isPackIdValid('3eff225a1036a58a7530b312dd92f8d8'));
|
||||||
|
assert.isTrue(Stickers.isPackIdValid('DDFD48B8097DA7A4E928192B10963F6A'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('redactPackId', () => {
|
describe('redactPackId', () => {
|
||||||
it('redacts pack IDs', () => {
|
it('redacts pack IDs', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
|
|
@ -271,7 +271,7 @@
|
||||||
"rule": "jQuery-load(",
|
"rule": "jQuery-load(",
|
||||||
"path": "js/modules/stickers.js",
|
"path": "js/modules/stickers.js",
|
||||||
"line": "async function load() {",
|
"line": "async function load() {",
|
||||||
"lineNumber": 77,
|
"lineNumber": 80,
|
||||||
"reasonCategory": "falseMatch",
|
"reasonCategory": "falseMatch",
|
||||||
"updated": "2019-04-26T17:48:30.675Z"
|
"updated": "2019-04-26T17:48:30.675Z"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue