mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
301 lines
7.1 KiB
JavaScript
301 lines
7.1 KiB
JavaScript
const express = require('express');
|
|
const TestObj = require('@example/test');
|
|
|
|
function basicTaint() {
|
|
const app = express();
|
|
app.use((req, res, next) => {
|
|
req.tainted = source();
|
|
req.safe = 'safe';
|
|
next();
|
|
});
|
|
app.get('/', (req, res) => {
|
|
sink(req.tainted); // NOT OK
|
|
sink(req.safe); // OK
|
|
});
|
|
}
|
|
|
|
function basicApiGraph() {
|
|
const app = express();
|
|
app.use((req, res, next) => {
|
|
req.obj = new TestObj();
|
|
next();
|
|
});
|
|
app.get('/', (req, res) => {
|
|
sink(req.obj.getSource()); // NOT OK
|
|
req.obj.getSink(source()); // NOT OK
|
|
});
|
|
}
|
|
|
|
function noTaint() {
|
|
const app = express();
|
|
function middleware(req, res, next) {
|
|
req.tainted = source();
|
|
req.safe = 'safe';
|
|
next();
|
|
}
|
|
app.get('/unsafe', middleware, (req, res) => {
|
|
sink(req.tainted); // NOT OK
|
|
sink(req.safe); // OK
|
|
});
|
|
app.get('/safe', (req, res) => {
|
|
sink(req.tainted); // OK - not preceded by middleware
|
|
sink(req.safe); // OK
|
|
});
|
|
}
|
|
|
|
function looseApiGraphStep() {
|
|
const app = express();
|
|
function middleware(req, res, next) {
|
|
req.obj = new TestObj();
|
|
next();
|
|
}
|
|
app.get('/unsafe', middleware, (req, res) => {
|
|
sink(req.obj.getSource()); // NOT OK
|
|
});
|
|
app.get('/safe', (req, res) => {
|
|
sink(req.obj.getSource()); // NOT OK - we allow API graph steps within the same app
|
|
});
|
|
}
|
|
|
|
function chainMiddlewares() {
|
|
const app = express();
|
|
function step1(req, res, next) {
|
|
req.taint = source();
|
|
next();
|
|
}
|
|
function step2(req, res, next) {
|
|
req.locals.alsoTaint = req.taint;
|
|
next();
|
|
}
|
|
app.get('/', step1, step2, (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
sink(req.locals.alsoTaint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function routerEscapesIntoParameter() {
|
|
const app = express();
|
|
function setupMiddlewares(router) {
|
|
router.use((req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
});
|
|
}
|
|
app.get('/before', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
setupMiddlewares(app);
|
|
app.get('/after', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function routerReturned() {
|
|
const app = express();
|
|
function makeMiddlewares() {
|
|
let router = new express.Router();
|
|
router.use((req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
});
|
|
return router;
|
|
}
|
|
app.get('/before', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
app.use(makeMiddlewares());
|
|
app.get('/after', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function routerCaptured() {
|
|
const app = express();
|
|
function addMiddlewares() {
|
|
app.use((req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
});
|
|
}
|
|
app.get('/before', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
addMiddlewares();
|
|
app.get('/after', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function withPath() {
|
|
const app = express();
|
|
app.use('/foo', (req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
});
|
|
app.get('/foo', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
app.get('/bar', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
}
|
|
|
|
|
|
function withNestedPath() {
|
|
const app = express();
|
|
app.use('/foo/bar', (req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
});
|
|
function makeRouter() {
|
|
const router = express.Router();
|
|
router.get('/bar', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
})
|
|
router.get('/baz', (req, res) => {
|
|
sink(req.taint); // OK
|
|
})
|
|
return router;
|
|
}
|
|
app.get('/foo', makeRouter());
|
|
app.get('/bar', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
}
|
|
|
|
function withHttpMethods() {
|
|
const app = express();
|
|
app.get('/foo', (req, res, next) => {
|
|
req.taintGet = source();
|
|
next();
|
|
});
|
|
app.post('/foo', (req, res, next) => {
|
|
req.taintPost = source();
|
|
next();
|
|
});
|
|
app.all('/foo', (req, res, next) => {
|
|
req.taintAll = source();
|
|
next();
|
|
});
|
|
app.get('/foo/a', (req, res) => {
|
|
sink(req.taintGet); // NOT OK
|
|
sink(req.taintPost); // OK - not tainted for GET requests
|
|
sink(req.taintAll); // NOT OK
|
|
});
|
|
app.post('/foo/b', (req, res) => {
|
|
sink(req.taintGet); // OK - not tainted for POST requests
|
|
sink(req.taintPost); // NOT OK
|
|
sink(req.taintAll); // NOT OK
|
|
});
|
|
app.all('/foo/c', (req, res) => {
|
|
sink(req.taintGet); // NOT OK
|
|
sink(req.taintPost); // NOT OK
|
|
sink(req.taintAll); // NOT OK
|
|
});
|
|
}
|
|
|
|
function withChaining() {
|
|
const app = express();
|
|
app.use('/', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
function middleware() {
|
|
return express.Router()
|
|
.use((req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
})
|
|
.use(blah());
|
|
}
|
|
app.use(middleware());
|
|
app.use('/', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function withClass() {
|
|
class App {
|
|
constructor(router) {
|
|
this.router = router;
|
|
this.earlyRoutes();
|
|
this.addMiddleware();
|
|
this.lateRoutes();
|
|
}
|
|
earlyRoutes() {
|
|
this.router.get('/', (req, res) => {
|
|
sink(req.taint); // OK
|
|
})
|
|
}
|
|
addMiddleware() {
|
|
this.router.use((req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
})
|
|
}
|
|
lateRoutes() {
|
|
this.router.get('/', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
})
|
|
}
|
|
}
|
|
let app = new App(express());
|
|
}
|
|
|
|
function withArray() {
|
|
const app = express();
|
|
app.get('/before', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
app.use([
|
|
(req, res, next) => {
|
|
sink(req.taint); // OK
|
|
next();
|
|
},
|
|
(req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
},
|
|
(req, res, next) => {
|
|
sink(req.taint); // NOT OK
|
|
next();
|
|
}
|
|
]);
|
|
app.get('/after', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function withForLoop() {
|
|
const app = express();
|
|
let middlewares = [
|
|
(req, res, next) => {
|
|
sink(req.taint); // OK
|
|
next();
|
|
},
|
|
(req, res, next) => {
|
|
req.taint = source();
|
|
next();
|
|
},
|
|
(req, res, next) => {
|
|
sink(req.taint); // NOT OK
|
|
next();
|
|
}
|
|
];
|
|
app.get('/before', (req, res) => {
|
|
sink(req.taint); // OK
|
|
});
|
|
for (let route of middlewares) {
|
|
app.use(route);
|
|
}
|
|
app.get('/after', (req, res) => {
|
|
sink(req.taint); // NOT OK
|
|
});
|
|
}
|
|
|
|
function routeHandlersInProps() {
|
|
let routes = require('./routes');
|
|
const app = express();
|
|
app.use(routes.first);
|
|
app.get('/', routes.second);
|
|
}
|