Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 30947x 30947x 30947x 30947x 30947x 30947x 30947x 1x 15474x 15474x 15474x 15474x 15474x 15474x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 150633x 15474x 15474x 14908x 14908x 15474x 15474x 268x 268x 268x 268x 15474x 15474x 304x 296x 296x 8x 8x 304x 11x 3x 3x 8x 11x 11x 5x 5x 5x 11x 8x 8x 15474x 15474x | import * as Expressions from "../abap/2_statements/expressions";
import * as Statements from "../abap/2_statements/statements";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Issue} from "../issue";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
export class ForbiddenKernelWriteConf extends BasicRuleConfig {
/** Objects allowed to use WRITE '@KERNEL', array of string regex matched against the object name.
* Empty, the default, allows every object
* @uniqueItems true
*/
public allow: string[] = [];
}
export class ForbiddenKernelWrite extends ABAPRule {
private conf = new ForbiddenKernelWriteConf();
private allow: RegExp[] = [];
public getMetadata(): IRuleMetadata {
return {
key: "forbidden_kernel_write",
title: "Forbidden kernel WRITE",
shortDescription: `Forbid WRITE '@KERNEL' outside the listed objects`,
extendedInformation: `The transpiler emits the literal of WRITE '@KERNEL ...' as raw JavaScript,
which runs with the privileges of the host. Open-abap uses this for its kernel classes, code compiled by a host it did not write should not.
allow is a list of regex, case insensitive, matched against the object name, eg. ["^CL_", "^KERNEL_"].
An empty list, the default, allows every object. To forbid WRITE '@KERNEL' everywhere use a regex matching no name, eg. ["^$"].`,
tags: [RuleTag.SingleFile, RuleTag.Security],
badExample: `WRITE '@KERNEL process.exit(1);'.`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: ForbiddenKernelWriteConf): void {
this.conf = conf;
if (this.conf.allow === undefined) {
this.conf.allow = [];
}
this.allow = this.conf.allow.map(a => new RegExp(a, "i"));
}
public runParsed(file: ABAPFile, obj: ABAPObject): Issue[] {
if (this.allow.length === 0 || this.allow.some(a => a.test(obj.getName()))) {
return [];
}
const ret: Issue[] = [];
for (const s of file.getStatements()) {
if (!(s.get() instanceof Statements.Write)) {
continue;
}
// same check as the transpiler, statements/write.ts
const source = s.findDirectExpression(Expressions.Source)?.concatTokens();
if (source?.startsWith("'@KERNEL ") === true) {
const message = "WRITE '@KERNEL' not allowed in " + obj.getName();
ret.push(Issue.atStatement(file, s, message, this.getMetadata().key, this.conf.severity));
}
}
return ret;
}
}
|