renderSecurityReportsLink() {
return (
<ul className="menu">
+ <li>
+ <Link
+ activeClassName="active"
+ to={{
+ pathname: '/project/security_reports/sonarsource_security',
+ query: this.getQuery()
+ }}>
+ {translate('security_reports.sonarsourceSecurity.page')}
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "branch": "release",
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
<ul
className="menu"
>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/security_reports/sonarsource_security",
+ "query": Object {
+ "branch": "release",
+ "id": "foo",
+ },
+ }
+ }
+ >
+ security_reports.sonarsourceSecurity.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
import Helmet from 'react-helmet';
import { Link } from 'react-router';
import VulnerabilityList from './VulnerabilityList';
-import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
-import { translate } from '../../../helpers/l10n';
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
+import { Alert } from '../../../components/ui/Alert';
import Checkbox from '../../../components/controls/Checkbox';
-import NotFound from '../../../app/components/NotFound';
-import { getSecurityHotspots } from '../../../api/security-reports';
-import { isLongLivingBranch } from '../../../helpers/branches';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
import DocTooltip from '../../../components/docs/DocTooltip';
-import { Alert } from '../../../components/ui/Alert';
+import NotFound from '../../../app/components/NotFound';
+import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import { withRouter, Location, Router } from '../../../components/hoc/withRouter';
+import { translate } from '../../../helpers/l10n';
+import { isLongLivingBranch } from '../../../helpers/branches';
+import { getSecurityHotspots } from '../../../api/security-reports';
+import { getType } from '../utils';
import '../style.css';
interface Props {
loading: false,
findings: [],
hasVulnerabilities: false,
- type: this.getType(props.params.type),
+ type: getType(props.params.type),
showCWE: props.location.query.showCWE === 'true'
};
}
componentWillReceiveProps(newProps: Props) {
if (newProps.location.pathname !== this.props.location.pathname) {
const showCWE = newProps.location.query.showCWE === 'true';
- const type = this.getType(newProps.params.type);
+ const type = getType(newProps.params.type);
this.setState({ type, showCWE }, this.fetchSecurityHotspots);
}
}
this.mounted = false;
}
- getType = (type: string): T.StandardType => {
- if (type === 'owasp_top_10') {
- return 'owaspTop10';
- } else if (type === 'sans_top_25') {
- return 'sansTop25';
- } else {
- return 'sonarsource';
- }
- };
-
fetchSecurityHotspots = () => {
const { branchLike, component } = this.props;
this.setState({ loading: true });
render() {
const { branchLike, component, params } = this.props;
const { loading, findings, showCWE, type } = this.state;
- if (params.type !== 'owasp_top_10' && params.type !== 'sans_top_25') {
+ if (!['owasp_top_10', 'sans_top_25', 'sonarsource_security'].includes(params.type)) {
return <NotFound withContainer={false} />;
}
return (
import HelpTooltip from '../../../components/controls/HelpTooltip';
import VulnerabilityIcon from '../../../components/icons-components/VulnerabilityIcon';
import SecurityHotspotIcon from '../../../components/icons-components/SecurityHotspotIcon';
-import { renderOwaspTop10Category, renderSansTop25Category, renderCWECategory } from '../utils';
+import {
+ renderOwaspTop10Category,
+ renderSansTop25Category,
+ renderCWECategory,
+ renderSonarSourceSecurityCategory
+} from '../utils';
import DetachIcon from '../../../components/icons-components/DetachIcon';
import Tooltip from '../../../components/controls/Tooltip';
import { getRatingTooltip } from '../../../helpers/measures';
owaspTop10: renderOwaspTop10Category,
sansTop25: renderSansTop25Category,
cwe: renderCWECategory,
- sonarsourceSecurity: () => {
- /* TODO */
- }
+ sonarsourceSecurity: renderSonarSourceSecurityCategory
};
return (
<>
const locationWithCWE = { pathname: 'foo', query: { showCWE: 'true' } };
const owaspParams = { type: 'owasp_top_10' };
const sansParams = { type: 'sans_top_25' };
+const sonarParams = { type: 'sonarsource_security' };
const wrongParams = { type: 'foo' };
beforeEach(() => {
});
expect(wrapper).toMatchSnapshot();
});
+
+it('renders sonarsourceSecurity', async () => {
+ const wrapper = shallow(
+ <App
+ component={component}
+ location={location}
+ params={sonarParams}
+ router={{ push: jest.fn() }}
+ />
+ );
+ await waitAndUpdate(wrapper);
+ expect(getSecurityHotspots).toBeCalledWith({
+ project: 'foo',
+ standard: 'sonarsourceSecurity',
+ includeDistribution: false,
+ branch: undefined
+ });
+ expect(wrapper).toMatchSnapshot();
+});
</div>
`;
+exports[`renders sonarsourceSecurity 1`] = `
+<div
+ className="page page-limited"
+ id="security-reports"
+>
+ <Suggestions
+ suggestions="security_reports"
+ />
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="security_reports.sonarsourceSecurity.page"
+ />
+ <header
+ className="page-header"
+ >
+ <A11ySkipTarget
+ anchor="security_main"
+ />
+ <h1
+ className="page-title"
+ >
+ security_reports.sonarsourceSecurity.page
+ </h1>
+ <div
+ className="page-description"
+ >
+ security_reports.sonarsourceSecurity.description
+ <Link
+ className="spacer-left"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to={
+ Object {
+ "pathname": "/documentation/user-guide/security-reports/",
+ }
+ }
+ >
+ learn_more
+ </Link>
+ <Alert
+ className="spacer-top"
+ display="inline"
+ variant="info"
+ >
+ security_reports.more_rules
+ </Alert>
+ </div>
+ </header>
+ <div
+ className="display-inline-flex-center"
+ >
+ <Checkbox
+ checked={false}
+ className="spacer-left spacer-right vertical-middle"
+ disabled={false}
+ id="showCWE"
+ onCheck={[Function]}
+ thirdState={false}
+ >
+ <label
+ className="little-spacer-left"
+ htmlFor="showCWE"
+ >
+ security_reports.cwe.show
+ <DocTooltip
+ className="spacer-left"
+ doc={Promise {}}
+ />
+ </label>
+ </Checkbox>
+ </div>
+ <DeferredSpinner
+ loading={false}
+ timeout={100}
+ >
+ <VulnerabilityList
+ component={
+ Object {
+ "key": "foo",
+ "name": "Foo",
+ "qualifier": "TRK",
+ }
+ }
+ findings={
+ Array [
+ Object {
+ "activeRules": 1,
+ "category": "a1",
+ "distribution": Array [
+ Object {
+ "cwe": "477",
+ "openSecurityHotspots": 10,
+ "toReviewSecurityHotspots": 2,
+ "vulnerabilities": 1,
+ "vulnerabiliyRating": 1,
+ "wontFixSecurityHotspots": 0,
+ },
+ Object {
+ "cwe": "396",
+ "openSecurityHotspots": 10,
+ "toReviewSecurityHotspots": 2,
+ "vulnerabilities": 2,
+ "vulnerabiliyRating": 2,
+ "wontFixSecurityHotspots": 0,
+ },
+ ],
+ "openSecurityHotspots": 10,
+ "toReviewSecurityHotspots": 2,
+ "totalRules": 1,
+ "vulnerabilities": 2,
+ "vulnerabiliyRating": 5,
+ "wontFixSecurityHotspots": 0,
+ },
+ Object {
+ "activeRules": 1,
+ "category": "a2",
+ "openSecurityHotspots": 100,
+ "toReviewSecurityHotspots": 8,
+ "totalRules": 1,
+ "vulnerabilities": 3,
+ "vulnerabiliyRating": 3,
+ "wontFixSecurityHotspots": 10,
+ },
+ Object {
+ "activeRules": 0,
+ "category": "a3",
+ "openSecurityHotspots": 100,
+ "toReviewSecurityHotspots": 8,
+ "totalRules": 1,
+ "vulnerabilities": 3,
+ "vulnerabiliyRating": 3,
+ "wontFixSecurityHotspots": 10,
+ },
+ ]
+ }
+ showCWE={false}
+ type="sonarsourceSecurity"
+ />
+ </DeferredSpinner>
+</div>
+`;
+
exports[`renders with cwe 1`] = `
<div
className="page page-limited"
return addPrefix(record ? record.title : category, 'SANS', withPrefix);
}
+export function renderSonarSourceCategory(
+ standards: T.Standards,
+ category: string,
+ withPrefix = false
+): string {
+ const record = standards.sonarsourceSecurity[category];
+ return addPrefix(record ? record.title : category, 'SONAR', withPrefix);
+}
+
function addPrefix(title: string, prefix: string, withPrefix: boolean) {
return withPrefix ? `${prefix} ${title}` : title;
}
+
+const TYPES_MAP: T.Dict<T.StandardType> = {
+ owasp_top_10: 'owaspTop10',
+ sans_top_25: 'sansTop25',
+ sonarsource_security: 'sonarsourceSecurity'
+};
+
+export function getType(type: string): T.StandardType {
+ return TYPES_MAP[type] || 'sonarsourceSecurity';
+}
},
"99": {
"title": "Improper Control of Resource Identifiers ('Resource Injection')",
- "description":
- "The software receives input from an upstream component, but it does not restrict or incorrectly restricts the input before it is used as an identifier for a resource that may be outside the intended sphere of control."
+ "description": "The software receives input from an upstream component, but it does not restrict or incorrectly restricts the input before it is used as an identifier for a resource that may be outside the intended sphere of control."
+ }
+ },
+ "sonarsourceSecurity": {
+ "sql-injection": {
+ "title": "SQL Injection"
+ },
+ "rce": {
+ "title": "Code Injection (RCE)"
+ },
+ "object-injection": {
+ "title": "Object Injection"
+ },
+ "command-injection": {
+ "title": "Command Injection"
+ },
+ "path-traversal-injection": {
+ "title": "Path Traversal Injection"
+ },
+ "ldap-injection": {
+ "title": "LDAP Injection"
+ },
+ "xpath-injection": {
+ "title": "XPath Injection"
+ },
+ "expression-lang-injection": {
+ "title": "Expression Language Injection"
+ },
+ "log-injection": {
+ "title": "Log Injection"
+ },
+ "xxe": {
+ "title": "XML External Entity (XXE)"
+ },
+ "xss": {
+ "title": "Cross-Site Scripting (XSS)"
+ },
+ "dos": {
+ "title": "Denial of Service (DoS)"
+ },
+ "ssrf": {
+ "title": "Server-Side Request Forgery (SSRF)"
+ },
+ "csrf": {
+ "title": "Cross-Site Request Forgery (CSRF)"
+ },
+ "http-response-splitting": {
+ "title": "HTTP Response Splitting"
+ },
+ "open-redirect": {
+ "title": "Open Redirect"
+ },
+ "weak-cryptography": {
+ "title": "Weak Cryptography"
+ },
+ "auth": {
+ "title": "Authentication"
+ },
+ "insecure-conf": {
+ "title": "Insecure Configuration"
+ },
+ "file-manipulation": {
+ "title": "File Manipulation"
+ },
+ "others": {
+ "title": "Others"
}
}
}
security_reports.more_rules=Additional security-related rules are available but not active in your profiles.
security_reports.owaspTop10.page=OWASP Top 10
security_reports.sansTop25.page=SANS Top 25
-security_reports.owaspTop10.description=Track Vulnerabilities and Security Hotspots conforming to OWASP Top 10 standard.
-security_reports.sansTop25.description=Track Vulnerabilities and Security Hotspots conforming to SANS Top 25 standard (25 CWE items in three categories).
+security_reports.sonarsourceSecurity.page=SonarSource Security
+security_reports.owaspTop10.description=Track Vulnerabilities and Security Hotspots corresponding to OWASP Top 10 standard.
+security_reports.sansTop25.description=Track Vulnerabilities and Security Hotspots corresponding to SANS Top 25 standard (25 CWE items in three categories).
+security_reports.sonarsourceSecurity.description=Track Vulnerabilities and Security Hotspots corresponding to SonarSource Security categories.
security_reports.list.categories=Categories
security_reports.list.vulnerabilities=Vulnerabilities
security_reports.list.security_hotspots=Security Hotspots