feat: more tests for url validation

This commit is contained in:
Hank Stoever
2020-11-06 16:39:51 -08:00
parent 7430cb90cc
commit cad6e6a489
8 changed files with 38 additions and 47 deletions

View File

@@ -1,7 +1,7 @@
import { ScreenPaths } from '@store/onboarding/types';
import { DecodedAuthRequest } from './dev/types';
import { event, page, setConfig, Providers } from '@blockstack/stats';
import { validUrl } from './validate-url';
import { isValidUrl } from './validate-url';
export const SECRET_KEY_FAQ_WHERE = 'View Secret Key FAQ (Where)';
export const SECRET_KEY_FAQ_LOSE = 'View Secret Key FAQ (Lose)';
@@ -63,7 +63,7 @@ export const doTrackScreenChange = (
if (titleNameMap[screen]) {
document.title = titleNameMap[screen];
}
if (decodedAuthRequest && !validUrl(decodedAuthRequest.redirect_uri)) return;
if (decodedAuthRequest && !isValidUrl(decodedAuthRequest.redirect_uri)) return;
const appURL = decodedAuthRequest ? new URL(decodedAuthRequest?.redirect_uri) : null;
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(async () => {

View File

@@ -1,7 +1,7 @@
import { DecodedAuthRequest } from './dev/types';
import { wordlists } from 'bip39';
import { FinishedTxData, shouldUsePopup } from '@stacks/connect';
import { validUrl } from './validate-url';
import { isValidUrl } from './validate-url';
export const getAuthRequestParam = () => {
const { hash } = document.location;
@@ -58,7 +58,7 @@ export const finalizeAuthResponse = ({
authResponse,
}: FinalizeAuthParams) => {
const dangerousUri = decodedAuthRequest.redirect_uri;
if (!validUrl(dangerousUri) || dangerousUri.includes('javascript')) {
if (!isValidUrl(dangerousUri) || dangerousUri.includes('javascript')) {
throw new Error('Cannot proceed auth with malformed url');
}
const redirect = `${dangerousUri}?authResponse=${authResponse}`;

View File

@@ -1,7 +1,5 @@
import { isUri } from 'valid-url';
import { isWebUri } from 'valid-url';
// https://stackoverflow.com/a/5717133/1141891
export function validUrl(str: string) {
const sanitized = isUri(str);
return !!sanitized;
export function isValidUrl(str: string) {
return !!isWebUri(str);
}

View File

@@ -22,7 +22,7 @@ import { useAnalytics } from '@common/hooks/use-analytics';
import { ScreenPaths } from '@store/onboarding/types';
import { useWallet } from '@common/hooks/use-wallet';
import { Navigate } from '@components/navigate';
import { validUrl } from '../../common/validate-url';
import { isValidUrl } from '../../common/validate-url';
interface ChooseAccountProps {
next: (identityIndex: number) => void;
@@ -67,7 +67,7 @@ export const ChooseAccount: React.FC<ChooseAccountProps> = ({ next }) => {
!wallet.walletConfig.hideWarningForReusingIdentity &&
authRequest.scopes.includes('publish_data')
) {
if (!validUrl(authRequest.redirect_uri)) {
if (!isValidUrl(authRequest.redirect_uri)) {
throw new Error('Cannot proceed with malformed url');
}
const url = new URL(authRequest.redirect_uri);

View File

@@ -1,5 +1,5 @@
import { AppState } from '..';
import { validUrl } from '../../common/validate-url';
import { isValidUrl } from '../../common/validate-url';
export const selectCurrentScreen = (state: AppState) => state.onboarding.screen;
@@ -35,7 +35,7 @@ export const selectFullAppIcon = (state: AppState) => {
authRequest?.redirect_uri &&
icon &&
!absoluteURLPattern.test(icon) &&
validUrl(authRequest.redirect_uri)
isValidUrl(authRequest.redirect_uri)
) {
const url = new URL(authRequest.redirect_uri);
url.pathname = icon;

View File

@@ -0,0 +1,23 @@
import { isValidUrl } from '../../src/common/validate-url';
describe('isValidUrl', () => {
test('accepts normal URLs', () => {
const normal = [
'http://example.com',
'https://blockstack.com/asdf?hey=true',
'https://blockstack.org/asdf#anchor',
];
normal.forEach(url => {
expect(isValidUrl(url)).toEqual(true);
});
});
test('rejects non http(s) schemas', () => {
const bad = ['javascript:alert("hello")//', 'web.org', 'javascript:console.log();'];
bad.forEach(url => {
expect(isValidUrl(url)).toEqual(false);
});
});
});

View File

@@ -8,7 +8,7 @@ import {
FungibleConditionCode,
createAssetInfo,
} from '@blockstack/stacks-transactions';
import { makeContractCallToken, TransactionPayload } from '../../../../packages/connect/src/index';
import { makeContractCallToken, TransactionPayload } from '../../../connect/src/index';
import BN from 'bn.js';
import { decodeToken } from 'blockstack';

View File

@@ -3046,36 +3046,11 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6"
integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=
"@types/node@*", "@types/node@>= 8", "@types/node@^12.7.12":
"@types/node@*", "@types/node@10.12.18", "@types/node@11.11.6", "@types/node@12.7.12", "@types/node@>= 8", "@types/node@^12.7.12", "@types/node@^13.11.1", "@types/node@^13.13.10", "@types/node@^14.6.0", "@types/node@^8.0.0":
version "12.7.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.12.tgz#7c6c571cc2f3f3ac4a59a5f2bd48f5bdbc8653cc"
integrity sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==
"@types/node@10.12.18":
version "10.12.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
"@types/node@11.11.6":
version "11.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a"
integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==
"@types/node@^13.11.1", "@types/node@^13.13.10":
version "13.13.30"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.30.tgz#1ed6e01e4ca576d5aec9cc802cc3bcf94c274192"
integrity sha512-HmqFpNzp3TSELxU/bUuRK+xzarVOAsR00hzcvM0TXrMlt/+wcSLa5q6YhTb6/cA6wqDCZLDcfd8fSL95x5h7AA==
"@types/node@^14.6.0":
version "14.14.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f"
integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==
"@types/node@^8.0.0":
version "8.10.66"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@@ -6874,7 +6849,7 @@ eslint-plugin-flowtype@^4.7.0:
dependencies:
lodash "^4.17.15"
eslint-plugin-import@>=2.20.2, eslint-plugin-import@^2.18.2, "eslint-plugin-import@^2.21.2 ":
eslint-plugin-import@2.21.2, eslint-plugin-import@>=2.20.2, eslint-plugin-import@^2.18.2, "eslint-plugin-import@^2.21.2 ":
version "2.21.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c"
integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==
@@ -15685,12 +15660,7 @@ typeforce@^1.11.3, typeforce@^1.11.5:
resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc"
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==
typescript@3.9.7:
version "3.9.7"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
typescript@^3.7.3, typescript@^3.9.3:
typescript@3.9.3, typescript@3.9.7, typescript@^3.7.3, typescript@^3.9.3:
version "3.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==