diff --git a/internal/services/engines/javascript/rule_manager.go b/internal/services/engines/javascript/rule_manager.go index dfa64e6ca..b455d4f82 100644 --- a/internal/services/engines/javascript/rule_manager.go +++ b/internal/services/engines/javascript/rule_manager.go @@ -82,6 +82,8 @@ func Rules() []engine.Rule { NewCreatingCookiesWithoutTheHttpOnlyFlag(), NewCreatingCookiesWithoutTheSecureFlag(), NewNoUseSocketManually(), + NewMongoDbHardCodedCredentialsSecuritySensitive(), + NewPostgresqlHardCodedCredentialsSecuritySensitive(), // Or rules NewEncryptionAlgorithmsWeak(), diff --git a/internal/services/engines/javascript/rules.go b/internal/services/engines/javascript/rules.go index e8a672be1..86d3b0608 100644 --- a/internal/services/engines/javascript/rules.go +++ b/internal/services/engines/javascript/rules.go @@ -389,7 +389,6 @@ func NewReadingTheStandardInput() *text.Rule { Type: text.Regular, Expressions: []*regexp.Regexp{ regexp.MustCompile(`process\.stdin.read\(\)`), - regexp.MustCompile(`process\.stdin`), }, } } @@ -498,7 +497,7 @@ func NewInsecureDownload() *text.Rule { }, Type: text.Regular, Expressions: []*regexp.Regexp{ - regexp.MustCompile(`(fetch|get|download)*\(.*(?:http:).*.(\.sh|\.exe|\.cmd|\.bat|\.dll|\.txt)`), + regexp.MustCompile(`(fetch|get|download)*\(.*(?:http:).*.(\.sh|\.exe|\.cmd|\.bat|\.dll|\.txt|\.js|\.go|\.bin)`), }, } } @@ -555,7 +554,7 @@ func NewCryptographicRsaShouldBeRobust() *text.Rule { Type: text.AndMatch, Expressions: []*regexp.Regexp{ regexp.MustCompile(`(modulusLength:\s*)([0-9][^\d]|[0-9]{2}[^\d]|[0-9]{3}[^\d]|[0-1][0-9]{3}[^\d]|20[0-3][0-9]|204[0-7])`), - regexp.MustCompile(`\.generateKeyPairSync\(.*rsa`), + regexp.MustCompile(`generateKeyPairSync|generateKeyPair\(.*rsa`), }, } } @@ -574,7 +573,7 @@ func NewCryptographicEcShouldBeRobust() *text.Rule { Type: text.AndMatch, Expressions: []*regexp.Regexp{ regexp.MustCompile(`(namedCurve:.*secp)([0-9][^\d]|[0-9]{2}[^\d]|[0-2][0-2][0-3][^\d])`), - regexp.MustCompile(`\.generateKeyPairSync\(.*ec`), + regexp.MustCompile(`generateKeyPairSync|generateKeyPair\(.*ec`), }, } } @@ -612,7 +611,7 @@ func NewServerHostnameNotVerified() *text.Rule { }, Type: text.AndMatch, Expressions: []*regexp.Regexp{ - regexp.MustCompile(`checkServerIdentity.*\{\s*\}`), + regexp.MustCompile(`checkServerIdentity`), regexp.MustCompile(`(\.request\(|request\.|\.connect\()`), }, } @@ -689,7 +688,7 @@ func NewUsingShellInterpreterWhenExecutingOSCommands() *text.Rule { }, Type: text.AndMatch, Expressions: []*regexp.Regexp{ - regexp.MustCompile(`(\.exec\(|\.execSync\(|\.spawn\(|\.spawnSync\(|\.execFile\(|\.execFileSync\()((.*,(.|\s)*shell\s*:\strue)|(("|')?(\w|\s)+("|')?[^,]\))|(.*,.*\{)(([^s]|s[^h]|sh[^e]|she[^l]|shel[^l])*)(\}))`), + regexp.MustCompile(`(exec\(|execSync\(|spawn\(|spawnSync\(|execFile\(|execFileSync\()((.*,(.|\s)*shell\s*:\strue)|(("|')?(\w|\s)+("|')?[^,]\))|(.*,.*\{)(([^s]|s[^h]|sh[^e]|she[^l]|shel[^l])*)(\}))`), regexp.MustCompile(`child_process`), }, } @@ -749,7 +748,7 @@ func NewAllowingBrowsersToPerformDNSPrefetching() *text.Rule { Type: text.AndMatch, Expressions: []*regexp.Regexp{ regexp.MustCompile(`allow\s*:\s*true`), - regexp.MustCompile(`dnsPrefetchControl\(`), + regexp.MustCompile(`dnsPrefetchControl`), regexp.MustCompile(`helmet`), }, } @@ -788,7 +787,7 @@ func NewDisablingStrictHTTPNoReferrerPolicy() *text.Rule { Type: text.AndMatch, Expressions: []*regexp.Regexp{ regexp.MustCompile(`policy\s*:(\s|.)*no-referrer-when-downgrade`), - regexp.MustCompile(`\.referrerPolicy\(`), + regexp.MustCompile(`referrerPolicy`), regexp.MustCompile(`helmet`), }, } @@ -828,7 +827,7 @@ func NewDisablingContentSecurityPolicyFrameAncestorsDirective() *text.Rule { Expressions: []*regexp.Regexp{ regexp.MustCompile(`frameAncestors\s*:(\s|.)*none`), regexp.MustCompile(`helmet`), - regexp.MustCompile(`\.contentSecurityPolicy\(`), + regexp.MustCompile(`contentSecurityPolicy`), }, } } @@ -848,7 +847,7 @@ func NewAllowingMixedContent() *text.Rule { Expressions: []*regexp.Regexp{ regexp.MustCompile(`(directives\s*:\s*\{)(([^b]|b[^l]|bl[^o]|blo[^c]|bloc[^k]|block[^A]|blockA[^l]|blockAl[^l]|blockAll[^M]|blockAllM[^i]|blockAllMi[^x]|blockAllMix[^e]|blockAllMixe[^d]|blockAllMixed[^C]|blockAllMixedC[^o]|blockAllMixedCo[^n]|blockAllMixedCon[^t]|blockAllMixedCont[^e]|blockAllMixedConte[^n]|blockAllMixedConten[^t])*)(\})`), regexp.MustCompile(`helmet`), - regexp.MustCompile(`\.contentSecurityPolicy\(`), + regexp.MustCompile(`contentSecurityPolicy`), }, } } @@ -921,7 +920,7 @@ func NewNoUseSocketManually() *text.Rule { SafeExample: SampleSafeHSJAVASCRIPT48, UnsafeExample: SampleVulnerableHSJAVASCRIPT48, }, - Type: text.Regular, + Type: text.AndMatch, Expressions: []*regexp.Regexp{ regexp.MustCompile(`new.*Socket\(`), regexp.MustCompile(`require\(.net.\)|from\s.net.`), @@ -1028,3 +1027,42 @@ func NewSQLInjection() *text.Rule { }, } } + +func NewMongoDbHardCodedCredentialsSecuritySensitive() *text.Rule { + return &text.Rule{ + Metadata: engine.Metadata{ + ID: "HS-JAVASCRIPT-54", + Name: "MongoDb Hard-coded credentials are security-sensitive", + Description: "Because it is easy to extract strings from an application source code or binary, credentials should not be hard-coded. This is particularly true for applications that are distributed or that are open-source. It's recommended to customize the configuration of this rule with additional credential words such as \"oauthToken\", \"secret\", others. For more information checkout the CWE-798 (https://cwe.mitre.org/data/definitions/798.html) advisory.", + Severity: severities.Critical.ToString(), + Confidence: confidence.High.ToString(), + SafeExample: SampleSafeHSJAVASCRIPT54, + UnsafeExample: SampleVulnerableHSJAVASCRIPT54, + }, + Type: text.AndMatch, + Expressions: []*regexp.Regexp{ + regexp.MustCompile(`\.connect\(\s*["|']\S+["|']`), + regexp.MustCompile(`require\(.mongodb.\)|from\s.mongodb.`), + }, + } +} + +func NewPostgresqlHardCodedCredentialsSecuritySensitive() *text.Rule { + return &text.Rule{ + Metadata: engine.Metadata{ + ID: "HS-JAVASCRIPT-55", + Name: "Postgresql Hard-coded credentials are security-sensitive", + Description: "Because it is easy to extract strings from an application source code or binary, credentials should not be hard-coded. This is particularly true for applications that are distributed or that are open-source. It's recommended to customize the configuration of this rule with additional credential words such as \"oauthToken\", \"secret\", others. For more information checkout the CWE-798 (https://cwe.mitre.org/data/definitions/798.html) advisory.", + Severity: severities.Critical.ToString(), + Confidence: confidence.High.ToString(), + SafeExample: SampleSafeHSJAVASCRIPT35, + UnsafeExample: SampleVulnerableHSJAVASCRIPT35, + }, + Type: text.AndMatch, + Expressions: []*regexp.Regexp{ + regexp.MustCompile(`(host|user|database|password|port):\s*["|']\w+["|']`), + regexp.MustCompile(`new Client\(\{`), + regexp.MustCompile(`require\(.pg.\)|from\s.pg.`), + }, + } +} diff --git a/internal/services/engines/javascript/rules_test.go b/internal/services/engines/javascript/rules_test.go index 8395163e8..0fbfd7889 100644 --- a/internal/services/engines/javascript/rules_test.go +++ b/internal/services/engines/javascript/rules_test.go @@ -394,6 +394,614 @@ func TestRulesVulnerableCode(t *testing.T) { }, }, }, + { + Name: "HS-JAVASCRIPT-20", + Rule: NewReadingTheStandardInput(), + Src: SampleVulnerableHSJAVASCRIPT20, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-20.test"), + Findings: []engine.Finding{ + { + CodeSample: `var input = process.stdin.read();`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-20.test"), + Line: 3, + Column: 13, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-21", + Rule: NewUsingCommandLineArguments(), + Src: SampleVulnerableHSJAVASCRIPT21, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-21.test"), + Findings: []engine.Finding{ + { + CodeSample: `console.exec(process.argv[0])`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-21.test"), + Line: 3, + Column: 1, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-22", + Rule: NewRedirectToUnknownPath(), + Src: SampleVulnerableHSJAVASCRIPT22, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-22.test"), + Findings: []engine.Finding{ + { + CodeSample: `redirect(path);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-22.test"), + Line: 4, + Column: 1, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-23", + Rule: NewNoRenderContentFromRequest(), + Src: SampleVulnerableHSJAVASCRIPT23, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-23.test"), + Findings: []engine.Finding{ + { + CodeSample: `return response.render(req.body.data);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-23.test"), + Line: 3, + Column: 16, + }, + }, + { + CodeSample: `return response.send(req.body.content);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-23.test"), + Line: 7, + Column: 16, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-24", + Rule: NewNoWriteOnDocumentContentFromRequest(), + Src: SampleVulnerableHSJAVASCRIPT24, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-24.test"), + Findings: []engine.Finding{ + { + CodeSample: `return document.write(req.body.data);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-24.test"), + Line: 3, + Column: 8, + }, + }, + { + CodeSample: `return body.write(req.body.content);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-24.test"), + Line: 7, + Column: 8, + }, + }, + { + CodeSample: `return element.write(req.body.content);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-24.test"), + Line: 12, + Column: 8, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-25", + Rule: NewNoExposeStackTrace(), + Src: SampleVulnerableHSJAVASCRIPT25, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-25.test"), + Findings: []engine.Finding{ + { + CodeSample: `return res.send(err.stack);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-25.test"), + Line: 7, + Column: 9, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-26", + Rule: NewInsecureDownload(), + Src: SampleVulnerableHSJAVASCRIPT26, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-26.test"), + Findings: []engine.Finding{ + { + CodeSample: `const badBinary = axios.get('http://insecureDomain.com/program.bin');`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-26.test"), + Line: 3, + Column: 25, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-27", + Rule: NewNoUseRequestMethodUsingDataFromRequestOfUserInput(), + Src: SampleVulnerableHSJAVASCRIPT27, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-27.test"), + Findings: []engine.Finding{ + { + CodeSample: `import request from 'request';`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-27.test"), + Line: 2, + Column: 15, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-28", + Rule: NewNoUseGetMethodUsingDataFromRequestOfUserInput(), + Src: SampleVulnerableHSJAVASCRIPT28, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-28.test"), + Findings: []engine.Finding{ + { + CodeSample: `const res = request.get(req.body);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-28.test"), + Line: 4, + Column: 20, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-29", + Rule: NewCryptographicRsaShouldBeRobust(), + Src: SampleVulnerableHSJAVASCRIPT29, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-29.test"), + Findings: []engine.Finding{ + { + CodeSample: `modulusLength: 1024`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-29.test"), + Line: 4, + Column: 2, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-30", + Rule: NewCryptographicEcShouldBeRobust(), + Src: SampleVulnerableHSJAVASCRIPT30, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-30.test"), + Findings: []engine.Finding{ + { + CodeSample: `namedCurve: 'secp102k1'`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-30.test"), + Line: 4, + Column: 2, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-31", + Rule: NewJWTNeedStrongCipherAlgorithms(), + Src: SampleVulnerableHSJAVASCRIPT31, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-31.test"), + Findings: []engine.Finding{ + { + CodeSample: `var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'});`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-31.test"), + Line: 4, + Column: 52, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-32", + Rule: NewServerHostnameNotVerified(), + Src: SampleVulnerableHSJAVASCRIPT32, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-32.test"), + Findings: []engine.Finding{ + { + CodeSample: `checkServerIdentity: () => myCustomVerification()`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-32.test"), + Line: 4, + Column: 2, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-33", + Rule: NewServerCertificatesNotVerified(), + Src: SampleVulnerableHSJAVASCRIPT33, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-33.test"), + Findings: []engine.Finding{ + { + CodeSample: `rejectUnauthorized: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-33.test"), + Line: 3, + Column: 2, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-34", + Rule: NewUntrustedContentShouldNotBeIncluded(), + Src: SampleVulnerableHSJAVASCRIPT34, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-34.test"), + Findings: []engine.Finding{ + { + CodeSample: `element.setAttribute('src', req.body.data)`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-34.test"), + Line: 3, + Column: 8, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-35", + Rule: NewMysqlHardCodedCredentialsSecuritySensitive(), + Src: SampleVulnerableHSJAVASCRIPT35, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-35.test"), + Findings: []engine.Finding{ + { + CodeSample: `password: "root",`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-35.test"), + Line: 5, + Column: 3, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-36", + Rule: NewUsingShellInterpreterWhenExecutingOSCommands(), + Src: SampleVulnerableHSJAVASCRIPT36, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-36.test"), + Findings: []engine.Finding{ + { + CodeSample: `exec('chmod 666 /home/dev', { shell: true })`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-36.test"), + Line: 3, + Column: 0, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-37", + Rule: NewForwardingClientIPAddress(), + Src: SampleVulnerableHSJAVASCRIPT37, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-37.test"), + Findings: []engine.Finding{ + { + CodeSample: `xfwd: true`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-37.test"), + Line: 5, + Column: 2, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-38", + Rule: NewAllowingConfidentialInformationToBeLoggedWithSignale(), + Src: SampleVulnerableHSJAVASCRIPT38, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-38.test"), + Findings: []engine.Finding{ + { + CodeSample: `const logger = new Signale({ secrets: [] });`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-38.test"), + Line: 3, + Column: 30, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-39", + Rule: NewAllowingBrowsersToPerformDNSPrefetching(), + Src: SampleVulnerableHSJAVASCRIPT39, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-39.test"), + Findings: []engine.Finding{ + { + CodeSample: `dnsPrefetchControl:{ allow: true }`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-39.test"), + Line: 5, + Column: 25, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-40", + Rule: NewDisablingCertificateTransparencyMonitoring(), + Src: SampleVulnerableHSJAVASCRIPT40, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-40.test"), + Findings: []engine.Finding{ + { + CodeSample: `expectCt: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-40.test"), + Line: 5, + Column: 4, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-41", + Rule: NewDisablingStrictHTTPNoReferrerPolicy(), + Src: SampleVulnerableHSJAVASCRIPT41, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-41.test"), + Findings: []engine.Finding{ + { + CodeSample: `referrerPolicy: { policy: 'no-referrer-when-downgrade' }`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-41.test"), + Line: 7, + Column: 22, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-42", + Rule: NewAllowingBrowsersToSniffMIMETypes(), + Src: SampleVulnerableHSJAVASCRIPT42, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-42.test"), + Findings: []engine.Finding{ + { + CodeSample: `noSniff: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-42.test"), + Line: 7, + Column: 4, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-43", + Rule: NewDisablingContentSecurityPolicyFrameAncestorsDirective(), + Src: SampleVulnerableHSJAVASCRIPT43, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-43.test"), + Findings: []engine.Finding{ + { + CodeSample: `frameAncestors: ["'none'"],`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-43.test"), + Line: 8, + Column: 6, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-44", + Rule: NewAllowingMixedContent(), + Src: SampleVulnerableHSJAVASCRIPT44, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-44.test"), + Findings: []engine.Finding{ + { + CodeSample: `directives: {`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-44.test"), + Line: 7, + Column: 4, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-45", + Rule: NewDisablingContentSecurityPolicyFetchDirectives(), + Src: SampleVulnerableHSJAVASCRIPT45, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-45.test"), + Findings: []engine.Finding{ + { + CodeSample: `contentSecurityPolicy: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-45.test"), + Line: 7, + Column: 4, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-46", + Rule: NewCreatingCookiesWithoutTheHttpOnlyFlag(), + Src: SampleVulnerableHSJAVASCRIPT46, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-46.test"), + Findings: []engine.Finding{ + { + CodeSample: `httpOnly: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-46.test"), + Line: 7, + Column: 1, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-47", + Rule: NewCreatingCookiesWithoutTheSecureFlag(), + Src: SampleVulnerableHSJAVASCRIPT47, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-47.test"), + Findings: []engine.Finding{ + { + CodeSample: `secure: false`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-47.test"), + Line: 7, + Column: 1, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-48", + Rule: NewNoUseSocketManually(), + Src: SampleVulnerableHSJAVASCRIPT48, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-48.test"), + Findings: []engine.Finding{ + { + CodeSample: `const socket = new net.Socket();`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-48.test"), + Line: 3, + Column: 15, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-49", + Rule: NewEncryptionAlgorithmsWeak(), + Src: SampleVulnerableHSJAVASCRIPT49, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-49.test"), + Findings: []engine.Finding{ + { + CodeSample: `let cipher = crypto.createCipheriv('RC4', key, iv);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-49.test"), + Line: 6, + Column: 19, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-50", + Rule: NewFileUploadsShouldBeRestricted(), + Src: SampleVulnerableHSJAVASCRIPT50, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-50.test"), + Findings: []engine.Finding{ + { + CodeSample: `const form = new Formidable();`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-50.test"), + Line: 3, + Column: 13, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-51", + Rule: NewAllowingRequestsWithExcessiveContentLengthSecurity(), + Src: SampleVulnerableHSJAVASCRIPT51, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-51.test"), + Findings: []engine.Finding{ + { + CodeSample: `const form = new Formidable();`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-51.test"), + Line: 3, + Column: 13, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-52", + Rule: NewNoDisableSanitizeHtml(), + Src: SampleVulnerableHSJAVASCRIPT52, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-52.test"), + Findings: []engine.Finding{ + { + CodeSample: `Mustache.escape = function(text) {return text;};`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-52.test"), + Line: 4, + Column: 1, + }, + }, + { + CodeSample: `const markdownIt = require('markdown-it');`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-52.test"), + Line: 9, + Column: 6, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-53", + Rule: NewSQLInjection(), + Src: SampleVulnerableHSJAVASCRIPT53, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-53.test"), + Findings: []engine.Finding{ + { + CodeSample: `db.query("SELECT * FROM USERS WHERE EMAIL = " + name);`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-53.test"), + Line: 4, + Column: 3, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-54", + Rule: NewMongoDbHardCodedCredentialsSecuritySensitive(), + Src: SampleVulnerableHSJAVASCRIPT54, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-54.test"), + Findings: []engine.Finding{ + { + CodeSample: `MongoClient.connect("mongodb://localhost:27017/mydb", function(err, db) {`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-54.test"), + Line: 3, + Column: 11, + }, + }, + }, + }, + { + Name: "HS-JAVASCRIPT-55", + Rule: NewPostgresqlHardCodedCredentialsSecuritySensitive(), + Src: SampleVulnerableHSJAVASCRIPT55, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-55.test"), + Findings: []engine.Finding{ + { + CodeSample: `password: 'root',`, + SourceLocation: engine.Location{ + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-55.test"), + Line: 4, + Column: 1, + }, + }, + }, + }, } testutil.TestVulnerableCode(t, testcases) @@ -420,6 +1028,30 @@ func TestRulesSafeCode(t *testing.T) { Src: SampleSafeHSJAVASCRIPT3, Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-3.test"), }, + { + Name: "HS-JAVASCRIPT-4", + Rule: NewNoUseMD5Hashing(), + Src: SampleSafeHSJAVASCRIPT4, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-4.test"), + }, + { + Name: "HS-JAVASCRIPT-5", + Rule: NewNoUseSHA1Hashing(), + Src: SampleSafeHSJAVASCRIPT5, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-5.test"), + }, + { + Name: "HS-JAVASCRIPT-6", + Rule: NewNoUseWeakRandom(), + Src: SampleSafeHSJAVASCRIPT6, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-6.test"), + }, + { + Name: "HS-JAVASCRIPT-7", + Rule: NewNoReadFileUsingDataFromRequest(), + Src: SampleSafeHSJAVASCRIPT7, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-7.test"), + }, { Name: "HS-JAVASCRIPT-9", Rule: NewSQLInjectionUsingParams(), @@ -444,6 +1076,12 @@ func TestRulesSafeCode(t *testing.T) { Src: SampleSafeHSJAVASCRIPT12, Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-12.test"), }, + { + Name: "HS-JAVASCRIPT-16", + Rule: NewAlertStatementsShouldNotBeUsed(), + Src: SampleSafeHSJAVASCRIPT16, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-16.test"), + }, { Name: "HS-JAVASCRIPT-17", Rule: NewStaticallyServingHiddenFilesIsSecuritySensitive(), @@ -456,6 +1094,198 @@ func TestRulesSafeCode(t *testing.T) { Src: SampleSafeHSJAVASCRIPT19, Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-19.test"), }, + { + Name: "HS-JAVASCRIPT-21", + Rule: NewUsingCommandLineArguments(), + Src: SampleSafeHSJAVASCRIPT21, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-21.test"), + }, + { + Name: "HS-JAVASCRIPT-22", + Rule: NewRedirectToUnknownPath(), + Src: SampleSafeHSJAVASCRIPT22, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-22.test"), + }, + { + Name: "HS-JAVASCRIPT-23", + Rule: NewNoRenderContentFromRequest(), + Src: SampleSafeHSJAVASCRIPT23, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-23.test"), + }, + { + Name: "HS-JAVASCRIPT-24", + Rule: NewNoWriteOnDocumentContentFromRequest(), + Src: SampleSafeHSJAVASCRIPT24, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-24.test"), + }, + { + Name: "HS-JAVASCRIPT-25", + Rule: NewNoExposeStackTrace(), + Src: SampleSafeHSJAVASCRIPT25, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-25.test"), + }, + { + Name: "HS-JAVASCRIPT-26", + Rule: NewInsecureDownload(), + Src: SampleSafeHSJAVASCRIPT26, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-26.test"), + }, + { + Name: "HS-JAVASCRIPT-27", + Rule: NewNoUseRequestMethodUsingDataFromRequestOfUserInput(), + Src: SampleSafeHSJAVASCRIPT27, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-27.test"), + }, + { + Name: "HS-JAVASCRIPT-29", + Rule: NewCryptographicRsaShouldBeRobust(), + Src: SampleSafeHSJAVASCRIPT29, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-29.test"), + }, + { + Name: "HS-JAVASCRIPT-30", + Rule: NewCryptographicEcShouldBeRobust(), + Src: SampleSafeHSJAVASCRIPT30, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-30.test"), + }, + { + Name: "HS-JAVASCRIPT-31", + Rule: NewJWTNeedStrongCipherAlgorithms(), + Src: SampleSafeHSJAVASCRIPT31, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-31.test"), + }, + { + Name: "HS-JAVASCRIPT-32", + Rule: NewServerHostnameNotVerified(), + Src: SampleSafeHSJAVASCRIPT32, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-32.test"), + }, + { + Name: "HS-JAVASCRIPT-33", + Rule: NewServerCertificatesNotVerified(), + Src: SampleSafeHSJAVASCRIPT33, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-33.test"), + }, + { + Name: "HS-JAVASCRIPT-35", + Rule: NewMysqlHardCodedCredentialsSecuritySensitive(), + Src: SampleSafeHSJAVASCRIPT35, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-35.test"), + }, + { + Name: "HS-JAVASCRIPT-37", + Rule: NewForwardingClientIPAddress(), + Src: SampleSafeHSJAVASCRIPT37, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-37.test"), + }, + { + Name: "HS-JAVASCRIPT-38", + Rule: NewAllowingConfidentialInformationToBeLoggedWithSignale(), + Src: SampleSafeHSJAVASCRIPT38, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-38.test"), + }, + { + Name: "HS-JAVASCRIPT-39", + Rule: NewAllowingBrowsersToPerformDNSPrefetching(), + Src: SampleSafeHSJAVASCRIPT39, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-39.test"), + }, + { + Name: "HS-JAVASCRIPT-40", + Rule: NewDisablingCertificateTransparencyMonitoring(), + Src: SampleSafeHSJAVASCRIPT40, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-40.test"), + }, + { + Name: "HS-JAVASCRIPT-41", + Rule: NewDisablingStrictHTTPNoReferrerPolicy(), + Src: SampleSafeHSJAVASCRIPT41, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-41.test"), + }, + { + Name: "HS-JAVASCRIPT-42", + Rule: NewAllowingBrowsersToSniffMIMETypes(), + Src: SampleSafeHSJAVASCRIPT42, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-42.test"), + }, + { + Name: "HS-JAVASCRIPT-43", + Rule: NewDisablingContentSecurityPolicyFrameAncestorsDirective(), + Src: SampleSafeHSJAVASCRIPT43, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-43.test"), + }, + { + Name: "HS-JAVASCRIPT-44", + Rule: NewAllowingMixedContent(), + Src: SampleSafeHSJAVASCRIPT44, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-44.test"), + }, + { + Name: "HS-JAVASCRIPT-45", + Rule: NewDisablingContentSecurityPolicyFetchDirectives(), + Src: SampleSafeHSJAVASCRIPT45, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-45.test"), + }, + { + Name: "HS-JAVASCRIPT-46", + Rule: NewCreatingCookiesWithoutTheHttpOnlyFlag(), + Src: SampleSafeHSJAVASCRIPT46, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-46.test"), + }, + { + Name: "HS-JAVASCRIPT-47", + Rule: NewCreatingCookiesWithoutTheSecureFlag(), + Src: SampleSafeHSJAVASCRIPT47, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-47.test"), + }, + { + Name: "HS-JAVASCRIPT-48", + Rule: NewNoUseSocketManually(), + Src: SampleSafeHSJAVASCRIPT48, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-48.test"), + }, + { + Name: "HS-JAVASCRIPT-49", + Rule: NewEncryptionAlgorithmsWeak(), + Src: SampleSafeHSJAVASCRIPT49, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-49.test"), + }, + { + Name: "HS-JAVASCRIPT-50", + Rule: NewFileUploadsShouldBeRestricted(), + Src: SampleSafeHSJAVASCRIPT50, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-50.test"), + }, + { + Name: "HS-JAVASCRIPT-51", + Rule: NewAllowingRequestsWithExcessiveContentLengthSecurity(), + Src: SampleSafeHSJAVASCRIPT51, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-51.test"), + }, + { + Name: "HS-JAVASCRIPT-52", + Rule: NewNoDisableSanitizeHtml(), + Src: SampleSafeHSJAVASCRIPT52, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-52.test"), + }, + { + Name: "HS-JAVASCRIPT-53", + Rule: NewSQLInjection(), + Src: SampleSafeHSJAVASCRIPT53, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-53.test"), + }, + { + Name: "HS-JAVASCRIPT-54", + Rule: NewMongoDbHardCodedCredentialsSecuritySensitive(), + Src: SampleSafeHSJAVASCRIPT54, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-54.test"), + }, + { + Name: "HS-JAVASCRIPT-55", + Rule: NewPostgresqlHardCodedCredentialsSecuritySensitive(), + Src: SampleSafeHSJAVASCRIPT55, + Filename: filepath.Join(tempDir, "HS-JAVASCRIPT-55.test"), + }, } testutil.TestSafeCode(t, testcases) diff --git a/internal/services/engines/javascript/samples.go b/internal/services/engines/javascript/samples.go index 3b3345698..a5f1d6519 100644 --- a/internal/services/engines/javascript/samples.go +++ b/internal/services/engines/javascript/samples.go @@ -31,36 +31,45 @@ function f() { window.eval("any string") } ` - SampleVulnerableHSJAVASCRIPT3 = ` process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; ` - SampleSafeHSJAVASCRIPT3 = `` + SampleSafeHSJAVASCRIPT3 = `process.env.NODE_TLS_REJECT_UNAUTHORIZED = "1";` SampleVulnerableHSJAVASCRIPT4 = ` const hash = crypto.createHash('md5') ` - SampleSafeHSJAVASCRIPT4 = `` + SampleSafeHSJAVASCRIPT4 = `const hash = crypto.createHash('sha256')` SampleVulnerableHSJAVASCRIPT5 = ` const hash = crypto.createHash('sha1') ` - SampleSafeHSJAVASCRIPT5 = `` + SampleSafeHSJAVASCRIPT5 = `const hash = crypto.createHash('sha512')` SampleVulnerableHSJAVASCRIPT6 = ` function f() { return Math.random(); } ` - SampleSafeHSJAVASCRIPT6 = `` - + SampleSafeHSJAVASCRIPT6 = ` +function f() { + const randomBuffer = new Uint32Array(1); + (window.crypto || window.msCrypto).getRandomValues(randomBuffer); + const uint = randomBuffer[0]; +} +` SampleVulnerableHSJAVASCRIPT7 = ` function f(req) { return fs.readFileSync(req.body, 'utf8') } ` - SampleSafeHSJAVASCRIPT7 = `` - + SampleSafeHSJAVASCRIPT7 = ` +function f(req) { + const sanitize = require("sanitize-filename"); + const userInput = sanitize(req.body) + return fs.readFileSync(userInput, 'utf8') +} +` SampleVulnerableHSJAVASCRIPT8 = ` function f(req) { return fs.createReadStream(req.body) @@ -78,7 +87,6 @@ function f(foo) { Model.find({ where: { foo: foo}}); } ` - SampleVulnerableHSJAVASCRIPT10 = ` var libxml = require("libxmljs2"); @@ -89,7 +97,6 @@ var libxml = require("libxmljs2"); var xmlDoc = libxml.parseXmlString(xml); ` - SampleVulnerableHSJAVASCRIPT11 = ` function f() { var popup = window.open(); @@ -114,7 +121,6 @@ function f2() { }); } ` - SampleVulnerableHSJAVASCRIPT12 = ` function f() { const options = { @@ -127,7 +133,7 @@ function f2() { secureProtocol: 'TLSv1.1' } } - ` +` SampleSafeHSJAVASCRIPT12 = ` function f() { @@ -136,10 +142,9 @@ function f() { } } ` - SampleVulnerableHSJAVASCRIPT13 = ` const db = window.openDatabase(); - ` +` SampleSafeHSJAVASCRIPT13 = `` SampleVulnerableHSJAVASCRIPT14 = ` @@ -182,7 +187,6 @@ app.use('/', express.static('public', { app.use('/', express.static('public', { })); ` - SampleVulnerableHSJAVASCRIPT18 = ` function success(pos) { console.log(pos) @@ -217,105 +221,525 @@ app.get('/products/:id', cors(corsOptions), function (req, res, next) { }) ` - SampleVulnerableHSJAVASCRIPT20 = `` - SampleSafeHSJAVASCRIPT20 = `` - - SampleVulnerableHSJAVASCRIPT21 = `` - SampleSafeHSJAVASCRIPT21 = `` - - SampleVulnerableHSJAVASCRIPT22 = `` - SampleSafeHSJAVASCRIPT22 = `` - - SampleVulnerableHSJAVASCRIPT23 = `` - SampleSafeHSJAVASCRIPT23 = `` - - SampleVulnerableHSJAVASCRIPT24 = `` - SampleSafeHSJAVASCRIPT24 = `` - - SampleVulnerableHSJAVASCRIPT25 = `` - SampleSafeHSJAVASCRIPT25 = `` - - SampleVulnerableHSJAVASCRIPT26 = `` - SampleSafeHSJAVASCRIPT26 = `` - - SampleVulnerableHSJAVASCRIPT27 = `` - SampleSafeHSJAVASCRIPT27 = `` - - SampleVulnerableHSJAVASCRIPT28 = `` - SampleSafeHSJAVASCRIPT28 = `` - - SampleVulnerableHSJAVASCRIPT29 = `` - SampleSafeHSJAVASCRIPT29 = `` - - SampleVulnerableHSJAVASCRIPT30 = `` - SampleSafeHSJAVASCRIPT30 = `` - - SampleVulnerableHSJAVASCRIPT31 = `` - SampleSafeHSJAVASCRIPT31 = `` - - SampleVulnerableHSJAVASCRIPT32 = `` - SampleSafeHSJAVASCRIPT32 = `` - - SampleVulnerableHSJAVASCRIPT33 = `` - SampleSafeHSJAVASCRIPT33 = `` - - SampleVulnerableHSJAVASCRIPT34 = `` - SampleSafeHSJAVASCRIPT34 = `` - - SampleVulnerableHSJAVASCRIPT35 = `` - SampleSafeHSJAVASCRIPT35 = `` - - SampleVulnerableHSJAVASCRIPT36 = `` - SampleSafeHSJAVASCRIPT36 = `` - - SampleVulnerableHSJAVASCRIPT37 = `` - SampleSafeHSJAVASCRIPT37 = `` - - SampleVulnerableHSJAVASCRIPT38 = `` - SampleSafeHSJAVASCRIPT38 = `` + SampleVulnerableHSJAVASCRIPT20 = ` +function f() { + var input = process.stdin.read(); + console.log(input); +} +` + SampleSafeHSJAVASCRIPT20 = `` - SampleVulnerableHSJAVASCRIPT39 = `` - SampleSafeHSJAVASCRIPT39 = `` + SampleVulnerableHSJAVASCRIPT21 = ` +function f() { + console.exec(process.argv[0]) +} +` + SampleSafeHSJAVASCRIPT21 = ` +function f() { + var userArgs = mySanitizer(process.argv[0]) + console.exec(userArgs); +} +` + SampleVulnerableHSJAVASCRIPT22 = ` +function f() { + const { path } = req.body; + redirect(path); +} +` + SampleSafeHSJAVASCRIPT22 = ` +function f() { + const { path } = req.body; + const sanitizedPath = mySanitizer(path) + redirect('https://myOrigin/' + sanitizedPath); +} +` + SampleVulnerableHSJAVASCRIPT23 = ` +function f() { + return response.render(req.body.data); +} - SampleVulnerableHSJAVASCRIPT40 = `` - SampleSafeHSJAVASCRIPT40 = `` +function f() { + return response.send(req.body.content); +} +` + SampleSafeHSJAVASCRIPT23 = ` +function f() { + const { content } = req.body; + const sanitizedContent= mySanitizer(content) + return response.send(sanitizedContent) +} +` + SampleVulnerableHSJAVASCRIPT24 = ` +function f() { + return document.write(req.body.data); +} - SampleVulnerableHSJAVASCRIPT41 = `` - SampleSafeHSJAVASCRIPT41 = `` +function f() { + return body.write(req.body.content); +} - SampleVulnerableHSJAVASCRIPT42 = `` - SampleSafeHSJAVASCRIPT42 = `` +function f() { + const element = document.getElementById('title') + return element.write(req.body.content); +} +` + SampleSafeHSJAVASCRIPT24 = ` +function f() { + const { content } = req.body; + const element = document.getElementById('title') + const sanitizedContent= mySanitizer(content) + return element.write(sanitizedContent); +} +` + SampleVulnerableHSJAVASCRIPT25 = ` +function f() { + try { + const allUsers = db.users.getAll() + return res.send(allUsers) + } catch (err) { + return res.send(err.stack); + } +} +` + SampleSafeHSJAVASCRIPT25 = ` +function f() { + try { + const allUsers = db.users.getAll() + return res.send(allUsers) + } catch (err) { + MyServerSideLogger(err.stack); + return res.status(500); + } +} +` + SampleVulnerableHSJAVASCRIPT26 = ` +function f() { + const badBinary = axios.get('http://insecureDomain.com/program.bin'); + os.exec(badBinary); +} +` + SampleSafeHSJAVASCRIPT26 = ` +function f() { + const myBinary = axios.get('https://secureDomain.com/program.exe'); + os.exec(myBinary); +} +` + SampleVulnerableHSJAVASCRIPT27 = ` +import request from 'request'; - SampleVulnerableHSJAVASCRIPT43 = `` - SampleSafeHSJAVASCRIPT43 = `` +function f() { + require request from request.body; + request(req.body); +} +` + SampleSafeHSJAVASCRIPT27 = ` +function f() { + const { data } = req.body; + const safeData = MySanitizer(data) + return request(safeData); +} +` + SampleVulnerableHSJAVASCRIPT28 = ` +function f({ req, res }) { + var request = require('request'); + const res = request.get(req.body); + return res; +} +` + SampleSafeHSJAVASCRIPT28 = `` - SampleVulnerableHSJAVASCRIPT44 = `` - SampleSafeHSJAVASCRIPT44 = `` + SampleVulnerableHSJAVASCRIPT29 = ` +function f() { + const myKey = crypto.generateKeyPairSync('rsa', { + modulusLength: 1024 + }); +} +` + SampleSafeHSJAVASCRIPT29 = ` +function f() { + const myKey = crypto.generateKeyPairSync('rsa', { + modulusLength: 4096 + }); +} +` + SampleVulnerableHSJAVASCRIPT30 = ` +function f() { + const myKey = crypto.generateKeyPairSync('ec', { + namedCurve: 'secp102k1' + }); +} +` + SampleSafeHSJAVASCRIPT30 = ` +function f() { + const myKey = crypto.generateKeyPairSync('ec', { + namedCurve: 'secp521k1' + }); +} +` + SampleVulnerableHSJAVASCRIPT31 = ` +function f() { + var jwt = require('jsonwebtoken'); + var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'}); +} +` + SampleSafeHSJAVASCRIPT31 = ` +function f() { + var jwt = require('jsonwebtoken'); + var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'HS384'}); +} +` + SampleVulnerableHSJAVASCRIPT32 = ` +const tls = require('tls') +tls.connect({ + checkServerIdentity: () => myCustomVerification() +}) +` + SampleSafeHSJAVASCRIPT32 = ` +const tls = require('tls') +tls.connect() +` + SampleVulnerableHSJAVASCRIPT33 = ` +tls.connect({ + rejectUnauthorized: false +}) +` + SampleSafeHSJAVASCRIPT33 = ` +tls.connect({ + rejectUnauthorized: true +}) +` + SampleVulnerableHSJAVASCRIPT34 = ` +const element = createElement('script'); +element.setAttribute('src', req.body.data) +element.setAttribute('type', 'text/javascript') +` + SampleSafeHSJAVASCRIPT34 = `` - SampleVulnerableHSJAVASCRIPT45 = `` - SampleSafeHSJAVASCRIPT45 = `` + SampleVulnerableHSJAVASCRIPT35 = ` +var mysql = require('mysql'); - SampleVulnerableHSJAVASCRIPT46 = `` - SampleSafeHSJAVASCRIPT46 = `` +var con = mysql.createConnection({ + password: "root", + user: "root", + host: "localhost", +}); +` + SampleSafeHSJAVASCRIPT35 = ` +var mysql = require('mysql'); + +var con = mysql.createConnection({ + user: process.env.DB_USER, + password: process.env.DB_PASS + host: process.env.DB_HOST, +}); +` + SampleVulnerableHSJAVASCRIPT36 = ` +const { exec } = require('child_process'); +exec('chmod 666 /home/dev', { shell: true }) +` + SampleSafeHSJAVASCRIPT36 = `` - SampleVulnerableHSJAVASCRIPT47 = `` - SampleSafeHSJAVASCRIPT47 = `` + SampleVulnerableHSJAVASCRIPT37 = ` +import httpProxy from 'http-proxy' +function f() { + return new httpProxy.createProxyServer({ + xfwd: true + }); +} +` + SampleSafeHSJAVASCRIPT37 = ` +import httpProxy from 'http-proxy' +function f() { + return new httpProxy.createProxyServer({ + xfwd: false + }); +} +` + SampleVulnerableHSJAVASCRIPT38 = ` + const { Signale } = require('signale'); + const logger = new Signale({ secrets: [] }); +` + SampleSafeHSJAVASCRIPT38 = ` + const { Signale } = require('signale'); + const regexToRemoveSensitiveData = "([0-9]{4}-?)+"; + const logger = new Signale({ secrets: [regexToRemoveSensitiveData] }); +` + SampleVulnerableHSJAVASCRIPT39 = ` +const express = require('express'), +app = express(); +app.use(require('helmet')({ + dnsPrefetchControl:{ allow: true } +})); +` + SampleSafeHSJAVASCRIPT39 = ` +const express = require('express'), +app = express(); +app.use(require('helmet')({ + dnsPrefetchControl:{ allow: false } +})); +` + SampleVulnerableHSJAVASCRIPT40 = ` +const express = require('express'), +app = express(); +app.use(require('helmet')({ + expectCt: false +})); +` + SampleSafeHSJAVASCRIPT40 = ` +const express = require('express'), +app = express(); +app.use(require('helmet')({ + expectCt: true +})); +` + SampleVulnerableHSJAVASCRIPT41 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use( + helmet({ + referrerPolicy: { policy: 'no-referrer-when-downgrade' } + }) +); +` + SampleSafeHSJAVASCRIPT41 = ` +const express = require('express'), +app = express(); +app.use(require('helmet')({ + referrerPolicy: { policy: 'no-referrer' } +})); +` + SampleVulnerableHSJAVASCRIPT42 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use( + helmet({ + noSniff: false + }) +); +` + SampleSafeHSJAVASCRIPT42 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); + +app.use(helmet.noSniff()); + +app.use( + helmet({ + noSniff: true + }) +); +` + SampleVulnerableHSJAVASCRIPT43 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use( + helmet.contentSecurityPolicy({ + directives: { + frameAncestors: ["'none'"], + }, + }) +); +` + SampleSafeHSJAVASCRIPT43 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use(helmet.contentSecurityPolicy()); +` + SampleVulnerableHSJAVASCRIPT44 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use( + helmet.contentSecurityPolicy({ + directives: { + blockAllMixed: ['self'], + }, + }) +); +` + SampleSafeHSJAVASCRIPT44 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use(helmet.contentSecurityPolicy()); +` + SampleVulnerableHSJAVASCRIPT45 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use( + helmet({ + contentSecurityPolicy: false + }) +); +` + SampleSafeHSJAVASCRIPT45 = ` +const express = require('express'), +const helmet = require('helmet'); +app = express(); +app.use(helmet.contentSecurityPolicy()); +` + SampleVulnerableHSJAVASCRIPT46 = ` +const express = require('express'); +const cookieSession = require('cookie-session'); +app = express(); +app.use(cookieSession({ + name: 'session', + httpOnly: false +}) +` + SampleSafeHSJAVASCRIPT46 = ` +const express = require('express'); +const cookieSession = require('cookie-session'); +app = express(); +app.use(cookieSession({ + name: 'session', + httpOnly: true +}) +` + SampleVulnerableHSJAVASCRIPT47 = ` +const express = require('express'); +const cookieSession = require('cookie-session'); +app = express(); +app.use(cookieSession({ + name: 'session', + secure: false +}) +` + SampleSafeHSJAVASCRIPT47 = ` +const express = require('express'); +const cookieSession = require('cookie-session'); +app = express(); +app.use(cookieSession({ + name: 'session', + secure: true +}) +` + SampleVulnerableHSJAVASCRIPT48 = ` +const net = require('net'); +const socket = new net.Socket(); +net.connect({ port: port }, () => {}); +` + SampleSafeHSJAVASCRIPT48 = ` +const express = require('express'); +const app = express(); +const server = http.createServer(app); +const { Server } = require("socket.io"); +const io = new Server(server); + +io.on('connection', (socket) => { + console.log('a user connected'); +}); + +server.listen(3000, () => { + console.log('listening on *:3000'); +}); +` + SampleVulnerableHSJAVASCRIPT49 = ` +const crypto = require('crypto'); +const key = Buffer.from(crypto.randomBytes(32)); +const iv = crypto.randomBytes(16); - SampleVulnerableHSJAVASCRIPT48 = `` - SampleSafeHSJAVASCRIPT48 = `` +let cipher = crypto.createCipheriv('RC4', key, iv); +` + SampleSafeHSJAVASCRIPT49 = ` +const crypto = require('crypto'); +const key = Buffer.from(crypto.randomBytes(32)); +const iv = crypto.randomBytes(16); - SampleVulnerableHSJAVASCRIPT49 = `` - SampleSafeHSJAVASCRIPT49 = `` +let cipher = crypto.createCipheriv('AES-256-GCM', key, iv); +` + SampleVulnerableHSJAVASCRIPT50 = ` +const Formidable = require('formidable'); +const form = new Formidable(); +form.keepExtensions = true; +` + SampleSafeHSJAVASCRIPT50 = ` +const Formidable = require('formidable'); +const form = new Formidable(); +form.keepExtensions = false; +` + SampleVulnerableHSJAVASCRIPT51 = ` +const Formidable = require('formidable'); +const form = new Formidable(); +form.maxFileSize = 10000000; +` + SampleSafeHSJAVASCRIPT51 = ` +const Formidable = require('formidable'); +const form = new Formidable(); +form.maxFileSize = 7000000; +` + SampleVulnerableHSJAVASCRIPT52 = ` +function f1() { + let Mustache = require("mustache"); + Mustache.escape = function(text) {return text;}; + let rendered = Mustache.render(template, { name: inputName }); +} - SampleVulnerableHSJAVASCRIPT50 = `` - SampleSafeHSJAVASCRIPT50 = `` +function f2() { +const markdownIt = require('markdown-it'); +let md = markdownIt({ + html: true +}); - SampleVulnerableHSJAVASCRIPT51 = `` - SampleSafeHSJAVASCRIPT51 = `` +let result = md.render('# attack'); +} +` + SampleSafeHSJAVASCRIPT52 = ` +function f1() { + let Mustache = require("mustache"); + let rendered = Mustache.render(template, { name: inputName }); +} - SampleVulnerableHSJAVASCRIPT52 = `` - SampleSafeHSJAVASCRIPT52 = `` +function f2() { +const markdownIt = require('markdown-it'); +let result = md.render('# attack'); +} +` + SampleVulnerableHSJAVASCRIPT53 = ` +const db = require('./mysql/dbConnection.js'); +const email = req.query.email; +db.query("SELECT * FROM USERS WHERE EMAIL = " + name); +` + SampleSafeHSJAVASCRIPT53 = ` +var query = ""; +const db = require('./mysql/dbConnection.js'); +const email = req.query.email; +db.query("SELECT * FROM USERS WHERE EMAIL = ?", [email]); +` + SampleVulnerableHSJAVASCRIPT54 = ` +const MongoClient = require('mongodb').MongoClient; +MongoClient.connect("mongodb://localhost:27017/mydb", function(err, db) { + if (err) throw err; + db.close(); +}); +` + SampleSafeHSJAVASCRIPT54 = ` +const MongoClient = require('mongodb').MongoClient; +MongoClient.connect(process.env.MONGO_URI, function(err, db) { + if (err) throw err; + db.close(); +}); +` - SampleVulnerableHSJAVASCRIPT53 = `` - SampleSafeHSJAVASCRIPT53 = `` + SampleVulnerableHSJAVASCRIPT55 = ` +const { Client } = require('pg') +const client = new Client({ + password: 'root', + user: 'root', + host: 'localhost', +}) +` + SampleSafeHSJAVASCRIPT55 = ` +const { Client } = require('pg') +const client = new Client({ + user: process.env.DB_USER, + password: process.env.DB_PASS + host: process.env.DB_HOST, +` ) diff --git a/internal/services/engines/rules_test.go b/internal/services/engines/rules_test.go index da1d29240..8adf6cc3e 100644 --- a/internal/services/engines/rules_test.go +++ b/internal/services/engines/rules_test.go @@ -42,7 +42,7 @@ func TestGetRules(t *testing.T) { { engine: "Javascript", manager: javascript.NewRules(), - expectedTotalRules: 53, + expectedTotalRules: 55, }, { engine: "Nginx",