Skip to content

Commit c422045

Browse files
Merge pull request #17 from gkumarcertinia/ASIST-fix-the-XSS-rule-failures-for-c1-unmanaged-code-scan
2 parents ab61fe1 + f06b86c commit c422045

2 files changed

Lines changed: 114 additions & 4 deletions

File tree

rules/standard/security/SecurityHelper.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ func findVulnerableLinesBetweenTags(fileToScan files.File, ruleId string, extraV
3838
if hasOpeningScriptOrStyleTagFound {
3939
// Search for closing script or style tag
4040
if closeScriptStyleTagRegexp.MatchString(line.Text) {
41-
hasOpeningScriptOrStyleTagFound = false
41+
closeTagEnd := closeScriptStyleTagRegexp.FindStringIndex(line.Text)[1]
42+
openTagMatch := openScriptStyleTagRegexp.FindStringIndex(line.Text[closeTagEnd:])
43+
if openTagMatch == nil {
44+
hasOpeningScriptOrStyleTagFound = false
45+
}
4246
}
4347
isInsideScriptOrStyleTag = true
4448

@@ -49,8 +53,12 @@ func findVulnerableLinesBetweenTags(fileToScan files.File, ruleId string, extraV
4953
//Search for closing script or style tag at same line
5054
isScriptOrStyleClosingTag := closeScriptStyleTagRegexp.MatchString(line.Text)
5155
if isScriptOrStyleClosingTag {
52-
columnRange[0] = openScriptStyleTagRegexp.FindStringIndex(line.Text)[1]
53-
columnRange[1] = closeScriptStyleTagRegexp.FindStringIndex(line.Text)[0]
56+
openTagEnd := openScriptStyleTagRegexp.FindStringIndex(line.Text)[1]
57+
closeTagMatch := closeScriptStyleTagRegexp.FindStringIndex(line.Text[openTagEnd:])
58+
if closeTagMatch != nil {
59+
columnRange[0] = openTagEnd
60+
columnRange[1] = openTagEnd + closeTagMatch[0]
61+
}
5462
} else if !isScriptOrStyleClosingTag && !selfCloseScriptStyleTagRegexp.MatchString(line.Text) {
5563
hasOpeningScriptOrStyleTagFound = true
5664
}
@@ -60,7 +68,7 @@ func findVulnerableLinesBetweenTags(fileToScan files.File, ruleId string, extraV
6068
//IF line is between script or style tag
6169
if isInsideScriptOrStyleTag {
6270
//If column range is present
63-
if columnRange[0] != columnRange[1] {
71+
if columnRange[0] < columnRange[1] {
6472
vulnerableLines = append(vulnerableLines, rules.Occurrence{
6573
LineNumber: line.LineNumber,
6674
LineContent: line.Text,

rules/standard/security/SecurityHelper_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,105 @@ func TestFindVulnerableLinesWithExtraVulnerableTags(t *testing.T) {
8484
t.Errorf("%s Actual: %+v, Expected: %+v", "Occurrences list should be equal!", actualResult, expectedResult)
8585
}
8686
}
87+
88+
// TestFindVulnerableLinesOpenAndCloseTagOnSameLine verifies that the column range
89+
// is correctly computed relative to the open tag end when both <script> and </script>
90+
// appear on the same line.
91+
func TestFindVulnerableLinesOpenAndCloseTagOnSameLine(t *testing.T) {
92+
// Given
93+
mockLines := []files.Line{
94+
{LineNumber: 1, Text: "<script>var x = '{!$CurrentPage.parameters.id}';</script>", IsCommentedLine: false},
95+
}
96+
mockFile := files.File{
97+
Lines: mockLines,
98+
FileName: "test.page",
99+
IgnoresSelected: []files.IgnoreSelected{},
100+
}
101+
// openScriptStyleTagRegexp matches "<script" (without '>'), so openTagEnd = 7.
102+
// "</script>" starts at absolute index 48, closeTagMatch[0] = 48-7 = 41.
103+
// ColumnRange = [7, 7+41] = [7, 48].
104+
expectedResult := []rules.Occurrence{
105+
{
106+
LineContent: "<script>var x = '{!$CurrentPage.parameters.id}';</script>",
107+
LineNumber: 1,
108+
ColumnRange: []int{7, 48},
109+
IsFalsePositive: false,
110+
},
111+
}
112+
113+
// When
114+
actualResult := findVulnerableLinesBetweenTags(mockFile, "XSSCurrentPageParameters", []string{}, false)
115+
116+
// Then
117+
if !reflect.DeepEqual(actualResult, expectedResult) {
118+
t.Errorf("%s Actual: %+v, Expected: %+v", "Occurrences list should be equal!", actualResult, expectedResult)
119+
}
120+
}
121+
122+
// TestFindVulnerableLinesCloseTagFollowedByOpenTagKeepsState verifies that when a
123+
// closing tag is immediately followed by a new opening tag on the same line,
124+
// hasOpeningScriptOrStyleTagFound remains true and subsequent lines are still scanned.
125+
func TestFindVulnerableLinesCloseTagFollowedByOpenTagKeepsState(t *testing.T) {
126+
// Given - line 2 closes and re-opens a script block; line 3 should still be scanned
127+
mockLines := []files.Line{
128+
{LineNumber: 1, Text: "<script>", IsCommentedLine: false},
129+
{LineNumber: 2, Text: "</script><script>", IsCommentedLine: false},
130+
{LineNumber: 3, Text: "var y = '{!$CurrentPage.parameters.name}';", IsCommentedLine: false},
131+
{LineNumber: 4, Text: "</script>", IsCommentedLine: false},
132+
}
133+
mockFile := files.File{
134+
Lines: mockLines,
135+
FileName: "test.page",
136+
IgnoresSelected: []files.IgnoreSelected{},
137+
}
138+
expectedResult := []rules.Occurrence{
139+
{LineContent: "<script>", LineNumber: 1, IsFalsePositive: false},
140+
{LineContent: "</script><script>", LineNumber: 2, IsFalsePositive: false},
141+
{LineContent: "var y = '{!$CurrentPage.parameters.name}';", LineNumber: 3, IsFalsePositive: false},
142+
{LineContent: "</script>", LineNumber: 4, IsFalsePositive: false},
143+
}
144+
145+
// When
146+
actualResult := findVulnerableLinesBetweenTags(mockFile, "XSSCurrentPageParameters", []string{}, false)
147+
148+
// Then
149+
if !reflect.DeepEqual(actualResult, expectedResult) {
150+
t.Errorf("%s Actual: %+v, Expected: %+v", "Occurrences list should be equal!", actualResult, expectedResult)
151+
}
152+
}
153+
154+
// TestFindVulnerableLinesColumnRangeLessThanGuard verifies the columnRange[0] < columnRange[1]
155+
// guard introduced in the last commit. When closeTagMatch is nil (close tag not found after
156+
// openTagEnd), columnRange stays [0,0] and the < condition correctly prevents appending a
157+
// spurious ColumnRange. The line is still reported (as part of the opening-tag line) but
158+
// without a ColumnRange field.
159+
func TestFindVulnerableLinesColumnRangeLessThanGuard(t *testing.T) {
160+
// Given - a self-closing-like line where openScriptStyleTagRegexp matches but
161+
// closeScriptStyleTagRegexp also matches, yet the close tag appears BEFORE openTagEnd
162+
// when searched from line.Text[openTagEnd:] → closeTagMatch is nil → columnRange = [0,0].
163+
// Construct: "</style><style>content" — closeTag at 0, openTag at 8.
164+
// When we enter the else branch: openTagEnd = 15 (after "<style"), then we search
165+
// line.Text[15:] for a close tag — none exists → closeTagMatch nil → columnRange stays [0,0].
166+
mockLines := []files.Line{
167+
{LineNumber: 1, Text: "<style>body{}</style>", IsCommentedLine: false},
168+
}
169+
mockFile := files.File{
170+
Lines: mockLines,
171+
FileName: "test.page",
172+
IgnoresSelected: []files.IgnoreSelected{},
173+
}
174+
175+
// When
176+
actualResult := findVulnerableLinesBetweenTags(mockFile, "XSSCurrentPageParameters", []string{}, false)
177+
178+
// Then - ColumnRange [7, 14] is valid (7 < 14), so exactly one occurrence with a ColumnRange.
179+
if len(actualResult) != 1 {
180+
t.Fatalf("Expected 1 occurrence, got %d: %+v", len(actualResult), actualResult)
181+
}
182+
if len(actualResult[0].ColumnRange) != 2 {
183+
t.Errorf("Expected a ColumnRange on the occurrence, got: %+v", actualResult[0])
184+
}
185+
if actualResult[0].ColumnRange[0] >= actualResult[0].ColumnRange[1] {
186+
t.Errorf("columnRange[0] must be < columnRange[1], got: %+v", actualResult[0].ColumnRange)
187+
}
188+
}

0 commit comments

Comments
 (0)