
Электроотрицательность — это инструмент для выявления неверных конфигураций и антипаттернов безопасности в приложениях Electron.
⚠️ Мы больше не активно поддерживаем этот проект ⚠️
Electronegativity — это инструмент для выявления неправильных конфигураций и анти-паттернов безопасности в приложениях на базе Electron.
Он использует синтаксический анализ AST и DOM для поиска конфигураций, связанных с безопасностью, как описано в статье "Electron Security Checklist - A Guide for Developers and Auditors".
Разработчики программного обеспечения и аудиторы безопасности могут использовать этот инструмент для обнаружения и устранения потенциальных уязвимостей и ошибок реализации при разработке приложений с использованием Electron. По-прежнему требуется хорошее понимание (не)безопасности Electron при использовании Electronegativity, так как некоторые из потенциальных проблем, обнаруженных инструментом, требуют ручного исследования.
Если вы интересуетесь безопасностью Electron, ознакомьтесь с нашим исследованием BlackHat 2017 Electronegativity - A Study of Electron Security и следите за блогом Doyensec.

Если вам нужно что-то более мощное или обновлённое, улучшенный SAST-инструмент на основе Electronegativity доступен как результат многолетних прикладных НИОКР от Doyensec. В конце 2020 года мы сели и создали дорожную карту проекта и собрали команду разработчиков для работы над тем, что сейчас называется ElectroNG. Вы можете прочитать о некоторых крупных улучшениях по сравнению с OSS-версией в недавнем посте в блоге.
Основные релизы публикуются в NPM и могут быть просто установлены с помощью:
$ npm install @doyensec/electronegativity -g
$ electronegativity -h
Использование electronegativity для поиска проблем в директории, содержащей приложение Electron:
$ electronegativity -i /path/to/electron/app
Использование electronegativity для поиска проблем в архиве asar и сохранение результатов в csv-файл:
$ electronegativity -i /path/to/asar/archive -o result.csv
Использование electronegativity при обновлении с одной версии Electron на другую для поиска критических изменений:
$ electronegativity -i /path/to/electron/app -v -u 7..8
Примечание: если вы столкнулись с фатальной ошибкой "JavaScript heap out of memory", вы можете запустить node с помощью node --max-old-space-size=4096 electronegativity -i /path/to/asar/archive -o result.csv
Electronegativity позволяет отключать отдельные проверки с помощью комментариев eng-disable. Например, если вы хотите, чтобы конкретная проверка игнорировала строку кода, вы можете отключить её следующим образом:
const res = eval(safeVariable); /* eng-disable DANGEROUS_FUNCTIONS_JS_CHECK */
<webview src="https://doyensec.com/" enableblinkfeatures="DangerousFeature"></webview> <!-- eng-disable BLINK_FEATURES_HTML_CHECK -->
Любой встроенный комментарий eng-disable (// eng-disable, /* eng-disable */, <!-- eng-disable -->) отключит указанную проверку только для этой строки. Также можно указать несколько имён проверок, используя как их snake case ID (DANGEROUS_FUNCTIONS_JS_CHECK), так и имена конструкторов (dangerousFunctionsJSCheck):
shell.openExternal(eval(safeVar)); /* eng-disable OPEN_EXTERNAL_JS_CHECK DANGEROUS_FUNCTIONS_JS_CHECK */
Если вы поместите директиву eng-disable перед любым кодом в начале файла .js или .html, это отключит переданные проверки для всего файла.
eng-disableДо версии v1.9.0 глобальные проверки нельзя было отключить с помощью аннотаций кода. Если вы всё ещё используете старую версию, используйте аргумент CLI -x, чтобы вручную отключить список проверок (например, -x LimitNavigationJsCheck,PermissionRequestHandlerJsCheck,CSPGlobalCheck).
Обратите внимание, что использование аннотаций может быть неприменимо для некоторых высокоуровневых проверок, таких как CSP_GLOBAL_CHECK или AVAILABLE_SECURITY_FIXES_GLOBAL_CHECK. В таких случаях вы можете использовать флаг -x, чтобы исключить определённые проверки из сканирования.
Electronegativity Action может выполняться как часть вашего конвейера GitHub CI/CD для получения "Оповещений сканирования кода":

Вы также можете использовать electronegativity программно, используя аналогичные опции, как для CLI:
const run = require('@doyensec/electronegativity')
// или: import run from '@doyensec/electronegativity';
run({
// входные данные (директория, .js, .html, .asar)
input: '/path/to/electron/app',
// сохранить результаты в файл в формате csv или sarif (необязательно)
output: '/path/for/output/file',
// true для сохранения вывода в sarif, false для csv (необязательно)
isSarif: false,
// запускать только указанные проверки (необязательно)
customScan: ['dangerousfunctionsjscheck', 'remotemodulejscheck'],
// возвращать только находки с указанным или выше уровнем серьёзности (необязательно)
severitySet: 'high',
// возвращать только находки с указанным или выше уровнем уверенности (необязательно)
confidenceSet: 'certain',
// показывать относительный путь для файлов (необязательно)
isRelative: false,
// запустить проверки обновления Electron, например -u 7..8 для проверки обновления с Electron 7 до 8 (необязательно)
electronUpgrade: '7..8',
// указать версию Electron, переопределяя обнаруженную
electronVersion: '5.0.0',
// использовать дополнительные плагины парсера
parserPlugins: ['optionalChaining']
})
.then(result => console.log(result))
.catch(err => console.error(err));
Результат содержит количество глобальных и атомарных проверок, любые ошибки, возникшие при разборе, и массив найденных проблем, например:
{
globalChecks: 6,
atomicChecks: 36,
errors: [
{
file: 'ts/main/main.ts',
sample: 'shell.openExternal(url);',
location: { line: 328, column: 4 },
id: 'OPEN_EXTERNAL_JS_CHECK',
description: 'Review the use of openExternal',
properties: undefined,
severity: { value: 2, name: 'MEDIUM', format: [Function: format] },
confidence: { value: 0, name: 'TENTATIVE', format: [Function: format] },
manualReview: true,
shortenedURL: 'https://git.io/JeuMC'
},
{
file: 'ts/main/main.ts',
sample: 'const popup = new BrowserWindow(options);',
location: { line: 340, column: 18 },
id: 'CONTEXT_ISOLATION_JS_CHECK',
description: 'Review the use of the contextIsolation option',
properties: undefined,
severity: { value: 3, name: 'HIGH', format: [Function: format] },
confidence: { value: 1, name: 'FIRM', format: [Function: format] },
manualReview: false,
shortenedURL: 'https://git.io/Jeu1p'
}
]
}
Если вы думаете о внесении вклада в этот проект, пожалуйста, ознакомьтесь с нашим CONTRIBUTING.md.
Electronegativity стал возможен благодаря работе многих участников.
Этот проект был спонсирован Doyensec LLC.
Пригласите нас взломать ваше приложение Electron.js!
| Опция | Описание |
|---|
| -V | вывести номер версии |
| -i, --input | входные данные (директория, .js, .html, .asar) |
| -l, --checks | запускать только указанные проверки, передаются в формате csv |
| -x, --exclude-checks | пропустить указанный список проверок, передаётся в формате csv |
| -s, --severity | возвращать только находки с указанным или выше уровнем серьёзности |
| -c, --confidence | возвращать только находки с указанным или выше уровнем уверенности |
| -o, --output <filename[.csv or .sarif]> | сохранить результаты в файл в формате csv или sarif |
| -r, --relative | показывать относительный путь для файлов |
| -v, --verbose | показывать описание находок, по умолчанию true |
| -u, --upgrade | запустить проверки обновления Electron, например -u 7..8 для проверки обновления с Electron 7 до 8 |
| -e, --electron-version | указать версию Electron, переопределяя обнаруженную, например -e 7.0.0 для обработки как Electron 7 |
| -p, --parser-plugins | указать дополнительные плагины парсера через запятую, например -p optionalChaining |
| -h, --help | вывести информацию об использовании |