tslint-config-security
Version:
TSLint security rules
85 lines (84 loc) • 4.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var Lint = require("tslint");
var ts = require("typescript");
var fs_module_methods_arguments_info_1 = require("../fs-module-methods-arguments-info");
var node_kind_1 = require("../node-kind");
var Rule = (function (_super) {
tslib_1.__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithFunction(sourceFile, walk);
};
Rule.metadata = {
ruleName: 'tsr-detect-non-literal-fs-filename',
description: 'Warns when methods of Node.js FileSystem API are used with non-literal argument as a filename',
descriptionDetails: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["Any usage of Node.js FileSystem methods\n with non-literal argument as a filename will trigger a warning.\n See https://github.com/webschik/tslint-config-security#tsr-detect-non-literal-fs-filename"], ["Any usage of Node.js FileSystem methods\n with non-literal argument as a filename will trigger a warning.\n See https://github.com/webschik/tslint-config-security#tsr-detect-non-literal-fs-filename"]))),
optionsDescription: '',
options: null,
type: 'functionality',
requiresTypeInfo: false,
typescriptOnly: false
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var expressionsToCheck = ['fs', "require('fs')", 'require("fs")', 'require(`fs`)'];
var reservedIdentifiers = ['__dirname'];
function walk(ctx) {
function visitNode(node) {
if (node.kind === ts.SyntaxKind.PropertyAccessExpression) {
var _a = node, expression = _a.expression, name = _a.name;
if (name && node.parent && expression) {
var methodName = name.text;
var parent = node.parent;
var fsArgsInfo = fs_module_methods_arguments_info_1.default.get(methodName);
var methodArguments_1 = parent.arguments;
if (fsArgsInfo && methodArguments_1 && expressionsToCheck.includes(expression.getText())) {
var invalidArgumentIndices = fsArgsInfo.filter(function (index) {
var arg = methodArguments_1[index];
if (!arg) {
return false;
}
var kind = arg.kind;
if (kind === ts.SyntaxKind.BinaryExpression) {
var _a = arg, left = _a.left, right = _a.right;
if (left &&
left.kind === ts.SyntaxKind.Identifier &&
reservedIdentifiers.includes(left.text)) {
return Boolean(right && !node_kind_1.stringLiteralKinds.includes(right.kind));
}
if (right &&
right.kind === ts.SyntaxKind.Identifier &&
reservedIdentifiers.includes(right.text)) {
return Boolean(left && !node_kind_1.stringLiteralKinds.includes(left.kind));
}
}
if (kind === ts.SyntaxKind.TemplateExpression) {
var _b = arg.templateSpans, templateSpans = _b === void 0 ? [] : _b;
var firstTemplateSpan = templateSpans[0];
var firstTemplateSpanExpr = firstTemplateSpan && firstTemplateSpan.expression;
if (firstTemplateSpanExpr &&
firstTemplateSpanExpr.kind === ts.SyntaxKind.Identifier &&
reservedIdentifiers.includes(firstTemplateSpanExpr.getText()) &&
!templateSpans[1]) {
return false;
}
}
return !node_kind_1.stringLiteralKinds.includes(kind);
});
if (invalidArgumentIndices[0] !== undefined) {
var errorIndex = invalidArgumentIndices.join(', ');
ctx.addFailureAtNode(node, "Found fs." + methodName + " with non-literal argument at index " + errorIndex);
}
}
}
}
return ts.forEachChild(node, visitNode);
}
return ts.forEachChild(ctx.sourceFile, visitNode);
}
var templateObject_1;