Custom Templates
Example Templates
Custom Templates
Example Templates
BROKEN_AUTHENTICATION
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing"
export default {
name: "BROKEN_AUTHENTICATION",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
if (!endpoint.authConfig) {
throw new Error(`No auth config defined for host: "${endpoint.host}"...`)
}
return new TestBuilder()
.setMeta({
name: `${endpoint.path} Broken Authentication`,
severity: "HIGH",
tags: ["BROKEN_AUTHENTICATION"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint).assert({
type: AssertionType.JS,
value: "resp.status < 300",
}),
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint).assert({
type: AssertionType.EQ,
key: "resp.status",
value: [401, 403],
}),
)
},
}
BOLA
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing"
export default {
name: "BOLA",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
if (!endpoint.authConfig) {
throw new Error(`No auth config defined for host: "${endpoint.host}"...`)
}
return new TestBuilder()
.setMeta({
name: `${endpoint.path} BOLA`,
severity: "HIGH",
tags: ["BOLA"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint, "USER_A").assert({
type: AssertionType.JS,
value: "resp.status < 300",
}),
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint, "USER_A")
.addAuth(endpoint, "USER_B")
.assert({
type: AssertionType.EQ,
key: "resp.status",
value: [401, 403],
}),
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint, "USER_B")
.addAuth(endpoint, "USER_A")
.assert({
type: AssertionType.EQ,
key: "resp.status",
value: [401, 403],
}),
)
},
}
BOLA_ADMIN
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing";
export default {
name: "BOLA_ADMIN",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
if (!endpoint.authConfig) {
throw new Error(`No auth config defined for host: "${endpoint.host}"...`);
}
return new TestBuilder()
.setMeta({
name: `${endpoint.path} BOLA_ADMIN`,
severity: "HIGH",
tags: ["BOLA", "ADMIN"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint, "ADMIN_USER").assert({
type: AssertionType.enum.JS,
value: "resp.status < 300",
})
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint, "ADMIN_USER")
.addAuth(endpoint, "NON_ADMIN_USER")
.assert({
type: AssertionType.enum.EQ,
key: "resp.status",
value: [401, 403, 404],
})
);
},
};
BOLA_MULTI_TENANT
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing";
export default {
name: "BOLA_MULTI_TENANT",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
if (!endpoint.authConfig) {
throw new Error(`No auth config defined for host: "${endpoint.host}"...`);
}
return new TestBuilder()
.setMeta({
name: `${endpoint.path} BOLA_MULTI_TENANT`,
severity: "HIGH",
tags: ["BOLA", "MULTI-TENANT"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint, "TENANT_A").assert({
type: AssertionType.enum.JS,
value: "resp.status < 300",
})
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint, "TENANT_A")
.addAuth(endpoint, "TENANT_B")
.assert({
type: AssertionType.enum.EQ,
key: "resp.status",
value: [404],
})
)
.addTestStep(
TestStepBuilder.sampleRequestWithoutAuth(endpoint, "TENANT_B")
.addAuth(endpoint, "TENANT_A")
.assert({
type: AssertionType.enum.EQ,
key: "resp.status",
value: [404],
})
);
},
};
HSTS
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing";
export default {
name: "HSTS",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
return new TestBuilder()
.setMeta({
name: `${endpoint.path} Has HSTS Headers`,
severity: "MEDIUM",
tags: ["HSTS"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint).assert({
type: AssertionType.JS,
value: "resp.headers['strict-transport-security']",
})
);
},
};
SQLI_TIME_BASED
TypeScript
import { GenTestEndpoint, TestBuilder, TestStepBuilder } from "@metlo/testing";
export default {
name: "SQLI_TIME_BASED",
version: 1,
builder: (endpoint: GenTestEndpoint) =>
new TestBuilder()
.setMeta({
name: `${endpoint.path} SQLI TIME BASED`,
severity: "HIGH",
tags: ["SQLI_TIME_BASED"],
})
.setOptions({
stopOnFailure: true,
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint)
.addPayloads({
key: "SQLI_PAYLOAD",
value: "SQLI_TIME",
})
.modifyRequest((req) => {
if (req.query && req.query.length > 0) {
req.query[0].value = "{{SQLI_PAYLOAD}}";
return req;
}
if (req.form && req.form.length > 0) {
req.form[0].value = "{{SQLI_PAYLOAD}}";
return req;
}
if (
req.data &&
req.headers?.find((e) => e.name == "Content-Type")?.value ==
"application/json"
) {
const parsed = JSON.parse(req.data);
const keys = Object.keys(parsed);
if (keys.length > 0) {
parsed[keys[0]] = "{{SQLI_PAYLOAD}}";
}
req.data = JSON.stringify(parsed, null, 4);
return req;
}
return req;
})
.assert("resp.duration < 1000")
),
};
CSP
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing";
export default {
name: "CSP",
version: 1,
builder: (endpoint: GenTestEndpoint) => {
return new TestBuilder()
.setMeta({
name: `${endpoint.path} Has CSP Headers`,
severity: "LOW",
tags: ["CSP"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint).assert({
type: AssertionType.JS,
value: "resp.headers['content-security-policy']",
})
);
},
};
GENERIC
TypeScript
import {
GenTestEndpoint,
TestBuilder,
TestStepBuilder,
AssertionType,
} from "@metlo/testing";
export default {
name: "GENERIC",
version: 1,
builder: (endpoint: GenTestEndpoint) =>
new TestBuilder()
.setMeta({
name: `${endpoint.path} Test`,
severity: "LOW",
tags: ["GENERIC"],
})
.addTestStep(
TestStepBuilder.sampleRequest(endpoint).assert({
type: AssertionType.JS,
value: "resp.status < 300",
})
),
};