Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Impl implements InlineExpectationsTestSig {
ExpectationComment() { this = MkExpectationComment(comment) }

/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
string getContents() { result = comment.getText().suffix(2) }
string getContents() { result = comment.getText().suffix(2).trim() }

/** Gets a textual representation of this element. */
string toString() { result = comment.toString() }
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
queries/Security/CWE-020/IncompleteHostnameRegex.ql
query: queries/Security/CWE-020/IncompleteHostnameRegex.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
queries/Security/CWE-020/MissingRegexAnchor.ql
query: queries/Security/CWE-020/MissingRegexAnchor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
Expand Up @@ -47,63 +47,63 @@ class NSString : NSObject {

func tests(input: String) throws {
_ = try Regex("^a|").firstMatch(in: input)
_ = try Regex("^a|b").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^a|b").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("a|^b").firstMatch(in: input)
_ = try Regex("^a|^b").firstMatch(in: input)
_ = try Regex("^a|b|c").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^a|b|c").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("a|^b|c").firstMatch(in: input)
_ = try Regex("a|b|^c").firstMatch(in: input)
_ = try Regex("^a|^b|c").firstMatch(in: input)

_ = try Regex("(^a)|b").firstMatch(in: input)
_ = try Regex("^a|(b)").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^a|(b)").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("^a|(^b)").firstMatch(in: input)
_ = try Regex("^(a)|(b)").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^(a)|(b)").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

_ = try Regex("a|b$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|b$").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("a$|b").firstMatch(in: input)
_ = try Regex("a$|b$").firstMatch(in: input)
_ = try Regex("a|b|c$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("a|b|c$").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("a|b$|c").firstMatch(in: input)
_ = try Regex("a$|b|c").firstMatch(in: input)
_ = try Regex("a|b$|c$").firstMatch(in: input)

_ = try Regex("a|(b$)").firstMatch(in: input)
_ = try Regex("(a)|b$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("(a)|b$").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("(a$)|b$").firstMatch(in: input)
_ = try Regex("(a)|(b)$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("(a)|(b)$").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^good.com|better.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^good\.com|better\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^good\\.com|better\\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^good\\\.com|better\\\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^good\\\\.com|better\\\\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // BAD (missing anchor)
_ = try Regex("^foo|bar|baz$").firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex("^foo|%").firstMatch(in: input)
}

func realWorld(input: String) throws {
// real-world examples that have been anonymized a bit
// the following are bad:
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // BAD (missing anchor)
_ = try Regex(#"(\.xxx)|(\.yyy)|(\.zzz)$"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"(^left|right|center)\sbottom$"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|\.zzz$"#).ignoresCase().firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"\.xxx|\.yyy|zzz$"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^([A-Z]|xxx[XY]$)"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)"#).ignoresCase().firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^(xxx yyy zzz)|(xxx yyy)|(1st( xxx)? yyy)|xxx|1st"#).ignoresCase().firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^(xxx:)|(yyy:)|(zzz:)"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^(xxx?:)|(yyy:zzz\/)"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^@media|@page"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^\s*(xxx?|yyy|zzz):|xxx:yyy"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^click|mouse|touch"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^http://good\.com|http://better\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^https?://good\.com|https?://better\.com"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^mouse|touch|click|contextmenu|drop|dragover|dragend"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"^xxx:|yyy:"#).ignoresCase().firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"_xxx|_yyy|_zzz$"#).firstMatch(in: input) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try Regex(#"em|%$"#).firstMatch(in: input) // BAD (missing anchor) [NOT DETECTED] - not flagged at the moment due to the anchor not being for letters

// the following are MAYBE OK due to apparent complexity; not flagged
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,36 +59,36 @@ func tests(url: String, secure: Bool) throws {
let input = "http://evil.com/?http://good.com"
let inputRange = NSMakeRange(0, input.utf16.count)

_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "^https?://good.com").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(^https?://good1.com)|(^https?://good2.com)").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing post-anchor)
_ = try NSRegularExpression(pattern: "(https?://good.com)|(^https?://goodie.com)").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com"#).matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https?://good.com").matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // BAD (missing anchor)
if let _ = try NSRegularExpression(pattern: "https?://good.com").firstMatch(in: input, range: inputRange) { } // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

let input2 = "something"
let input2Range = NSMakeRange(0, input2.utf16.count)
_ = try NSRegularExpression(pattern: "other").firstMatch(in: input2, range: input2Range) // OK
_ = try NSRegularExpression(pattern: "x.commissary").firstMatch(in: input2, range: input2Range) // OK

_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com"#).firstMatch(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?://good.com:8080"#).firstMatch(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)

let trustedUrlRegexs = [
"https?://good.com", // BAD (missing anchor), referenced below
#"https?:\/\/good.com"#, // BAD (missing anchor), referenced below
"^https?://good.com" // BAD (missing post-anchor), referenced below
"https?://good.com", // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor), referenced below
#"https?:\/\/good.com"#, // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor), referenced below
"^https?://good.com" // $ Alert[swift/missing-regexp-anchor] // BAD (missing post-anchor), referenced below
]
for trustedUrlRegex in trustedUrlRegexs {
if let _ = try NSRegularExpression(pattern: trustedUrlRegex).firstMatch(in: input, range: inputRange) { }
}

let trustedUrlRegexs2 = [
"https?://good.com", // BAD (missing anchor), referenced below
"https?://good.com", // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor), referenced below
]
if let _ = try NSRegularExpression(pattern: trustedUrlRegexs2[0]).firstMatch(in: input, range: inputRange) { }

Expand All @@ -98,13 +98,13 @@ func tests(url: String, secure: Bool) throws {
for _ in notUsedUrlRegexs {
}

_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // BAD (missing anchor)
_ = try NSRegularExpression(pattern: #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange) // $ Alert[swift/missing-regexp-anchor] // BAD (missing anchor)
_ = try NSRegularExpression(pattern: "https://verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
_ = try NSRegularExpression(pattern: "http" + (secure ? "s" : "") + "://" + "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK
_ = try NSRegularExpression(pattern: "verygood.com/?id=" + #"https?:\/\/good.com\/([0-9]+)"#).matches(in: url, range: urlRange)[0] // OK

_ = try NSRegularExpression(pattern: #"\.com|\.org"#).matches(in: input, range: inputRange) // OK, has no domain name
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]
_ = try NSRegularExpression(pattern: #"example\.com|whatever"#).matches(in: input, range: inputRange) // $ Alert[swift/missing-regexp-anchor] // OK, the other disjunction doesn't match a hostname [FALSE POSITIVE]

// tests for the `isLineAnchoredHostnameRegExp` case

Expand Down
Loading
Loading