Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add a warning to the console to discourage attacks and encourage contributing #7608

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/KeyBindingsDefaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
NavigationAction,
RoomAction,
RoomListAction,
WindowAction,
} from "./KeyBindingsManager";
import { isMac, Key } from "./Keyboard";
import SettingsStore from "./settings/SettingsStore";
Expand Down Expand Up @@ -411,10 +412,30 @@ const navigationBindings = (): KeyBinding<NavigationAction>[] => {
];
};

const windowBindings = (): KeyBinding<WindowAction>[] => {
return [
{
action: WindowAction.OpenBrowserDevtools,
keyCombo: {
key: Key.F12,
},
},
{
action: WindowAction.OpenBrowserDevtools,
keyCombo: {
key: Key.I,
shiftKey: true,
ctrlOrCmd: true,
},
},
];
};

export const defaultBindingsProvider: IKeyBindingsProvider = {
getMessageComposerBindings: messageComposerBindings,
getAutocompleteBindings: autocompleteBindings,
getRoomListBindings: roomListBindings,
getRoomBindings: roomBindings,
getNavigationBindings: navigationBindings,
getWindowBindings: windowBindings,
};
11 changes: 11 additions & 0 deletions src/KeyBindingsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ export enum NavigationAction {
SelectNextUnreadRoom = 'SelectNextUnreadRoom',
}

/** Actions for navigating do various menus, dialogs or screens */
export enum WindowAction {
/** Open browser devtools */
OpenBrowserDevtools = 'OpenBrowserDevtools'
}

/**
* Represent a key combination.
*
Expand Down Expand Up @@ -213,6 +219,7 @@ export interface IKeyBindingsProvider {
getRoomListBindings: KeyBindingGetter<RoomListAction>;
getRoomBindings: KeyBindingGetter<RoomAction>;
getNavigationBindings: KeyBindingGetter<NavigationAction>;
getWindowBindings: KeyBindingGetter<WindowAction>;
}

export class KeyBindingsManager {
Expand Down Expand Up @@ -264,6 +271,10 @@ export class KeyBindingsManager {
getNavigationAction(ev: KeyboardEvent | React.KeyboardEvent): NavigationAction | undefined {
return this.getAction(this.bindingsProviders.map(it => it.getNavigationBindings), ev);
}

getWindowAction(ev: KeyboardEvent | React.KeyboardEvent): WindowAction | undefined {
return this.getAction(this.bindingsProviders.map(it => it.getWindowBindings), ev);
}
}

const manager = new KeyBindingsManager();
Expand Down
13 changes: 13 additions & 0 deletions src/Keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ export const Key = {
X: "x",
Y: "y",
Z: "z",

F1: "F1",
F2: "F2",
F3: "F3",
F4: "F4",
F5: "F5",
F6: "F6",
F7: "F7",
F8: "F8",
F9: "F9",
F10: "F10",
F11: "F11",
F12: "F12",
};

export const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
Expand Down
35 changes: 35 additions & 0 deletions src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ import FeedbackDialog from "../views/dialogs/FeedbackDialog";
import AccessibleButton from "../views/elements/AccessibleButton";
import { ActionPayload } from "../../dispatcher/payloads";
import { SummarizedNotificationState } from "../../stores/notifications/SummarizedNotificationState";
import { getKeyBindingsManager, WindowAction } from "../../KeyBindingsManager";

/** constants for MatrixChat.state.view */
export enum Views {
Expand Down Expand Up @@ -439,6 +440,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.setState({ pendingInitialSync: false });
}

public componentDidMount(): void {
window.addEventListener("keydown", this.onKeyDown);
}

// TODO: [REACT-WARNING] Replace with appropriate lifecycle stage
// eslint-disable-next-line
UNSAFE_componentWillUpdate(props, state) {
Expand All @@ -461,6 +466,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}

componentWillUnmount() {
window.removeEventListener("keydown", this.onKeyDown);
Lifecycle.stopMatrixClient();
dis.unregister(this.dispatcherRef);
this.themeWatcher.stop();
Expand All @@ -471,6 +477,35 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
if (this.accountPasswordTimer !== null) clearTimeout(this.accountPasswordTimer);
}

private onKeyDown = (event: KeyboardEvent): void => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can open the devtools in many more ways, e.g Inspect Element, browser's View menu etc

image

So I don't think this is fool-proof enough and a good scammer could just instruct them to use one of those instead of the keyboard shortcut to avoid this warning

Copy link
Contributor Author

@SimonBrandner SimonBrandner Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Args, I am notan idiot... Though I have no idea how to detect the console in another way...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could do it on viewport resize (unreliable way of detecting console state) but that's still far from ideal, maybe make a localStorage flag which enables debug log and otherwise hide non-critical/bug console.logs.

element-hq/element-web#2803 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not, only I am an idiot but I am also blind 🤦‍♂️

Thanks, will have a look

const windowAction = getKeyBindingsManager().getWindowAction(event);
switch (windowAction) {
case WindowAction.OpenBrowserDevtools: {
const largeFontSize = "50px";
const normalFontSize = "15px";

const waitText = _t("Wait!");
const scamText = _t(
"If someone told you to copy/paste something here, " +
"there is a high likelihood you're being scammed!",
);
const devText = _t(
"If you know what you're doing, Element is open-source, "+
"be sure to check out our GitHub (https://github.com/vector-im/element-web/) " +
"and contribute!",
);

console.log(
`%c${waitText}\n%c${scamText}\n%c${devText}`,
`font-size:${largeFontSize}; color:blue;`,
`font-size:${normalFontSize}; color:red;`,
`font-size:${normalFontSize};`,
);
break;
}
}
};

public trackScreenChange(durationMs: number): void {
const notLoggedInMap = {};
notLoggedInMap[Views.LOADING] = "WebLoading";
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -3035,6 +3035,9 @@
"Private community": "Private community",
"To view %(communityName)s, swap to communities in your <a>preferences</a>": "To view %(communityName)s, swap to communities in your <a>preferences</a>",
"To join %(communityName)s, swap to communities in your <a>preferences</a>": "To join %(communityName)s, swap to communities in your <a>preferences</a>",
"Wait!": "Wait!",
"If someone told you to copy/paste something here, there is a high likelihood you're being scammed!": "If someone told you to copy/paste something here, there is a high likelihood you're being scammed!",
"If you know what you're doing, Element is open-source, be sure to check out our GitHub (https://github.com/vector-im/element-web/) and contribute!": "If you know what you're doing, Element is open-source, be sure to check out our GitHub (https://github.com/vector-im/element-web/) and contribute!",
"Failed to reject invitation": "Failed to reject invitation",
"Cannot create rooms in this community": "Cannot create rooms in this community",
"You do not have permission to create rooms in this community.": "You do not have permission to create rooms in this community.",
Expand Down