Skip to content

Commit 8bc3ef6

Browse files
authored
Merge pull request from GHSA-h4w9-6x78-8vrj
Signed-off-by: Michael Crenshaw <[email protected]> fix tests/lint Signed-off-by: Michael Crenshaw <[email protected]>
1 parent 8fe9a58 commit 8bc3ef6

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@ func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error
10101010
if !argoCDSettings.AnonymousUserEnabled {
10111011
return ctx, claimsErr
10121012
} else {
1013+
// nolint:staticcheck
10131014
ctx = context.WithValue(ctx, "claims", "")
10141015
}
10151016
}

server/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool) (argoc
508508
cm.Data["users.anonymous.enabled"] = "true"
509509
}
510510
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
511-
return // Start with a placeholder. We need the server URL before setting up the real handler.
511+
// Start with a placeholder. We need the server URL before setting up the real handler.
512512
}))
513513
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
514514
dexMockHandler(t, ts.URL)(w, r)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {ExternalLink, InvalidExternalLinkError} from './application-urls';
2+
3+
test('rejects malicious URLs', () => {
4+
expect(() => {
5+
const _ = new ExternalLink('javascript:alert("hi")');
6+
}).toThrowError(InvalidExternalLinkError);
7+
expect(() => {
8+
const _ = new ExternalLink('data:text/html;<h1>hi</h1>');
9+
}).toThrowError(InvalidExternalLinkError);
10+
});
11+
12+
test('allows absolute URLs', () => {
13+
expect(new ExternalLink('https://localhost:8080/applications').ref).toEqual('https://localhost:8080/applications');
14+
});
15+
16+
test('allows relative URLs', () => {
17+
// @ts-ignore
18+
window.location = new URL('https://localhost:8080/applications');
19+
expect(new ExternalLink('/applications').ref).toEqual('/applications');
20+
});

ui/src/app/applications/components/application-urls.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import {DropDownMenu} from 'argo-ui';
22
import * as React from 'react';
33

4-
class ExternalLink {
4+
export class InvalidExternalLinkError extends Error {
5+
constructor(message: string) {
6+
super(message);
7+
Object.setPrototypeOf(this, InvalidExternalLinkError.prototype);
8+
this.name = 'InvalidExternalLinkError';
9+
}
10+
}
11+
12+
export class ExternalLink {
513
public title: string;
614
public ref: string;
715

@@ -14,13 +22,36 @@ class ExternalLink {
1422
this.title = url;
1523
this.ref = url;
1624
}
25+
if (!ExternalLink.isValidURL(this.ref)) {
26+
throw new InvalidExternalLinkError('Invalid URL');
27+
}
28+
}
29+
30+
private static isValidURL(url: string): boolean {
31+
try {
32+
const parsedUrl = new URL(url);
33+
return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:';
34+
} catch (TypeError) {
35+
try {
36+
// Try parsing as a relative URL.
37+
const parsedUrl = new URL(url, window.location.origin);
38+
return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:';
39+
} catch (TypeError) {
40+
return false;
41+
}
42+
}
1743
}
1844
}
1945

2046
export const ApplicationURLs = ({urls}: {urls: string[]}) => {
2147
const externalLinks: ExternalLink[] = [];
2248
for (const url of urls || []) {
23-
externalLinks.push(new ExternalLink(url));
49+
try {
50+
const externalLink = new ExternalLink(url);
51+
externalLinks.push(externalLink);
52+
} catch (InvalidExternalLinkError) {
53+
continue;
54+
}
2455
}
2556

2657
// sorted alphabetically & links with titles first

0 commit comments

Comments
 (0)