Getdiffense connects to your GitHub repos and automatically detects security vulnerabilities, database performance issues, and logic flaws — before the merge button is pressed.
No monthly fees. No credit card required to start. GitHub OAuth only.
Document lookup uses req.params.id without verifying ownership against req.user.id. Any authenticated user can access any document.
findMany() followed by per-item user.findUnique() inside loop. Will fire N+1 queries for N projects.
findMany() with no take limit. Will return entire table as dataset grows.
Built for TypeScript backends
The problem
Human reviewers are great at logic and readability. They are not trained to spot every IDOR pattern, every N+1 query, or every missing auth guard across hundreds of changed lines. That's what machines are for.
68%
of security incidents trace back to a code change that was reviewed and approved
4.5×
more expensive to fix a vulnerability post-deployment than pre-merge
12 min
average time a developer spends reviewing a pull request — not enough for deep security analysis
How it works
Your team keeps working the same way. Getdiffense runs silently in the background.
Select the repos you want covered. No code changes, no CI config, no YAML. Just select and go.
The webhook fires the moment a PR is opened or updated. Your team works exactly as before.
Security, Database, and Code agents each analyse the diff independently — simultaneously — in under 30 seconds.
Every finding includes the exact file path, line number, severity, and a plain-English explanation of the risk.
PR #142 · auth-refactor · 2.4s total
Real findings
Three real vulnerability classes, with the code pattern that triggers them and the exact finding Getdiffense produces.
A route that fetches a resource by ID from the URL without checking whether the requesting user owns it. Any authenticated user can read or mutate any other user's data.
router.get('/invoices/:id', requireAuth, async (req, res) => {
const invoice = await prisma.invoice.findUnique({
where: { id: req.params.id }, // ID comes from the URL
});
if (!invoice) return res.status(404).json({ error: 'Not found' });
// No ownership check — any logged-in user can access this
res.json(invoice);
});router.get('/invoices/:id', requireAuth, async (req, res) => {
const invoice = await prisma.invoice.findUnique({
where: {
id: req.params.id,
userId: req.currentUser.id, // ownership enforced at DB level
},
});
if (!invoice) return res.status(404).json({ error: 'Not found' });
res.json(invoice);
});IDOR: Invoice lookup at line 2 uses req.params.id without filtering by req.currentUser.id. Any authenticated session can enumerate and read all invoices.
Fetching a list of records then querying the database once per record inside a loop. Works fine in development with 10 rows. Destroys performance in production with 10,000.
async function getProjectsWithOwners(orgId: string) {
const projects = await prisma.project.findMany({
where: { orgId },
});
// N database queries for N projects
for (const project of projects) {
project.owner = await prisma.user.findUnique({
where: { id: project.ownerId },
});
}
return projects;
}async function getProjectsWithOwners(orgId: string) {
// 1 query total — Prisma joins the relation
const projects = await prisma.project.findMany({
where: { orgId },
include: { owner: true },
});
return projects;
}N+1 query: prisma.user.findUnique() called inside loop at line 8 after findMany() at line 2. Will execute N+1 queries for N projects. Use include: { owner: true } instead.
An admin endpoint that performs a privileged action but only checks that the user is logged in — not that they have the admin role.
router.delete('/admin/users/:id', requireAuth, async (req, res) => {
// requireAuth only checks the session exists.
// Any logged-in user can delete any account.
await prisma.user.delete({ where: { id: req.params.id } });
res.json({ deleted: true });
});router.delete(
'/admin/users/:id',
requireAuth,
requireRole('admin'), // explicit role check
async (req, res) => {
await prisma.user.delete({ where: { id: req.params.id } });
res.json({ deleted: true });
}
);Broken access control: DELETE /admin/users/:id at line 1 uses requireAuth but no role check. Any authenticated user can delete arbitrary accounts. Add requireRole('admin') middleware.
Detection coverage
Each agent has a focused system prompt and runs at temperature 0. Deterministic, structured JSON output — no hallucinated findings.
Pricing
No monthly subscriptions. Buy credits, use them on any repo. PR charges are based on the size of the diff.
Small
$0.10
< 100 lines
Medium
$0.25
100-500 lines
Large
$0.50
500-2k lines
Massive
$0.75
> 2k lines
No surprise charges. Credits never expire. Use across any number of repositories.
Every PR. Every repo. Every risk — caught before production.
No monthly fees. No credit card required to start.