Broken Access Control in Strapi with Mongodb
Broken Access Control in Strapi with Mongodb — how this specific combination creates or exposes the vulnerability
Broken Access Control in Strapi when using Mongodb often arises because permissions and policies are enforced at the Strapi layer while data filtering and projection are handled by Mongodb. If role-based rules are implemented in Strapi services or controllers but the underlying Mongodb query does not repeat the same restrictions, an authenticated user can manipulate parameters to access or modify records they should not see.
For example, consider a Strapi content type document with fields teamId, sensitivity, and archived. A Strapi policy might check that a user belongs to an allowed team, but if the service constructs a Mongodb query like { teamId: userIdTeam } only in some paths and omits it in others, an attacker can leverage IDOR via predictable ObjectIds or query parameters to traverse across teams. Similarly, field-level permissions such as hiding sensitive columns can be bypassed if Mongodb projections are inconsistent or missing, inadvertently returning sensitive fields like ssn or apiKey to lower-privilege roles.
Another common pattern is the use of populated relations where Strapi resolves references without re-applying access constraints at the Mongodb level. If a report references a client and the policy ensures users can only see reports for their client, but the Mongodb lookup does not enforce the same client filter, unauthorized records can be returned. In addition, complex aggregation pipelines in Mongodb may expose internal IDs or reshape data in ways that leak information when combined with Strapi’s default output serialization.
These issues map directly to the OWASP API Top 10 category Broken Access Control and can violate compliance frameworks such as PCI-DSS and SOC2. Attack patterns include tampering with offset and limit, exploiting missing role checks in custom controllers, and leveraging verbose error messages to infer record existence. Because Strapi’s admin UI and REST/GraphQL endpoints rely on the same service logic, an insecure implementation in Mongodb queries creates a uniform risk across interfaces.
Mongodb-Specific Remediation in Strapi — concrete code fixes
To secure Strapi with Mongodb, enforce access rules consistently in both Strapi policies/services and the generated Mongodb queries. Always filter by tenant or ownership at the database level, use strict projections, and validate input before constructing pipeline stages.
Example: secure service query ensuring team isolation and field masking
// services/document.js
module.exports = {
async findDocumentsByTeam(userId, teamId) {
// Ensure the query enforces team ownership in Mongodb
const documents = await strapi.db.query('api::document.document').collection
.find({ teamId: teamId }, { projection: { title: 1, content: 1, teamId: 1 } })
.toArray();
// Optionally redact sensitive fields in application layer after retrieval
return documents.map(({ ssn, apiKey, ...safe }) => safe);
}
};
Example: policy-based population with Mongodb match condition
// policies/team-access.js
module.exports = async (ctx, next) => {
const userTeamId = ctx.state.user.teamId;
const entryId = ctx.params.id;
const entry = await strapi.db.query('api::report.report').collection
.findOne({ _id: entryId, teamId: userTeamId });
if (!entry) {
return ctx.unauthorized('Report not found or access denied');
}
// Proceed only if the record belongs to the user's team
await next();
};
Example: aggregation pipeline with strict $match and $project
// controllers/report.js
async getTeamReports(ctx) {
const teamId = ctx.query.teamId;
const pipeline = [
{ $match: { teamId: teamId } },
{ $project: { title: 1, createdAt: 1, teamId: 1 } } // exclude sensitive fields
];
const results = await strapi.db.query('api::report.report').collection.aggregate(pipeline).toArray();
ctx.body = results;
}
When integrating with the middleBook Web Dashboard or CLI (middlebrick scan <url>), you can validate that your endpoints do not leak data across roles. The Pro plan’s continuous monitoring and GitHub Action integration can alert you if a new endpoint lacks team filters or returns excessive fields, helping you maintain consistent Mongodb-level checks as your API evolves.