Bug 1369067 - file security bugs: provide option and auto-enable it based on search terms (#7201)

This commit is contained in:
Sebastian Hengst 2021-07-08 01:40:22 +02:00 коммит произвёл GitHub
Родитель 550d535480
Коммит db200cb921
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 106 добавлений и 2 удалений

Просмотреть файл

@ -101,6 +101,23 @@ describe('BugFiler', () => {
);
};
const getBugFilerForSecurityCheck = (suggestions) => {
return mount(
<BugFilerClass
isOpen={isOpen}
toggle={toggle}
suggestion={suggestions[0]}
suggestions={suggestions}
fullLog={fullLog}
parsedLog={parsedLog}
reftestUrl={isReftest(selectedJob) ? reftest : ''}
successCallback={successCallback}
jobGroupName={selectedJob.job_group_name}
notify={() => {}}
/>,
);
};
test('parses a crash suggestion', () => {
const summary =
'PROCESS-CRASH | browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js | application crashed [@ js::GCMarker::eagerlyMarkChildren]';
@ -255,6 +272,32 @@ describe('BugFiler', () => {
expect(summary[1]).toBe('wide--cover--width.html');
});
test('should set as security bug if summary contains initially a relevant search term', () => {
const suggestions = [
{
bugs: {},
search_terms: [],
search:
'SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/checkouts/gecko/mock/folder/file.c:12:34 in mock::MockComponent::MockMethod(mock::squirrel::Weasel*)',
},
];
const bugFiler = getBugFilerForSecurityCheck(suggestions);
expect(bugFiler.state().isSecurityIssue).toBe(true);
});
test('should not set as security bug if summary contains initially no relevant search term', () => {
const suggestions = [
{
bugs: {},
search_terms: [],
search:
'TEST-UNEXPECTED-FAIL | mock/folder/test/subfolder/browser_test.js | Test timed out -',
},
];
const bugFiler = getBugFilerForSecurityCheck(suggestions);
expect(bugFiler.state().isSecurityIssue).toBe(false);
});
test('should parse finding the filename when the `TEST-FOO` is not omitted', () => {
const rawSummary =
'TEST-UNEXPECTED-CRASH | /service-workers/service-worker/xhr.https.html | expected OK';

Просмотреть файл

@ -50,6 +50,7 @@ def test_create_bug(client, eleven_jobs_stored, activate_responses, test_user):
"comment": u"Intermittent Description",
"comment_tags": "treeherder",
"keywords": ["intermittent-failure"],
"groups": [],
},
)
assert resp.status_code == 200
@ -102,6 +103,7 @@ def test_create_bug_with_unicode(client, eleven_jobs_stored, activate_responses,
"comment": u"Intermittent “description” string",
"comment_tags": "treeherder",
"keywords": ["intermittent-failure"],
"groups": [],
},
)
assert resp.status_code == 200
@ -156,6 +158,7 @@ def test_create_crash_bug(client, eleven_jobs_stored, activate_responses, test_u
"crash_signature": "[@crashsig]",
"priority": "--",
"keywords": ["intermittent-failure", "crash"],
"groups": [],
},
)
assert resp.status_code == 200
@ -204,6 +207,7 @@ def test_create_unauthenticated_bug(client, eleven_jobs_stored, activate_respons
"comment_tags": "treeherder",
"keywords": ["intermittent-failure"],
"see_also": "12345",
"groups": [],
},
)
assert resp.status_code == 403
@ -261,6 +265,7 @@ def test_create_bug_with_long_crash_signature(
"crash_signature": crashsig,
"regressed_by": "123",
"see_also": "12345",
"groups": [],
},
)
assert resp.status_code == 400

Просмотреть файл

@ -51,6 +51,8 @@ class BugzillaViewSet(viewsets.ViewSet):
'description': description,
'comment_tags': "treeherder",
}
if len(params.get('groups')) > 0:
data['groups'] = params.get('groups')
try:
response = make_request(url, method='POST', headers=headers, json=data)

Просмотреть файл

@ -167,6 +167,7 @@ export class BugFilerClass extends React.Component {
isFilerSummaryVisible: false,
selectedProduct: null,
isIntermittent: true,
isSecurityIssue: false,
comment: '',
searching: false,
parsedSummary,
@ -177,6 +178,10 @@ export class BugFilerClass extends React.Component {
};
}
componentDidMount() {
this.checkForSecurityIssue();
}
getUnhelpfulSummaryReason(summary) {
const { suggestion } = this.props;
const searchTerms = suggestion.search_terms;
@ -384,6 +389,7 @@ export class BugFilerClass extends React.Component {
selectedProduct,
comment,
isIntermittent,
isSecurityIssue,
checkedLogLinks,
regressedBy,
seeAlso,
@ -487,6 +493,7 @@ export class BugFilerClass extends React.Component {
crash_signature: crashSignature,
severity: 'S4',
priority,
groups: isSecurityIssue ? ['core-security'] : [],
comment: descriptionStrings,
comment_tags: 'treeherder',
};
@ -536,6 +543,35 @@ export class BugFilerClass extends React.Component {
});
};
checkForSecurityIssue() {
const { comment, isSecurityIssue, summary } = this.state;
if (isSecurityIssue) {
return;
}
const inputToCheck = `${summary}\n${comment}`;
const potentialSecurityIssues = [
'access-violation',
'data race',
'double-free',
'e5e5e5e5',
'global-buffer-overflow',
'heap-buffer-overflow',
'heap-use-after-free',
'negative-size-param',
'stack-buffer-overflow',
'use-after-poison',
];
for (const searchTerm of potentialSecurityIssues) {
if (inputToCheck.includes(searchTerm)) {
this.setState({ isSecurityIssue: true });
break;
}
}
}
render() {
const {
isOpen,
@ -551,6 +587,7 @@ export class BugFilerClass extends React.Component {
thisFailure,
isFilerSummaryVisible,
isIntermittent,
isSecurityIssue,
summary,
searching,
checkedLogLinks,
@ -666,7 +703,9 @@ export class BugFilerClass extends React.Component {
placeholder="Intermittent..."
pattern=".{0,255}"
onChange={(evt) =>
this.setState({ summary: evt.target.value })
this.setState({ summary: evt.target.value }, () =>
this.checkForSecurityIssue(),
)
}
value={summary}
/>
@ -775,7 +814,9 @@ export class BugFilerClass extends React.Component {
<Label for="summary-input">Comment:</Label>
<Input
onChange={(evt) =>
this.setState({ comment: evt.target.value })
this.setState({ comment: evt.target.value }, () =>
this.checkForSecurityIssue(),
)
}
type="textarea"
id="summary-input"
@ -833,6 +874,19 @@ export class BugFilerClass extends React.Component {
</Tooltip>
</div>
</div>
<div className="d-inline-flex mt-2 ml-5">
<Label>
<Input
id="securityIssue"
onChange={() =>
this.setState({ isSecurityIssue: !isSecurityIssue })
}
type="checkbox"
checked={isSecurityIssue}
/>
Report this as a security issue
</Label>
</div>
{!!crashSignatures.length && (
<div>
<Label for="signature-input">Signature:</Label>