T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:450
- Finding
- Unrestricted bulk database deletion in generated test teardown## Vulnerability Details **File Location**: `SKILL.md:349`, `SKILL.md:450-454`, `SKILL.md:579`, and `SKILL.md:615` **Vulnerability Type**: Unguarded destructive database operation **Risk Level**: High ### Vulnerable Code ```typescript const prisma = new PrismaClient(); ``` ```typescript export async function clearTestData() { // Delete in reverse dependency order (children before parents) await prisma.order.deleteMany(); await prisma.post.deleteMany(); await prisma.user.deleteMany(); } ``` The generated report also recommends automatic invocation during test teardown: ```typescript afterAll(clearTestData); ``` ### Technical Analysis The generated `PrismaClient` uses the application's ambient Prisma configuration, while `clearTestData()` performs unfiltered `deleteMany()` operations. Each operation deletes every accessible row in the corresponding table. The cleanup function does not verify that: - The process is running in a test environment. - The configured database is a dedicated test database. - The database host or name belongs to an approved test allowlist. - The records were created by the current test run. - The user explicitly authorized destructive cleanup. The skill also recommends connecting the function to `afterAll`, causing it to run automatically. If a developer accidentally supplies production or shared-environment database credentials, normal test execution can therefore trigger destructive deletion without an additional confirmation step. ### Attack Path 1. A user follows the skill and generates Prisma test factories. 2. The generated setup constructs `PrismaClient` from the current environment configuration. 3. The user or CI system runs the test suite with a production, staging, or shared database URL due to configuration error or environment-variable manipulation. 4. The test framework invokes `afterAll(clearTestData)`. 5. `deleteMany()` executes without ...[truncated 815 chars]
- Remediation
- ## Remediation Suggestions 1. Make cleanup explicitly opt-in rather than automatically registering it with `afterAll`. 2. Fail closed unless the process is demonstrably running in a test environment: ```typescript function assertSafeTestDatabase() { if (process.env.NODE_ENV !== 'test') { throw new Error('Database cleanup is restricted to NODE_ENV=test'); } const databaseUrl = process.env.DATABASE_URL; if (!databaseUrl) { throw new Error('DATABASE_URL is required'); } const parsed = new URL(databaseUrl); const approvedDatabases = new Set(['app_test', 'app_test_ci']); if (!approvedDatabases.has(parsed.pathname.replace(/^\//, ''))) { throw new Error('Refusing to clean a non-approved database'); } } ``` 3. Invoke the guard immediately before every destructive operation. 4. Tag generated records with a unique test-run identifier and delete only records carrying that identifier. 5. Prefer transaction-based isolation followed by rollback rather than table-wide deletion. 6. Use a dedicated database account restricted to a dedicated test database. 7. Require an additional explicit environment variable, such as `ALLOW_TEST_DATA_DELETION=true`, for destructive cleanup. 8. Prevent test and CI credentials from accessing production databases through network and database-level access controls.
