Skip to content

Commit 56eafc9

Browse files
authored
Switch to secure random strings (#29013)
* Switch to secure random strings Because the js-sdk methods are changing and there's no reason for these not to use the secure versions. The dedicated upper/lower functions were *only* used in this one case, so this should do the exact same thing with the one exported function. Requires matrix-org/matrix-js-sdk#4621 (merge both together) * Change remaining instances of randomString which I somehow entirely missed the first time. * Fix import order
1 parent 1644169 commit 56eafc9

File tree

15 files changed

+38
-33
lines changed

15 files changed

+38
-33
lines changed

src/components/views/elements/LabelledToggleSwitch.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
88

99
import React from "react";
1010
import classNames from "classnames";
11-
import { randomString } from "matrix-js-sdk/src/randomstring";
11+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1212

1313
import ToggleSwitch from "./ToggleSwitch";
1414
import { Caption } from "../typography/Caption";
@@ -36,7 +36,7 @@ interface IProps {
3636
}
3737

3838
export default class LabelledToggleSwitch extends React.PureComponent<IProps> {
39-
private readonly id = `mx_LabelledToggleSwitch_${randomString(12)}`;
39+
private readonly id = `mx_LabelledToggleSwitch_${secureRandomString(12)}`;
4040

4141
public render(): React.ReactNode {
4242
// This is a minimal version of a SettingsFlag

src/components/views/elements/SettingsFlag.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
88
*/
99

1010
import React from "react";
11-
import { randomString } from "matrix-js-sdk/src/randomstring";
11+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1212

1313
import SettingsStore from "../../../settings/SettingsStore";
1414
import { _t } from "../../../languageHandler";
@@ -35,7 +35,7 @@ interface IState {
3535
}
3636

3737
export default class SettingsFlag extends React.Component<IProps, IState> {
38-
private readonly id = `mx_SettingsFlag_${randomString(12)}`;
38+
private readonly id = `mx_SettingsFlag_${secureRandomString(12)}`;
3939

4040
public constructor(props: IProps) {
4141
super(props);

src/components/views/elements/StyledCheckbox.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
77
*/
88

99
import React, { Ref } from "react";
10-
import { randomString } from "matrix-js-sdk/src/randomstring";
10+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1111
import classnames from "classnames";
1212

1313
export enum CheckboxStyle {
@@ -33,7 +33,7 @@ export default class StyledCheckbox extends React.PureComponent<IProps, IState>
3333
public constructor(props: IProps) {
3434
super(props);
3535
// 56^10 so unlikely chance of collision.
36-
this.id = this.props.id || "checkbox_" + randomString(10);
36+
this.id = this.props.id || "checkbox_" + secureRandomString(10);
3737
}
3838

3939
public render(): React.ReactNode {

src/components/views/messages/MBeaconBody.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
ContentHelpers,
1919
M_BEACON,
2020
} from "matrix-js-sdk/src/matrix";
21-
import { randomString } from "matrix-js-sdk/src/randomstring";
21+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
2222
import classNames from "classnames";
2323

2424
import MatrixClientContext from "../../../contexts/MatrixClientContext";
@@ -81,10 +81,10 @@ const useBeaconState = (
8181
// eg thread and main timeline, reply
8282
// maplibregl needs a unique id to attach the map instance to
8383
const useUniqueId = (eventId: string): string => {
84-
const [id, setId] = useState(`${eventId}_${randomString(8)}`);
84+
const [id, setId] = useState(`${eventId}_${secureRandomString(8)}`);
8585

8686
useEffect(() => {
87-
setId(`${eventId}_${randomString(8)}`);
87+
setId(`${eventId}_${secureRandomString(8)}`);
8888
}, [eventId]);
8989

9090
return id;

src/components/views/messages/MLocationBody.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
88

99
import React from "react";
1010
import { MatrixEvent, ClientEvent, ClientEventHandlerMap } from "matrix-js-sdk/src/matrix";
11-
import { randomString } from "matrix-js-sdk/src/randomstring";
11+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1212
import { Tooltip } from "@vector-im/compound-web";
1313

1414
import { _t } from "../../../languageHandler";
@@ -41,7 +41,7 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
4141

4242
// multiple instances of same map might be in document
4343
// eg thread and main timeline, reply
44-
const idSuffix = `${props.mxEvent.getId()}_${randomString(8)}`;
44+
const idSuffix = `${props.mxEvent.getId()}_${secureRandomString(8)}`;
4545
this.mapId = `mx_MLocationBody_${idSuffix}`;
4646

4747
this.reconnectedListener = createReconnectedListener(this.clearError);

src/models/Call.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
} from "matrix-js-sdk/src/matrix";
1919
import { KnownMembership, Membership } from "matrix-js-sdk/src/types";
2020
import { logger } from "matrix-js-sdk/src/logger";
21-
import { randomString } from "matrix-js-sdk/src/randomstring";
21+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
2222
import { CallType } from "matrix-js-sdk/src/webrtc/call";
2323
import { NamespacedValue } from "matrix-js-sdk/src/NamespacedValue";
2424
import { IWidgetApiRequest } from "matrix-widget-api";
@@ -743,7 +743,7 @@ export class ElementCall extends Call {
743743
const url = ElementCall.generateWidgetUrl(client, roomId);
744744
return WidgetStore.instance.addVirtualWidget(
745745
{
746-
id: randomString(24), // So that it's globally unique
746+
id: secureRandomString(24), // So that it's globally unique
747747
creatorUserId: client.getUserId()!,
748748
name: "Element Call",
749749
type: WidgetType.CALL.preferred,

src/rageshake/rageshake.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Please see LICENSE files in the repository root for full details.
3131

3232
// the frequency with which we flush to indexeddb
3333
import { logger } from "matrix-js-sdk/src/logger";
34-
import { randomString } from "matrix-js-sdk/src/randomstring";
34+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
3535

3636
import { getCircularReplacer } from "../utils/JSON";
3737

@@ -135,7 +135,7 @@ export class IndexedDBLogStore {
135135
private indexedDB: IDBFactory,
136136
private logger: ConsoleLogger,
137137
) {
138-
this.id = "instance-" + randomString(16);
138+
this.id = "instance-" + secureRandomString(16);
139139
}
140140

141141
/**

src/utils/WidgetUtils.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ Please see LICENSE files in the repository root for full details.
99

1010
import { useCallback, useEffect, useState } from "react";
1111
import { base32 } from "rfc4648";
12+
import { capitalize } from "lodash";
1213
import { IWidget, IWidgetData } from "matrix-widget-api";
1314
import { Room, ClientEvent, MatrixClient, RoomStateEvent, MatrixEvent } from "matrix-js-sdk/src/matrix";
1415
import { KnownMembership } from "matrix-js-sdk/src/types";
1516
import { logger } from "matrix-js-sdk/src/logger";
1617
import { CallType } from "matrix-js-sdk/src/webrtc/call";
17-
import { randomString, randomLowercaseString, randomUppercaseString } from "matrix-js-sdk/src/randomstring";
18+
import { LOWERCASE, secureRandomString, secureRandomStringFrom } from "matrix-js-sdk/src/randomstring";
1819

1920
import PlatformPeg from "../PlatformPeg";
2021
import SdkConfig from "../SdkConfig";
@@ -427,7 +428,10 @@ export default class WidgetUtils {
427428
): Promise<void> {
428429
const domain = Jitsi.getInstance().preferredDomain;
429430
const auth = (await Jitsi.getInstance().getJitsiAuth()) ?? undefined;
430-
const widgetId = randomString(24); // Must be globally unique
431+
432+
// Must be globally unique, although predicatablity is not important, the js-sdk has functions to generate
433+
// secure ranom strings, and speed is not important here.
434+
const widgetId = secureRandomString(24);
431435

432436
let confId: string;
433437
if (auth === "openidtoken-jwt") {
@@ -437,8 +441,8 @@ export default class WidgetUtils {
437441
// https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
438442
confId = base32.stringify(new TextEncoder().encode(roomId), { pad: false });
439443
} else {
440-
// Create a random conference ID
441-
confId = `Jitsi${randomUppercaseString(1)}${randomLowercaseString(23)}`;
444+
// Create a random conference ID (capitalised so the name looks sensible in Jitsi)
445+
confId = `Jitsi${capitalize(secureRandomStringFrom(24, LOWERCASE))}`;
442446
}
443447

444448
// TODO: Remove URL hacks when the mobile clients eventually support v2 widgets

src/utils/oidc/authorize.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
99
import { completeAuthorizationCodeGrant, generateOidcAuthorizationUrl } from "matrix-js-sdk/src/oidc/authorize";
1010
import { QueryDict } from "matrix-js-sdk/src/utils";
1111
import { OidcClientConfig } from "matrix-js-sdk/src/matrix";
12-
import { randomString } from "matrix-js-sdk/src/randomstring";
12+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1313
import { IdTokenClaims } from "oidc-client-ts";
1414

1515
import { OidcClientError } from "./error";
@@ -34,7 +34,7 @@ export const startOidcLogin = async (
3434
): Promise<void> => {
3535
const redirectUri = PlatformPeg.get()!.getOidcCallbackUrl().href;
3636

37-
const nonce = randomString(10);
37+
const nonce = secureRandomString(10);
3838

3939
const prompt = isRegistration ? "create" : undefined;
4040

src/vector/platform/ElectronPlatform.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Please see LICENSE files in the repository root for full details.
1212

1313
import { MatrixClient, Room, MatrixEvent, OidcRegistrationClientMetadata } from "matrix-js-sdk/src/matrix";
1414
import React from "react";
15-
import { randomString } from "matrix-js-sdk/src/randomstring";
15+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1616
import { logger } from "matrix-js-sdk/src/logger";
1717

1818
import BasePlatform, { UpdateCheckStatus, UpdateStatus } from "../../BasePlatform";
@@ -93,7 +93,7 @@ export default class ElectronPlatform extends BasePlatform {
9393
private readonly ipc = new IPCManager("ipcCall", "ipcReply");
9494
private readonly eventIndexManager: BaseEventIndexManager = new SeshatIndexManager();
9595
// this is the opaque token we pass to the HS which when we get it in our callback we can resolve to a profile
96-
private readonly ssoID: string = randomString(32);
96+
private readonly ssoID: string = secureRandomString(32);
9797

9898
public constructor() {
9999
super();

test/setupTests.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
88

99
import "@testing-library/jest-dom";
1010
import "blob-polyfill";
11-
import { randomString } from "matrix-js-sdk/src/randomstring";
11+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1212
import { mocked } from "jest-mock";
1313

1414
import { PredictableRandom } from "./test-utils/predictableRandom"; // https://github.com/jsdom/jsdom/issues/2555
@@ -25,7 +25,8 @@ jest.mock("matrix-js-sdk/src/randomstring");
2525
beforeEach(() => {
2626
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2727
const mockRandom = new PredictableRandom();
28-
mocked(randomString).mockImplementation((len) => {
28+
// needless to say, the mock is not cryptographically secure
29+
mocked(secureRandomString).mockImplementation((len) => {
2930
let ret = "";
3031
for (let i = 0; i < len; ++i) {
3132
const v = mockRandom.get() * chars.length;

test/test-utils/poll.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
M_POLL_RESPONSE,
1919
M_TEXT,
2020
} from "matrix-js-sdk/src/matrix";
21-
import { randomString } from "matrix-js-sdk/src/randomstring";
21+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
2222

2323
import { flushPromises } from "./utilities";
2424

@@ -67,7 +67,7 @@ export const makePollEndEvent = (
6767
id?: string,
6868
): MatrixEvent => {
6969
return new MatrixEvent({
70-
event_id: id || randomString(16),
70+
event_id: id || secureRandomString(16),
7171
room_id: roomId,
7272
origin_server_ts: ts,
7373
type: M_POLL_END.name,
@@ -91,7 +91,7 @@ export const makePollResponseEvent = (
9191
ts = 0,
9292
): MatrixEvent =>
9393
new MatrixEvent({
94-
event_id: randomString(16),
94+
event_id: secureRandomString(16),
9595
room_id: roomId,
9696
origin_server_ts: ts,
9797
type: M_POLL_RESPONSE.name,

test/unit-tests/components/views/settings/Notifications-test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
IThreepid,
2424
ThreepidMedium,
2525
} from "matrix-js-sdk/src/matrix";
26-
import { randomString } from "matrix-js-sdk/src/randomstring";
26+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
2727
import {
2828
act,
2929
fireEvent,
@@ -287,7 +287,7 @@ describe("<Notifications />", () => {
287287

288288
beforeEach(async () => {
289289
let i = 0;
290-
mocked(randomString).mockImplementation(() => {
290+
mocked(secureRandomString).mockImplementation(() => {
291291
return "testid_" + i++;
292292
});
293293

test/unit-tests/components/views/spaces/SpaceSettingsVisibilityTab-test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
88

99
import React from "react";
1010
import { mocked } from "jest-mock";
11-
import { randomString } from "matrix-js-sdk/src/randomstring";
11+
import { secureRandomString } from "matrix-js-sdk/src/randomstring";
1212
import { act, fireEvent, render, RenderResult } from "jest-matrix-react";
1313
import { EventType, MatrixClient, Room, GuestAccess, HistoryVisibility, JoinRule } from "matrix-js-sdk/src/matrix";
1414

@@ -92,7 +92,7 @@ describe("<SpaceSettingsVisibilityTab />", () => {
9292

9393
beforeEach(() => {
9494
let i = 0;
95-
mocked(randomString).mockImplementation(() => {
95+
mocked(secureRandomString).mockImplementation(() => {
9696
return "testid_" + i++;
9797
});
9898

test/unit-tests/utils/oidc/authorize-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe("OIDC authorization", () => {
4949
origin: baseUrl,
5050
};
5151

52-
jest.spyOn(randomStringUtils, "randomString").mockRestore();
52+
jest.spyOn(randomStringUtils, "secureRandomString").mockRestore();
5353
mockPlatformPeg();
5454
Object.defineProperty(window, "crypto", {
5555
value: {

0 commit comments

Comments
 (0)