]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14442 CWE Top 25 Security report
authorJeremy Davis <jeremy.davis@sonarsource.com>
Mon, 8 Feb 2021 17:24:19 +0000 (18:24 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 17 Feb 2021 20:07:15 +0000 (20:07 +0000)
server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx
server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx
server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx
server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx
server/sonar-web/src/main/js/apps/security-hotspots/__tests__/__snapshots__/SecurityHotspotsAppRenderer-test.tsx.snap
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSimpleList-test.tsx.snap
server/sonar-web/src/main/js/apps/security-hotspots/utils.ts
server/sonar-web/src/main/js/helpers/urls.ts

index d9cb36b17607327942f7d97f180f1b5c824b9ddc..5f15f8816dd21ebc9eb6937024ec883573e7c42f 100644 (file)
@@ -63,6 +63,7 @@ type Props = DispatchProps & OwnProps;
 
 interface State {
   filterByCategory?: { standard: SecurityStandard; category: string };
+  filterByCWE?: string;
   filters: HotspotFilters;
   hotspotKeys?: string[];
   hotspots: RawHotspot[];
@@ -249,12 +250,16 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
       ? (location.query.hotspots as string).split(',')
       : undefined;
 
-    const standard = SECURITY_STANDARDS.find(stnd => location.query[stnd] !== undefined);
+    const standard = SECURITY_STANDARDS.find(
+      stnd => stnd !== SecurityStandard.CWE && location.query[stnd] !== undefined
+    );
     const filterByCategory = standard
       ? { standard, category: location.query[standard] }
       : undefined;
 
-    this.setState({ filterByCategory, hotspotKeys });
+    const filterByCWE: string | undefined = location.query.cwe;
+
+    this.setState({ filterByCategory, filterByCWE, hotspotKeys });
 
     if (hotspotKeys && hotspotKeys.length > 0) {
       return getSecurityHotspotList(hotspotKeys, {
@@ -263,9 +268,18 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
       });
     }
 
-    if (filterByCategory) {
+    if (filterByCategory || filterByCWE) {
+      const hotspotFilters: T.Dict<string> = {};
+
+      if (filterByCategory) {
+        hotspotFilters[filterByCategory.standard] = filterByCategory.category;
+      }
+      if (filterByCWE) {
+        hotspotFilters[SecurityStandard.CWE] = filterByCWE;
+      }
+
       return getSecurityHotspots({
-        [filterByCategory.standard]: filterByCategory.category,
+        ...hotspotFilters,
         projectKey: component.key,
         p: page,
         ps: PAGE_SIZE,
@@ -365,6 +379,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
       query: {
         ...this.props.location.query,
         hotspots: undefined,
+        [SecurityStandard.CWE]: undefined,
         [SecurityStandard.OWASP_TOP10]: undefined,
         [SecurityStandard.SANS_TOP25]: undefined,
         [SecurityStandard.SONARSOURCE]: undefined
@@ -396,6 +411,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
     const { branchLike, component } = this.props;
     const {
       filterByCategory,
+      filterByCWE,
       filters,
       hotspotKeys,
       hotspots,
@@ -414,11 +430,12 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
         component={component}
         filters={filters}
         filterByCategory={filterByCategory}
+        filterByCWE={filterByCWE}
         hotspots={hotspots}
         hotspotsReviewedMeasure={hotspotsReviewedMeasure}
         hotspotsTotal={hotspotsTotal}
         isStaticListOfHotspots={Boolean(
-          (hotspotKeys && hotspotKeys.length > 0) || filterByCategory
+          (hotspotKeys && hotspotKeys.length > 0) || filterByCategory || filterByCWE
         )}
         loading={loading}
         loadingMeasure={loadingMeasure}
index 518f8e3b8f1480a288221e71653751bb00aa1b80..c8dba8306cf6c791919794255801cd727b322a80 100644 (file)
@@ -43,6 +43,7 @@ export interface SecurityHotspotsAppRendererProps {
     standard: SecurityStandard;
     category: string;
   };
+  filterByCWE?: string;
   filters: HotspotFilters;
   hotspots: RawHotspot[];
   hotspotsReviewedMeasure?: string;
@@ -66,6 +67,7 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe
     branchLike,
     component,
     filterByCategory,
+    filterByCWE,
     filters,
     hotspots,
     hotspotsReviewedMeasure,
@@ -125,9 +127,10 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe
               {({ top }) => (
                 <div className="layout-page-side" ref={scrollableRef} style={{ top }}>
                   <div className="layout-page-side-inner">
-                    {filterByCategory ? (
+                    {filterByCategory || filterByCWE ? (
                       <HotspotSimpleList
                         filterByCategory={filterByCategory}
+                        filterByCWE={filterByCWE}
                         hotspots={hotspots}
                         hotspotsTotal={hotspotsTotal}
                         loadingMore={loadingMore}
index bf65636abc6f652457ccce172efe53a845d9dee3..de6de5e30c4cffe0582b1a9293ea3b45fadd8a51 100644 (file)
@@ -123,6 +123,19 @@ it('should handle category request', () => {
   );
 });
 
+it('should handle cwe request', () => {
+  (getStandards as jest.Mock).mockResolvedValue(mockStandards());
+  (getMeasures as jest.Mock).mockResolvedValue([{ value: '86.6' }]);
+
+  shallowRender({
+    location: mockLocation({ query: { [SecurityStandard.CWE]: '1004' } })
+  });
+
+  expect(getSecurityHotspots).toBeCalledWith(
+    expect.objectContaining({ [SecurityStandard.CWE]: '1004' })
+  );
+});
+
 it('should load data correctly when hotspot key list is forced', async () => {
   const hotspots = [
     mockRawHotspot({ key: 'test1' }),
index fcc8140337d8e11f06f534bb073056d484006f5a..6fdd414e13611cce482f60c38f2c220f71d684c9 100644 (file)
@@ -23,6 +23,7 @@ import { scrollToElement } from 'sonar-ui-common/helpers/scrolling';
 import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
 import { mockRawHotspot, mockStandards } from '../../../helpers/mocks/security-hotspots';
 import { mockComponent } from '../../../helpers/testMocks';
+import { SecurityStandard } from '../../../types/security';
 import { HotspotStatusFilter } from '../../../types/security-hotspots';
 import FilterBar from '../components/FilterBar';
 import SecurityHotspotsAppRenderer, {
@@ -59,6 +60,26 @@ it('should render correctly with hotspots', () => {
   ).toMatchSnapshot();
 });
 
+it('should render correctly when filtered by category or cwe', () => {
+  const hotspots = [mockRawHotspot({ key: 'h1' }), mockRawHotspot({ key: 'h2' })];
+
+  expect(
+    shallowRender({ filterByCWE: '327', hotspots, hotspotsTotal: 2, selectedHotspot: hotspots[0] })
+      .find(ScreenPositionHelper)
+      .dive()
+  ).toMatchSnapshot('cwe');
+  expect(
+    shallowRender({
+      filterByCategory: { category: 'a1', standard: SecurityStandard.OWASP_TOP10 },
+      hotspots,
+      hotspotsTotal: 2,
+      selectedHotspot: hotspots[0]
+    })
+      .find(ScreenPositionHelper)
+      .dive()
+  ).toMatchSnapshot('category');
+});
+
 it('should properly propagate the "show all" call', () => {
   const onShowAllHotspots = jest.fn();
   const wrapper = shallowRender({ onShowAllHotspots });
index b4296c6c919c34d2a842403723963d69ffd76d36..483ece472725d67f9226bec0622c4c54f812d63b 100644 (file)
@@ -58,6 +58,249 @@ exports[`should render correctly 1`] = `
 </div>
 `;
 
+exports[`should render correctly when filtered by category or cwe: category 1`] = `
+<div
+  className="layout-page-side"
+  style={
+    Object {
+      "top": 0,
+    }
+  }
+>
+  <div
+    className="layout-page-side-inner"
+  >
+    <HotspotSimpleList
+      filterByCategory={
+        Object {
+          "category": "a1",
+          "standard": "owaspTop10",
+        }
+      }
+      hotspots={
+        Array [
+          Object {
+            "author": "Developer 1",
+            "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+            "creationDate": "2013-05-13T17:55:39+0200",
+            "key": "h1",
+            "line": 81,
+            "message": "'3' is a magic number.",
+            "project": "com.github.kevinsawicki:http-request",
+            "resolution": undefined,
+            "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+            "securityCategory": "command-injection",
+            "status": "TO_REVIEW",
+            "updateDate": "2013-05-13T17:55:39+0200",
+            "vulnerabilityProbability": "HIGH",
+          },
+          Object {
+            "author": "Developer 1",
+            "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+            "creationDate": "2013-05-13T17:55:39+0200",
+            "key": "h2",
+            "line": 81,
+            "message": "'3' is a magic number.",
+            "project": "com.github.kevinsawicki:http-request",
+            "resolution": undefined,
+            "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+            "securityCategory": "command-injection",
+            "status": "TO_REVIEW",
+            "updateDate": "2013-05-13T17:55:39+0200",
+            "vulnerabilityProbability": "HIGH",
+          },
+        ]
+      }
+      hotspotsTotal={2}
+      loadingMore={false}
+      onHotspotClick={[MockFunction]}
+      onLoadMore={[MockFunction]}
+      selectedHotspot={
+        Object {
+          "author": "Developer 1",
+          "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+          "creationDate": "2013-05-13T17:55:39+0200",
+          "key": "h1",
+          "line": 81,
+          "message": "'3' is a magic number.",
+          "project": "com.github.kevinsawicki:http-request",
+          "resolution": undefined,
+          "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+          "securityCategory": "command-injection",
+          "status": "TO_REVIEW",
+          "updateDate": "2013-05-13T17:55:39+0200",
+          "vulnerabilityProbability": "HIGH",
+        }
+      }
+      standards={
+        Object {
+          "cwe": Object {
+            "1004": Object {
+              "title": "Sensitive Cookie Without 'HttpOnly' Flag",
+            },
+            "unknown": Object {
+              "title": "No CWE associated",
+            },
+          },
+          "owaspTop10": Object {
+            "a1": Object {
+              "title": "Injection",
+            },
+            "a2": Object {
+              "title": "Broken Authentication",
+            },
+            "a3": Object {
+              "title": "Sensitive Data Exposure",
+            },
+          },
+          "sansTop25": Object {
+            "insecure-interaction": Object {
+              "title": "Insecure Interaction Between Components",
+            },
+            "porous-defenses": Object {
+              "title": "Porous Defenses",
+            },
+            "risky-resource": Object {
+              "title": "Risky Resource Management",
+            },
+          },
+          "sonarsourceSecurity": Object {
+            "buffer-overflow": Object {
+              "title": "Buffer Overflow",
+            },
+            "rce": Object {
+              "title": "Code Injection (RCE)",
+            },
+            "sql-injection": Object {
+              "title": "SQL Injection",
+            },
+          },
+        }
+      }
+    />
+  </div>
+</div>
+`;
+
+exports[`should render correctly when filtered by category or cwe: cwe 1`] = `
+<div
+  className="layout-page-side"
+  style={
+    Object {
+      "top": 0,
+    }
+  }
+>
+  <div
+    className="layout-page-side-inner"
+  >
+    <HotspotSimpleList
+      filterByCWE="327"
+      hotspots={
+        Array [
+          Object {
+            "author": "Developer 1",
+            "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+            "creationDate": "2013-05-13T17:55:39+0200",
+            "key": "h1",
+            "line": 81,
+            "message": "'3' is a magic number.",
+            "project": "com.github.kevinsawicki:http-request",
+            "resolution": undefined,
+            "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+            "securityCategory": "command-injection",
+            "status": "TO_REVIEW",
+            "updateDate": "2013-05-13T17:55:39+0200",
+            "vulnerabilityProbability": "HIGH",
+          },
+          Object {
+            "author": "Developer 1",
+            "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+            "creationDate": "2013-05-13T17:55:39+0200",
+            "key": "h2",
+            "line": 81,
+            "message": "'3' is a magic number.",
+            "project": "com.github.kevinsawicki:http-request",
+            "resolution": undefined,
+            "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+            "securityCategory": "command-injection",
+            "status": "TO_REVIEW",
+            "updateDate": "2013-05-13T17:55:39+0200",
+            "vulnerabilityProbability": "HIGH",
+          },
+        ]
+      }
+      hotspotsTotal={2}
+      loadingMore={false}
+      onHotspotClick={[MockFunction]}
+      onLoadMore={[MockFunction]}
+      selectedHotspot={
+        Object {
+          "author": "Developer 1",
+          "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+          "creationDate": "2013-05-13T17:55:39+0200",
+          "key": "h1",
+          "line": 81,
+          "message": "'3' is a magic number.",
+          "project": "com.github.kevinsawicki:http-request",
+          "resolution": undefined,
+          "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+          "securityCategory": "command-injection",
+          "status": "TO_REVIEW",
+          "updateDate": "2013-05-13T17:55:39+0200",
+          "vulnerabilityProbability": "HIGH",
+        }
+      }
+      standards={
+        Object {
+          "cwe": Object {
+            "1004": Object {
+              "title": "Sensitive Cookie Without 'HttpOnly' Flag",
+            },
+            "unknown": Object {
+              "title": "No CWE associated",
+            },
+          },
+          "owaspTop10": Object {
+            "a1": Object {
+              "title": "Injection",
+            },
+            "a2": Object {
+              "title": "Broken Authentication",
+            },
+            "a3": Object {
+              "title": "Sensitive Data Exposure",
+            },
+          },
+          "sansTop25": Object {
+            "insecure-interaction": Object {
+              "title": "Insecure Interaction Between Components",
+            },
+            "porous-defenses": Object {
+              "title": "Porous Defenses",
+            },
+            "risky-resource": Object {
+              "title": "Risky Resource Management",
+            },
+          },
+          "sonarsourceSecurity": Object {
+            "buffer-overflow": Object {
+              "title": "Buffer Overflow",
+            },
+            "rce": Object {
+              "title": "Code Injection (RCE)",
+            },
+            "sql-injection": Object {
+              "title": "SQL Injection",
+            },
+          },
+        }
+      }
+    />
+  </div>
+</div>
+`;
+
 exports[`should render correctly with hotspots 1`] = `
 <div
   id="security_hotspots"
index 60f6128819a1f214110302eadc7b06fd9239f4a0..b3725d4df4f09ab82dbc7c32e91e319d0f8aa2f2 100644 (file)
@@ -27,10 +27,11 @@ import { SECURITY_STANDARD_RENDERER } from '../utils';
 import HotspotListItem from './HotspotListItem';
 
 export interface HotspotSimpleListProps {
-  filterByCategory: {
+  filterByCategory?: {
     standard: SecurityStandard;
     category: string;
   };
+  filterByCWE?: string;
   hotspots: RawHotspot[];
   hotspotsTotal: number;
   loadingMore: boolean;
@@ -43,6 +44,7 @@ export interface HotspotSimpleListProps {
 export default function HotspotSimpleList(props: HotspotSimpleListProps) {
   const {
     filterByCategory,
+    filterByCWE,
     hotspots,
     hotspotsTotal,
     loadingMore,
@@ -50,6 +52,13 @@ export default function HotspotSimpleList(props: HotspotSimpleListProps) {
     standards
   } = props;
 
+  const categoryLabel =
+    filterByCategory &&
+    SECURITY_STANDARD_RENDERER[filterByCategory.standard](standards, filterByCategory.category);
+
+  const cweLabel =
+    filterByCWE && SECURITY_STANDARD_RENDERER[SecurityStandard.CWE](standards, filterByCWE);
+
   return (
     <div className="hotspots-list-single-category huge-spacer-bottom">
       <h1 className="hotspot-list-header bordered-bottom">
@@ -60,10 +69,9 @@ export default function HotspotSimpleList(props: HotspotSimpleListProps) {
         <div className="hotspot-category">
           <div className="hotspot-category-header">
             <strong className="flex-1 spacer-right break-word">
-              {SECURITY_STANDARD_RENDERER[filterByCategory.standard](
-                standards,
-                filterByCategory.category
-              )}
+              {categoryLabel}
+              {categoryLabel && cweLabel && <hr />}
+              {cweLabel}
             </strong>
           </div>
           <ul>
index 6c3a64891944bc7b955d16243198dcb5ea0709d3..024a4a720b5571b906a37f43e4f4c58793d3abb6 100644 (file)
@@ -24,7 +24,11 @@ import { SecurityStandard } from '../../../../types/security';
 import HotspotSimpleList, { HotspotSimpleListProps } from '../HotspotSimpleList';
 
 it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender()).toMatchSnapshot('filter by category');
+  expect(shallowRender({ filterByCategory: undefined, filterByCWE: '327' })).toMatchSnapshot(
+    'filter by cwe'
+  );
+  expect(shallowRender({ filterByCWE: '327' })).toMatchSnapshot('filter by both');
 });
 
 function shallowRender(props: Partial<HotspotSimpleListProps> = {}) {
@@ -40,7 +44,7 @@ function shallowRender(props: Partial<HotspotSimpleListProps> = {}) {
       onLoadMore={jest.fn()}
       selectedHotspot={hotspots[0]}
       standards={{
-        cwe: {},
+        cwe: { 327: { title: 'Use of a Broken or Risky Cryptographic Algorithm' } },
         owaspTop10: {
           a1: { title: 'A1 - SQL Injection' },
           a3: { title: 'A3 - Sensitive Data Exposure' }
index 24eb95c2d4abe87b7692ddf2f7f26a996a744521..ca7d9427533d587519c4b7e0214546f42c808e6d 100644 (file)
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render correctly 1`] = `
+exports[`should render correctly: filter by both 1`] = `
 <div
   className="hotspots-list-single-category huge-spacer-bottom"
 >
@@ -25,6 +25,192 @@ exports[`should render correctly 1`] = `
           className="flex-1 spacer-right break-word"
         >
           A1 - A1 - SQL Injection
+          <hr />
+          CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
+        </strong>
+      </div>
+      <ul>
+        <li
+          data-hotspot-key="h1"
+          key="h1"
+        >
+          <HotspotListItem
+            hotspot={
+              Object {
+                "author": "Developer 1",
+                "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+                "creationDate": "2013-05-13T17:55:39+0200",
+                "key": "h1",
+                "line": 81,
+                "message": "'3' is a magic number.",
+                "project": "com.github.kevinsawicki:http-request",
+                "resolution": undefined,
+                "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+                "securityCategory": "command-injection",
+                "status": "TO_REVIEW",
+                "updateDate": "2013-05-13T17:55:39+0200",
+                "vulnerabilityProbability": "HIGH",
+              }
+            }
+            onClick={[MockFunction]}
+            selected={true}
+          />
+        </li>
+        <li
+          data-hotspot-key="h2"
+          key="h2"
+        >
+          <HotspotListItem
+            hotspot={
+              Object {
+                "author": "Developer 1",
+                "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+                "creationDate": "2013-05-13T17:55:39+0200",
+                "key": "h2",
+                "line": 81,
+                "message": "'3' is a magic number.",
+                "project": "com.github.kevinsawicki:http-request",
+                "resolution": undefined,
+                "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+                "securityCategory": "command-injection",
+                "status": "TO_REVIEW",
+                "updateDate": "2013-05-13T17:55:39+0200",
+                "vulnerabilityProbability": "HIGH",
+              }
+            }
+            onClick={[MockFunction]}
+            selected={false}
+          />
+        </li>
+      </ul>
+    </div>
+  </div>
+  <ListFooter
+    count={2}
+    loadMore={[MockFunction]}
+    loading={false}
+    total={2}
+  />
+</div>
+`;
+
+exports[`should render correctly: filter by category 1`] = `
+<div
+  className="hotspots-list-single-category huge-spacer-bottom"
+>
+  <h1
+    className="hotspot-list-header bordered-bottom"
+  >
+    <SecurityHotspotIcon
+      className="spacer-right"
+    />
+    hotspots.list_title.2
+  </h1>
+  <div
+    className="big-spacer-bottom"
+  >
+    <div
+      className="hotspot-category"
+    >
+      <div
+        className="hotspot-category-header"
+      >
+        <strong
+          className="flex-1 spacer-right break-word"
+        >
+          A1 - A1 - SQL Injection
+        </strong>
+      </div>
+      <ul>
+        <li
+          data-hotspot-key="h1"
+          key="h1"
+        >
+          <HotspotListItem
+            hotspot={
+              Object {
+                "author": "Developer 1",
+                "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+                "creationDate": "2013-05-13T17:55:39+0200",
+                "key": "h1",
+                "line": 81,
+                "message": "'3' is a magic number.",
+                "project": "com.github.kevinsawicki:http-request",
+                "resolution": undefined,
+                "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+                "securityCategory": "command-injection",
+                "status": "TO_REVIEW",
+                "updateDate": "2013-05-13T17:55:39+0200",
+                "vulnerabilityProbability": "HIGH",
+              }
+            }
+            onClick={[MockFunction]}
+            selected={true}
+          />
+        </li>
+        <li
+          data-hotspot-key="h2"
+          key="h2"
+        >
+          <HotspotListItem
+            hotspot={
+              Object {
+                "author": "Developer 1",
+                "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest",
+                "creationDate": "2013-05-13T17:55:39+0200",
+                "key": "h2",
+                "line": 81,
+                "message": "'3' is a magic number.",
+                "project": "com.github.kevinsawicki:http-request",
+                "resolution": undefined,
+                "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck",
+                "securityCategory": "command-injection",
+                "status": "TO_REVIEW",
+                "updateDate": "2013-05-13T17:55:39+0200",
+                "vulnerabilityProbability": "HIGH",
+              }
+            }
+            onClick={[MockFunction]}
+            selected={false}
+          />
+        </li>
+      </ul>
+    </div>
+  </div>
+  <ListFooter
+    count={2}
+    loadMore={[MockFunction]}
+    loading={false}
+    total={2}
+  />
+</div>
+`;
+
+exports[`should render correctly: filter by cwe 1`] = `
+<div
+  className="hotspots-list-single-category huge-spacer-bottom"
+>
+  <h1
+    className="hotspot-list-header bordered-bottom"
+  >
+    <SecurityHotspotIcon
+      className="spacer-right"
+    />
+    hotspots.list_title.2
+  </h1>
+  <div
+    className="big-spacer-bottom"
+  >
+    <div
+      className="hotspot-category"
+    >
+      <div
+        className="hotspot-category-header"
+      >
+        <strong
+          className="flex-1 spacer-right break-word"
+        >
+          CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
         </strong>
       </div>
       <ul>
index 1d9e7b68e320e7ba2ea3b3321bb3dba36573c045..99f3d242d7668ea533faf18d3ca00bd5f28c406c 100644 (file)
@@ -40,7 +40,8 @@ export const RISK_EXPOSURE_LEVELS = [RiskExposure.HIGH, RiskExposure.MEDIUM, Ris
 export const SECURITY_STANDARDS = [
   SecurityStandard.SONARSOURCE,
   SecurityStandard.OWASP_TOP10,
-  SecurityStandard.SANS_TOP25
+  SecurityStandard.SANS_TOP25,
+  SecurityStandard.CWE
 ];
 
 export const SECURITY_STANDARD_RENDERER = {
index f591b968188b7b59a46ecb8e97e6c4fa7c04de32..629480e472b39a47b69fded53a59e00354a7d169 100644 (file)
@@ -128,7 +128,8 @@ export function getComponentSecurityHotspotsUrl(componentKey: string, query: Que
       ...pick(query, [
         SecurityStandard.SONARSOURCE,
         SecurityStandard.OWASP_TOP10,
-        SecurityStandard.SANS_TOP25
+        SecurityStandard.SANS_TOP25,
+        SecurityStandard.CWE
       ])
     }
   };