Skip to content

Commit 85817c2

Browse files
chore(chat): add CSP headers, bump minimatch to 10.2.4 (#5917)
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent fe5534d commit 85817c2

18 files changed

Lines changed: 304 additions & 567 deletions

.github/workflows/deploy-development.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
gitlab-project-id: "3016"
2525

2626
name: Deploy to ${{ matrix.environment-name }}
27-
uses: epam/ai-dial-ci/.github/workflows/deploy-development.yml@3.1.2
27+
uses: epam/ai-dial-ci/.github/workflows/deploy-development.yml@3.1.3
2828
with:
2929
gitlab-project-id: ${{ matrix.gitlab-project-id }}
3030
environment-name: ${{ matrix.environment-name }}

.github/workflows/pr-title-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ concurrency:
1313

1414
jobs:
1515
pr-title-check:
16-
uses: epam/ai-dial-ci/.github/workflows/pr-title-check.yml@3.1.2
16+
uses: epam/ai-dial-ci/.github/workflows/pr-title-check.yml@3.1.3
1717
secrets:
1818
ACTIONS_BOT_TOKEN: ${{ secrets.ACTIONS_BOT_TOKEN }}

.github/workflows/pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ concurrency:
1010

1111
jobs:
1212
run_tests:
13-
uses: epam/ai-dial-ci/.github/workflows/node_pr.yml@3.1.2
13+
uses: epam/ai-dial-ci/.github/workflows/node_pr.yml@3.1.3
1414
secrets: inherit
1515
with:
1616
node-version: 24

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ concurrency:
1010

1111
jobs:
1212
release:
13-
uses: epam/ai-dial-ci/.github/workflows/node_release.yml@3.1.2
13+
uses: epam/ai-dial-ci/.github/workflows/node_release.yml@3.1.3
1414
secrets: inherit
1515
with:
1616
node-version: 24

.trivyignore

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
# node:24-alpine vulnerabilities in https://hub.docker.com/layers/library/node/24-alpine
2-
CVE-2026-25547 exp:2026-05-20
3-
CVE-2026-26996 exp:2026-05-20
4-
CVE-2026-24842 exp:2026-05-20
5-
CVE-2026-26960 exp:2026-05-20
2+
CVE-2026-22184 exp:2026-05-20

apps/chat/.env.development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ NEXT_PUBLIC_OVERLAY_HOST="localhost:3000"
153153
TOPICS="Business,Development,User Experience,Analysis,SQL,SDLC,Talk-To-Your-Data,RAG,Text Generation,Image Generation,Image Recognition"
154154
# CODE_EDITOR_PYTHON_VERSIONS="python3.11,python3.12"
155155

156-
# NEXT_PUBLIC_STAGE_CONTENT_LIMIT="400"
156+
NEXT_PUBLIC_STAGE_CONTENT_LIMIT="100"
157157

158158
# HIDDEN_ENTITY_TAG=""
159159
AUTH_IDTOKEN_PROVIDERS="google,gitlab"

apps/chat/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ DIAL Chat uses environment variables for configuration. All environment variable
107107
| `DIAL_API_VERSION` | No | DIAL API Version | Any string | `2025-01-01-preview` |
108108
| `APP_BASE_PATH` | No | The root directory in the file system where the application is located | Any string | |
109109
| `APP_BASE_ORIGIN` | Optional | A base URL or origin of the application.<br />Required if `APP_BASE_PATH` is set. | Any string | |
110-
| `ALLOWED_IFRAME_ORIGINS` | No | Specifies all URLs that are allowed to embed DIAL Chat within an iframe.<br />Necessary for [DIAL Overlay](../../libs/overlay/README.md). | Any origin valid format. List of space separated URLs. | `none` |
111-
| `ALLOWED_IFRAME_SOURCES` | No | iFrame sources (e.g. [visualizers](https://github.com/epam/ai-dial-chat/blob/development/libs/chat-visualizer-connector/README.md)) that are allowed to load content into an iframe in the DIAL Chat application | Any valid source format. List of space separated sources. | `none` |
110+
| `ALLOWED_IFRAME_ORIGINS` | No | Specifies all URLs that are allowed to embed DIAL Chat within an iframe.<br />Necessary for [DIAL Overlay](../../libs/overlay/README.md). (`frame-ancestors` directive of Content Security Policy (CSP)) | Any origin valid format. List of space separated URLs. | `none` |
111+
| `ALLOWED_IFRAME_SOURCES` | No | iFrame sources (e.g. [visualizers](https://github.com/epam/ai-dial-chat/blob/development/libs/chat-visualizer-connector/README.md)) that are allowed to load content into an iframe in the DIAL Chat application (`frame-src` directive of Content Security Policy (CSP)) | Any valid source format. List of space separated sources. | `none` |
112+
| `ALLOWED_SCRIPT_SOURCES` | No | Specifies `script-src` directive of Content Security Policy (CSP) : define from where scripts can be executed | Any origin valid format. List of space separated URLs. | `'self' ALLOWED_IFRAME_ORIGINS ALLOWED_IFRAME_SOURCES` |
112113
| `IS_IFRAME` | No | Is iFrame flag enables/disables the [DIAL Overlay](../../libs/overlay/README.md) | `true`, `false` | `false` |
113114
| `ALLOW_OPEN_SIGNIN_PAGE_IN_IFRAME` | No | This is the iFrame flag for the [DIAL Overlay](../../libs/overlay/README.md) enables the Sign-In page to render within an iFrame. Activating this flag disables the `X-Frame-Options: SAMEORIGIN` header and enforces the `frame-ancestors` directive using the URLs specified in the `ALLOWED_IFRAME_ORIGINS` variable. | `true`, `false` | `false` |
114115
| `ENABLED_FEATURES` | No | Features enabled in the DIAL Chat application. [See details](/docs/ENABLED_FEATURES_ROLES.md) | Refer to [Features](../../libs/shared/src/types/features.ts) to view all the available features. | |

apps/chat/environment.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ declare global {
1616
APP_BASE_PATH?: string;
1717
APP_BASE_ORIGIN?: string;
1818
ALLOWED_IFRAME_ORIGINS?: string;
19+
ALLOWED_IFRAME_SOURCES?: string;
20+
ALLOWED_SCRIPT_SOURCES?: string;
1921
IS_IFRAME?: string;
2022
ALLOW_OPEN_SIGNIN_PAGE_IN_IFRAME?: string;
21-
ALLOWED_IFRAME_SOURCES?: string;
2223
CUSTOM_VISUALIZERS?: string;
2324
ALLOW_VISUALIZER_SEND_MESSAGES?: boolean;
2425
ENABLED_FEATURES?: string;

apps/chat/src/components/Chat/MessageStage.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { getDownLoadCurrentDate } from '@/src/utils/app/import-export';
1414

1515
import { Translation } from '@/src/types/translation';
1616

17+
import { useAppSelector } from '@/src/store/hooks';
18+
import { SettingsSelectors } from '@/src/store/selectors';
19+
1720
import { Spinner } from '@/src/components/Common/Spinner';
1821
import { Tooltip } from '@/src/components/Common/Tooltip';
1922
import { ChatMDComponent } from '@/src/components/Markdown/ChatMDComponent';
@@ -60,14 +63,12 @@ const StageTitle = ({ isOpened, stage }: StageTitleProps) => (
6063
</div>
6164
);
6265

63-
const getLimitStageContent = () =>
64-
parseFloat(process.env.NEXT_PUBLIC_STAGE_CONTENT_LIMIT ?? '40');
65-
66-
interface Props {
67-
stage: Stage;
66+
interface DownloadStageViewProps {
67+
content: string;
68+
limit: number;
6869
}
6970

70-
const DownloadStageView = ({ content }: { content: string }) => {
71+
const DownloadStageView = ({ content, limit }: DownloadStageViewProps) => {
7172
const { t } = useTranslation(Translation.Chat);
7273

7374
const { copied: isCopied, onCopy: copyToClipboard } = useCopy(content, true);
@@ -89,9 +90,7 @@ const DownloadStageView = ({ content }: { content: string }) => {
8990

9091
return (
9192
<div className="flex justify-between gap-1 ps-1">
92-
{t(
93-
`Content is too large to display (exceeds ${getLimitStageContent()} KB).`,
94-
)}
93+
{t(`Content is too large to display (exceeds ${limit} KB).`)}
9594
<div className="flex items-center gap-3 text-secondary">
9695
<DialButton
9796
className="[&:not(:disabled)]:hover:text-accent-primary"
@@ -124,10 +123,13 @@ const DownloadStageView = ({ content }: { content: string }) => {
124123
const StageView = ({ content }: { content: string }) => {
125124
// Calculate byte size of the string
126125
const size = useMemo(() => new Blob([content]).size, [content]);
126+
const stageContentLimit = useAppSelector(
127+
SettingsSelectors.selectStageContentLimit,
128+
);
127129

128130
// in bytes
129-
if (size > getLimitStageContent() * 1024) {
130-
return <DownloadStageView content={content} />;
131+
if (size > stageContentLimit * 1024) {
132+
return <DownloadStageView content={content} limit={stageContentLimit} />;
131133
}
132134
return (
133135
<span className="inline-block overflow-auto">
@@ -136,7 +138,11 @@ const StageView = ({ content }: { content: string }) => {
136138
);
137139
};
138140

139-
export const MessageStage = ({ stage }: Props) => {
141+
interface MessageStageProps {
142+
stage: Stage;
143+
}
144+
145+
export const MessageStage = ({ stage }: MessageStageProps) => {
140146
const [isOpened, setIsOpened] = useState(false);
141147
const [hasContent, setHasContent] = useState(
142148
() => !!(stage?.content || stage?.attachments?.length),

apps/chat/src/middleware.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,15 @@ import { HeadersNames } from './constants/server';
1010
export function middleware(request: NextRequest) {
1111
const path = request.nextUrl.pathname;
1212

13-
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
14-
15-
const isDev = process.env.NODE_ENV === 'development';
1613
const shouldIgnoreFrameOptions =
1714
(!process.env.ALLOW_OPEN_SIGNIN_PAGE_IN_IFRAME ||
1815
process.env.ALLOW_OPEN_SIGNIN_PAGE_IN_IFRAME === 'false') &&
1916
(path === '/auth/signin' || path === '/api/auth/signin');
2017

21-
const frameDirectives = getFrameContentSecurityPolicyDirectives(
22-
process.env.ALLOWED_IFRAME_ORIGINS,
23-
process.env.ALLOWED_IFRAME_SOURCES,
18+
const [cspHeader, nonce] = getFrameContentSecurityPolicyDirectives(
2419
shouldIgnoreFrameOptions,
2520
);
26-
const allowedScriptsSrc =
27-
`${process.env.ALLOWED_IFRAME_ORIGINS ?? ''} ${process.env.ALLOWED_IFRAME_SOURCES ?? ''}`.replace(
28-
"'self'",
29-
'',
30-
);
31-
const cspHeader = `
32-
object-src 'none';
33-
base-uri 'self';
34-
script-src 'self' ${allowedScriptsSrc}
35-
https://cdn.jsdelivr.net/npm/monaco-editor@0.54.0/
36-
'nonce-${nonce}' 'wasm-unsafe-eval' ${isDev ? "'unsafe-eval'" : ''};
37-
worker-src 'self' blob:;
38-
${frameDirectives}
39-
`;
21+
4022
// Replace newline characters and spaces
4123
const contentSecurityPolicyHeaderValue = cleanHeaderDirectives(cspHeader);
4224

0 commit comments

Comments
 (0)