Skip to content

Commit

Permalink
Merge pull request from GHSA-h4w9-6x78-8vrj
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix tests/lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
  • Loading branch information
crenshaw-dev committed Jun 21, 2022
1 parent 8fe9a58 commit 8bc3ef6
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
1 change: 1 addition & 0 deletions server/server.go
Expand Up @@ -1010,6 +1010,7 @@ func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error
if !argoCDSettings.AnonymousUserEnabled {
return ctx, claimsErr
} else {
// nolint:staticcheck
ctx = context.WithValue(ctx, "claims", "")
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/server_test.go
Expand Up @@ -508,7 +508,7 @@ func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool) (argoc
cm.Data["users.anonymous.enabled"] = "true"
}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
return // Start with a placeholder. We need the server URL before setting up the real handler.
// Start with a placeholder. We need the server URL before setting up the real handler.
}))
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dexMockHandler(t, ts.URL)(w, r)
Expand Down
20 changes: 20 additions & 0 deletions ui/src/app/applications/components/application-urls.test.ts
@@ -0,0 +1,20 @@
import {ExternalLink, InvalidExternalLinkError} from './application-urls';

test('rejects malicious URLs', () => {
expect(() => {
const _ = new ExternalLink('javascript:alert("hi")');
}).toThrowError(InvalidExternalLinkError);
expect(() => {
const _ = new ExternalLink('data:text/html;<h1>hi</h1>');
}).toThrowError(InvalidExternalLinkError);
});

test('allows absolute URLs', () => {
expect(new ExternalLink('https://localhost:8080/applications').ref).toEqual('https://localhost:8080/applications');
});

test('allows relative URLs', () => {
// @ts-ignore
window.location = new URL('https://localhost:8080/applications');
expect(new ExternalLink('/applications').ref).toEqual('/applications');
});
35 changes: 33 additions & 2 deletions ui/src/app/applications/components/application-urls.tsx
@@ -1,7 +1,15 @@
import {DropDownMenu} from 'argo-ui';
import * as React from 'react';

class ExternalLink {
export class InvalidExternalLinkError extends Error {
constructor(message: string) {
super(message);
Object.setPrototypeOf(this, InvalidExternalLinkError.prototype);
this.name = 'InvalidExternalLinkError';
}
}

export class ExternalLink {
public title: string;
public ref: string;

Expand All @@ -14,13 +22,36 @@ class ExternalLink {
this.title = url;
this.ref = url;
}
if (!ExternalLink.isValidURL(this.ref)) {
throw new InvalidExternalLinkError('Invalid URL');
}
}

private static isValidURL(url: string): boolean {
try {
const parsedUrl = new URL(url);
return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:';
} catch (TypeError) {
try {
// Try parsing as a relative URL.
const parsedUrl = new URL(url, window.location.origin);
return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:';
} catch (TypeError) {
return false;
}
}
}
}

export const ApplicationURLs = ({urls}: {urls: string[]}) => {
const externalLinks: ExternalLink[] = [];
for (const url of urls || []) {
externalLinks.push(new ExternalLink(url));
try {
const externalLink = new ExternalLink(url);
externalLinks.push(externalLink);
} catch (InvalidExternalLinkError) {
continue;
}
}

// sorted alphabetically & links with titles first
Expand Down

0 comments on commit 8bc3ef6

Please sign in to comment.