Compare commits

...

4 Commits

Author SHA1 Message Date
Kevin Minehart
414304eb7a update publishing gpg secret key name 2023-01-24 13:44:19 -06:00
Jo
c37dcaf0da Auth: Update saml go.mod (missing query sig verification) [9.2.x] (#713)
update saml go.mod (missing query sig verification)

(cherry picked from commit 1e1dbd1a06455a451d722856dc619b2a7c78e2c0)
2023-01-24 11:33:12 +01:00
Nathan Marrs
c022534e38 [v9.2.x] SVG: Add dompurify preprocessor step (#704)
* SVG: Add dompurify preprocessor step (#698)

* add sanitized SVG component

(cherry picked from commit dbbe819368f507b9493b7a3cf6e080a5dd752b3e)

* remove added file

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-01-24 11:33:11 +01:00
Misi
2294e23134 [v9.2.x] Update grafana/saml library (#689)
SAML: update grafana/saml

Co-authored-by: Jo <joao.guerreiro@grafana.com>

Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>
Co-authored-by: Jo <joao.guerreiro@grafana.com>
2023-01-24 11:33:10 +01:00
16 changed files with 87 additions and 37 deletions

View File

@@ -1770,11 +1770,11 @@ steps:
GCP_KEY:
from_secret: gcp_key
GPG_KEY_PASSWORD:
from_secret: gpg_key_password
from_secret: packages_gpg_passphrase
GPG_PRIV_KEY:
from_secret: gpg_priv_key
from_secret: packages_gpg_private_key
GPG_PUB_KEY:
from_secret: gpg_pub_key
from_secret: packages_gpg_public_key
GRAFANA_COM_API_KEY:
from_secret: grafana_api_key
image: grafana/grafana-ci-deploy:1.3.3
@@ -3797,11 +3797,11 @@ steps:
GCP_KEY:
from_secret: gcp_key
GPG_KEY_PASSWORD:
from_secret: gpg_key_password
from_secret: packages_gpg_passphrase
GPG_PRIV_KEY:
from_secret: gpg_priv_key
from_secret: packages_gpg_private_key
GPG_PUB_KEY:
from_secret: gpg_pub_key
from_secret: packages_gpg_public_key
GRAFANA_COM_API_KEY:
from_secret: grafana_api_key
image: grafana/grafana-ci-deploy:1.3.3
@@ -3910,11 +3910,11 @@ steps:
GCP_KEY:
from_secret: gcp_key
GPG_KEY_PASSWORD:
from_secret: gpg_key_password
from_secret: packages_gpg_passphrase
GPG_PRIV_KEY:
from_secret: gpg_priv_key
from_secret: packages_gpg_private_key
GPG_PUB_KEY:
from_secret: gpg_pub_key
from_secret: packages_gpg_public_key
GRAFANA_COM_API_KEY:
from_secret: grafana_api_key
image: grafana/grafana-ci-deploy:1.3.3
@@ -5657,6 +5657,6 @@ kind: secret
name: aws_secret_access_key
---
kind: signature
hmac: 4cd9c45598335fad9a2d337ada7b09c6620038bbd878683bb78281cf2de6d1de
hmac: 613244b7c6b51cdcbfb71f124850e27da526b72b2c07c7c660356b484b3e7cb4
...

4
go.mod
View File

@@ -30,7 +30,7 @@ require (
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
github.com/centrifugal/centrifuge v0.25.0
github.com/cortexproject/cortex v1.10.1-0.20211014125347-85c378182d0d
github.com/crewjam/saml v0.4.8
github.com/crewjam/saml v0.4.9
github.com/davecgh/go-spew v1.1.1
github.com/denisenkom/go-mssqldb v0.12.0
github.com/dop251/goja v0.0.0-20210804101310-32956a348b49
@@ -341,7 +341,7 @@ require (
)
// Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.9-0.20220727151557-61cd9c9353fc
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.9-0.20230102094056-b61b9eb7c8b7
replace github.com/apache/thrift => github.com/apache/thrift v0.14.1

7
go.sum
View File

@@ -1257,7 +1257,6 @@ github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -1377,8 +1376,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.139.0 h1:2RQKM2QpSaWTtaGN6sK+R7LO7zy
github.com/grafana/grafana-plugin-sdk-go v0.139.0/go.mod h1:Y+Ps2sesZ62AyCnX+hzrYnyDQYe/ZZl+A8yKLOBm12c=
github.com/grafana/prometheus-alertmanager v0.24.1-0.20221012142027-823cd9150293 h1:dJIdfHqu+XjKz+w9zXLqXKPdp6Jjx/UPSOwdeSfWdeQ=
github.com/grafana/prometheus-alertmanager v0.24.1-0.20221012142027-823cd9150293/go.mod h1:HVHqK+BVPa/tmL8EMhLCCrPt2a1GdJpEyxr5hgur2UI=
github.com/grafana/saml v0.4.9-0.20220727151557-61cd9c9353fc h1:1PY8n+rXuBNr3r1JQhoytWDCpc+pq+BibxV0SZv+Cr4=
github.com/grafana/saml v0.4.9-0.20220727151557-61cd9c9353fc/go.mod h1:9Zh6dWPtB3MSzTRt8fIFH60Z351QQ+s7hCU3J/tTlA4=
github.com/grafana/saml v0.4.9-0.20230102094056-b61b9eb7c8b7 h1:cujJQ3XV6IK7Y96VpYurd2EpI5rfMRFcuyGqUlk+030=
github.com/grafana/saml v0.4.9-0.20230102094056-b61b9eb7c8b7/go.mod h1:9Zh6dWPtB3MSzTRt8fIFH60Z351QQ+s7hCU3J/tTlA4=
github.com/grafana/thema v0.0.0-20220817114012-ebeee841c104 h1:dYpwFYIChrMfpq3wDa/ZBxAbUGSW5NYmYBeSezhaoao=
github.com/grafana/thema v0.0.0-20220817114012-ebeee841c104/go.mod h1:fCV1rqv6XRQg2GfIQ7pU9zdxd5fLRcEBCnrDVwlK+ZY=
github.com/grafana/xorm v0.8.3-0.20220614223926-2fcda7565af6 h1:I9dh1MXGX0wGyxdV/Sl7+ugnki4Dfsy8lv2s5Yf887o=
@@ -1830,8 +1829,6 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=

View File

@@ -119,6 +119,7 @@
"@types/d3-force": "^2.1.0",
"@types/d3-scale-chromatic": "1.3.1",
"@types/debounce-promise": "3.1.4",
"@types/dompurify": "^2",
"@types/enzyme": "3.10.12",
"@types/enzyme-adapter-react-16": "1.0.6",
"@types/eslint": "8.4.5",
@@ -315,6 +316,7 @@
"dangerously-set-html-content": "1.0.9",
"date-fns": "2.29.1",
"debounce-promise": "3.1.2",
"dompurify": "^2.4.1",
"emotion": "11.0.0",
"eventemitter3": "4.0.7",
"fast-deep-equal": "^3.1.3",

View File

@@ -57,9 +57,13 @@ export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
console.warn('Icon component passed an invalid icon name', name);
}
if (!name || name.includes('..')) {
return <div ref={ref}>invalid icon name</div>;
}
const svgSize = getSvgSize(size);
const svgHgt = svgSize;
const svgWid = name?.startsWith('gf-bar-align') ? 16 : name?.startsWith('gf-interp') ? 30 : svgSize;
const svgWid = name.startsWith('gf-bar-align') ? 16 : name.startsWith('gf-interp') ? 30 : svgSize;
const subDir = getIconSubDir(name, type);
const svgPath = `${iconRoot}${subDir}/${name}.svg`;

View File

@@ -0,0 +1,18 @@
import * as DOMPurify from 'dompurify';
import React from 'react';
import SVG, { Props } from 'react-inlinesvg';
export const SanitizedSVG = (props: Props) => {
return <SVG {...props} cacheRequests={true} preProcessor={getCleanSVG} />;
};
let cache = new Map<string, string>();
function getCleanSVG(code: string): string {
let clean = cache.get(code);
if (!clean) {
clean = DOMPurify.sanitize(code, { USE_PROFILES: { svg: true, svgFilters: true } });
cache.set(code, clean);
}
return clean;
}

View File

@@ -1,8 +1,8 @@
import { css } from '@emotion/css';
import { isString } from 'lodash';
import React, { CSSProperties } from 'react';
import SVG from 'react-inlinesvg';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import {
ColorDimensionConfig,
ResourceDimensionConfig,
@@ -59,7 +59,7 @@ export function IconDisplay(props: CanvasElementProps) {
};
return (
<SVG
<SanitizedSVG
onClick={onClick}
src={data.path}
style={svgStyle}

View File

@@ -1,11 +1,12 @@
import { css } from '@emotion/css';
import React, { Dispatch, SetStateAction, useState } from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { FileDropzone, useStyles2, Button, DropzoneFile, Field } from '@grafana/ui';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { MediaType } from '../types';
interface Props {
setFormData: Dispatch<SetStateAction<FormData>>;
mediaType: MediaType;
@@ -36,8 +37,8 @@ export const FileUploader = ({ mediaType, setFormData, setUpload, error }: Props
const Preview = () => (
<Field label="Preview">
<div className={styles.iconPreview}>
{mediaType === MediaType.Icon && <SVG src={file} className={styles.img} />}
{mediaType === MediaType.Image && <img src={file} className={styles.img} />}
{mediaType === MediaType.Icon && <SanitizedSVG src={file} className={styles.img} />}
{mediaType === MediaType.Image && <img src={file} alt="Preview of the uploaded file" className={styles.img} />}
</div>
</Field>
);

View File

@@ -1,11 +1,11 @@
import { css, cx } from '@emotion/css';
import React, { memo, CSSProperties } from 'react';
import SVG from 'react-inlinesvg';
import AutoSizer from 'react-virtualized-auto-sizer';
import { areEqual, FixedSizeGrid as Grid } from 'react-window';
import { GrafanaTheme2 } from '@grafana/data';
import { useTheme2, stylesFactory } from '@grafana/ui';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { ResourceItem } from './FolderPickerTab';
@@ -38,7 +38,7 @@ function Cell(props: CellProps) {
onClick={() => onChange(card.value)}
>
{card.imgUrl.endsWith('.svg') ? (
<SVG src={card.imgUrl} className={styles.img} />
<SanitizedSVG src={card.imgUrl} className={styles.img} />
) : (
<img src={card.imgUrl} className={styles.img} />
)}

View File

@@ -1,6 +1,5 @@
import { css } from '@emotion/css';
import React, { createRef } from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import {
@@ -15,6 +14,7 @@ import {
useTheme2,
} from '@grafana/ui';
import { closePopover } from '@grafana/ui/src/utils/closePopover';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { getPublicOrAbsoluteUrl } from '../resource';
import { MediaType, ResourceFolderName, ResourcePickerSize } from '../types';
@@ -56,7 +56,7 @@ export const ResourcePicker = (props: Props) => {
const renderSmallResourcePicker = () => {
if (value && sanitizedSrc) {
return <SVG src={sanitizedSrc} className={styles.icon} style={{ ...colorStyle }} />;
return <SanitizedSVG src={sanitizedSrc} className={styles.icon} style={{ ...colorStyle }} />;
} else {
return (
<LinkButton variant="primary" fill="text" size="sm">
@@ -73,7 +73,7 @@ export const ResourcePicker = (props: Props) => {
value={name}
placeholder={placeholder}
readOnly={true}
prefix={sanitizedSrc && <SVG src={sanitizedSrc} className={styles.icon} style={{ ...colorStyle }} />}
prefix={sanitizedSrc && <SanitizedSVG src={sanitizedSrc} className={styles.icon} style={{ ...colorStyle }} />}
suffix={<Button icon="times" variant="secondary" fill="text" size="sm" onClick={onClear} />}
/>
</InlineField>

View File

@@ -1,9 +1,9 @@
import { css } from '@emotion/css';
import React, { Dispatch, SetStateAction } from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { Field, Input, Label, useStyles2 } from '@grafana/ui';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { getPublicOrAbsoluteUrl } from '../resource';
import { MediaType } from '../types';
@@ -33,7 +33,7 @@ export const URLPickerTab = (props: Props) => {
<div className={styles.iconContainer}>
<Field label="Preview">
<div className={styles.iconPreview}>
{mediaType === MediaType.Icon && <SVG src={imgSrc} className={styles.img} />}
{mediaType === MediaType.Icon && <SanitizedSVG src={imgSrc} className={styles.img} />}
{mediaType === MediaType.Image && newValue && <img src={imgSrc} className={styles.img} />}
</div>
</Field>

View File

@@ -1,12 +1,12 @@
import { css } from '@emotion/css';
import { isString } from 'lodash';
import React, { useMemo } from 'react';
import SVG from 'react-inlinesvg';
import { useAsync } from 'react-use';
import AutoSizer from 'react-virtualized-auto-sizer';
import { DataFrame, GrafanaTheme2 } from '@grafana/data';
import { CodeEditor, useStyles2 } from '@grafana/ui';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { getGrafanaStorage } from './storage';
import { StorageView } from './types';
@@ -55,7 +55,7 @@ export function FileView({ listing, path, onPathChange, view }: Props) {
case 'svg':
return (
<div>
<SVG src={src} className={styles.icon} />
<SanitizedSVG src={src} className={styles.icon} />
</div>
);
case 'image':

View File

@@ -1,7 +1,6 @@
import { css, cx } from '@emotion/css';
import BaseLayer from 'ol/layer/Base';
import React, { useMemo } from 'react';
import SVG from 'react-inlinesvg';
import { useObservable } from 'react-use';
import { of } from 'rxjs';
@@ -9,6 +8,7 @@ import { DataFrame, formattedValueToString, getFieldColorModeForField, GrafanaTh
import { getMinMaxAndDelta } from '@grafana/data/src/field/scale';
import { useStyles2, VizLegendItem } from '@grafana/ui';
import { ColorScale } from 'app/core/components/ColorScale/ColorScale';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { config } from 'app/core/config';
import { DimensionSupplier } from 'app/features/dimensions';
import { getThresholdItems } from 'app/plugins/panel/state-timeline/utils';
@@ -58,7 +58,7 @@ export function MarkersLegend(props: MarkersLegendProps) {
<div className={style.infoWrap}>
<div className={style.layerName}>{layerName}</div>
<div className={cx(style.layerBody, style.fixedColorContainer)}>
<SVG
<SanitizedSVG
src={`public/${symbol}`}
className={style.legendSymbol}
title={'Symbol'}

View File

@@ -1,3 +1,4 @@
import * as DOMPurify from 'dompurify';
import { Fill, RegularShape, Stroke, Circle, Style, Icon, Text } from 'ol/style';
import tinycolor from 'tinycolor2';
@@ -247,6 +248,8 @@ async function prepareSVG(url: string, size?: number): Promise<string> {
return res.text();
})
.then((text) => {
text = DOMPurify.sanitize(text, { USE_PROFILES: { svg: true, svgFilters: true } });
const parser = new DOMParser();
const doc = parser.parseFromString(text, 'image/svg+xml');
const svg = doc.getElementsByTagName('svg')[0];

View File

@@ -1003,9 +1003,9 @@ def publish_packages_step(edition, ver_mode):
'environment': {
'GRAFANA_COM_API_KEY': from_secret('grafana_api_key'),
'GCP_KEY': from_secret('gcp_key'),
'GPG_PRIV_KEY': from_secret('gpg_priv_key'),
'GPG_PUB_KEY': from_secret('gpg_pub_key'),
'GPG_KEY_PASSWORD': from_secret('gpg_key_password'),
'GPG_PRIV_KEY': from_secret('packages_gpg_private_key'),
'GPG_PUB_KEY': from_secret('packages_gpg_public_key'),
'GPG_KEY_PASSWORD': from_secret('packages_gpg_passphrase'),
},
'commands': [
cmd,

View File

@@ -11635,6 +11635,15 @@ __metadata:
languageName: node
linkType: hard
"@types/dompurify@npm:^2":
version: 2.4.0
resolution: "@types/dompurify@npm:2.4.0"
dependencies:
"@types/trusted-types": "*"
checksum: b48cd81e997794ebc390c7c5bef1a67ec14a6f2f0521973e07e06af186c7583abe114d94d24868c0632b9573f5bd77131a4b76f3fffdf089ba99a4e53dd46c39
languageName: node
linkType: hard
"@types/enzyme-adapter-react-16@npm:1.0.6":
version: 1.0.6
resolution: "@types/enzyme-adapter-react-16@npm:1.0.6"
@@ -12859,6 +12868,13 @@ __metadata:
languageName: node
linkType: hard
"@types/trusted-types@npm:*":
version: 2.0.2
resolution: "@types/trusted-types@npm:2.0.2"
checksum: 3371eef5f1c50e1c3c07a127c1207b262ba65b83dd167a1c460fc1b135a3fb0c97b9f508efebd383f239cc5dd5b7169093686a692a501fde9c3f7208657d9b0d
languageName: node
linkType: hard
"@types/uglify-js@npm:*":
version: 3.13.1
resolution: "@types/uglify-js@npm:3.13.1"
@@ -18730,6 +18746,13 @@ __metadata:
languageName: node
linkType: hard
"dompurify@npm:^2.4.1":
version: 2.4.1
resolution: "dompurify@npm:2.4.1"
checksum: 1169177465b3cbb25a44322937fba549f6c4e1a91b83245d144471be26619c835cccf0f8e20aa78c25ac11a06efd17cc1b9db9cacadceb78a4c08a1029eafee5
languageName: node
linkType: hard
"domutils@npm:^2.5.2, domutils@npm:^2.6.0, domutils@npm:^2.7.0":
version: 2.8.0
resolution: "domutils@npm:2.8.0"
@@ -21841,6 +21864,7 @@ __metadata:
"@types/d3-force": ^2.1.0
"@types/d3-scale-chromatic": 1.3.1
"@types/debounce-promise": 3.1.4
"@types/dompurify": ^2
"@types/enzyme": 3.10.12
"@types/enzyme-adapter-react-16": 1.0.6
"@types/eslint": 8.4.5
@@ -21929,6 +21953,7 @@ __metadata:
dangerously-set-html-content: 1.0.9
date-fns: 2.29.1
debounce-promise: 3.1.2
dompurify: ^2.4.1
emotion: 11.0.0
enzyme: 3.11.0
enzyme-to-json: 3.6.2