new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

OWASP Cheat Sheets · all subjects

authorization & access control

79 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

ACL implementation with acl module

Use the `acl` module in Node.js to implement Access Control Lists (ACL) for authorization. With this module, create roles and assign users to those roles following the principle of least privilege. Each user role should have access only to the resources required for their function.

Object property descriptors for security

Object properties have three hidden attributes: `writable` (controls if value can change), `enumerable` (controls if property appears in for loops), and `configurable` (controls if property can be deleted). All default to true. Set these explicitly using `Object.defineProperty()` to restrict property modification. Use `Object.preventExtensions()` to prevent adding new properties to an object.

Mitigating IDOR: use indirect references

Implement user/session specific indirect references using a tool such as OWASP ESAPI. This approach masks or randomizes object IDs to prevent attackers from guessing and manipulating identifiers.

Authorization definition and distinction from authentication

Authorization is the process of verifying that a requested action or service is approved for a specific entity, as defined by NIST. Authorization is distinct from authentication, which is the process of verifying an entity's identity. An authenticated user is often not authorized to access every resource and perform every action that is technically possible through a system.

Least Privileges principle application

Least Privileges refers to assigning users only the minimum privileges necessary to complete their job. This principle must be applied both horizontally (different resources for users at same organizational level) and vertically (hierarchical privilege differences). For example, an accountant should not access a customer database and a sales representative should not access payroll data.

Least Privileges implementation during design phase

During the design phase, define trust boundaries and enumerate the types of users accessing the system, the resources exposed, and the operations (read, write, update, etc.) that might be performed on those resources. For every combination of user type and resource, determine what operations the user based on role and/or other attributes must be able to perform on that resource. For ABAC systems, ensure all categories of attributes are considered, such as network location and time of day.

Deny by default access control strategy

An application must always make a decision, whether implicitly or explicitly, to either deny or permit requested access. Applications should be configured to deny access by default. Adopt a deny-by-default mentality both during initial development and whenever new functionality or resources are exposed by the app. One should be able to explicitly justify why a specific permission was granted to a particular user or group rather than assuming access to be the default position.

Deny by default and framework defaults

Although some frameworks or libraries may adopt a deny-by-default strategy, explicit configuration should be preferred over relying on framework or library defaults. The logic and defaults of third-party code may evolve over time, without the developer's full knowledge or understanding of the change's implications for a particular project.

Validate permissions on every request without exception

Permission should be validated correctly on every request, regardless of whether the request was initiated by an AJAX script, server-side, or any other source. An attacker only needs to find one way in. Even if just a single access control check is missed, the confidentiality and/or integrity of a resource can be jeopardized. Validating permissions correctly on just the majority of requests is insufficient.

Global application-wide permission validation technology

The technology used to perform permission checks should allow for global, application-wide configuration rather than needing to be applied individually to every method or class. Technologies that can help include Java/Jakarta EE Filters (including implementations in Spring Security), Django Framework Middleware, .NET Core Filters, and Laravel PHP Framework Middleware.

Thoroughly review authorization logic of third-party components

Developers must thoroughly understand any technology used for authorization logic. Analyze the technology's capabilities with the understanding that the authorization logic provided by the component may be insufficient for the application's specific security requirements. Relying on prebuilt logic may be convenient, but custom authorization logic may be necessary to meet an app's security requirements.

Mitigating IDOR: access control checks on specific objects

Perform access control checks on every request for the specific object or functionality being accessed. Just because a user has access to an object of a particular type does not mean they should have access to every object of that particular type.

Authorization requirements should drive component selection

Do not let the capabilities of any library, platform, or framework guide authorization requirements. Rather, authorization requirements should be decided first and then the third-party components may be analyzed in light of these requirements. Do not rely on default configurations and test configuration thoroughly.

Defend against vulnerable third-party components

Assume any third-party component incorporated into an application could be or become subject to an authorization vulnerability. Create, maintain, and follow processes for detecting and responding to vulnerable components. Incorporate tools such as Dependency Check into the SDLC. Implement defense in depth and do not depend on any single framework, library, technology, or control to be the sole thing enforcing proper access control.

RBAC definition and characteristics

Role-Based Access Control (RBAC) is a model of access control in which access is granted or denied based upon the roles assigned to a user. Permissions are not directly assigned to an entity; rather, permissions are associated with a role and the entity inherits the permissions of any roles assigned to it. Generally, the relationship between roles and users can be many-to-many, and roles may be hierarchical in nature.

ABAC definition and flexibility

Attribute-Based Access Control (ABAC) is an access control model where subject requests to perform operations on objects are granted or denied based on assigned attributes of the subject, assigned attributes of the object, environment conditions, and a set of policies specified in terms of those attributes and conditions (NIST SP 800-162). Attributes are characteristics that can be represented as name-value pairs and assigned to a subject, object, or the environment. Examples include job role, time of day, project name, MAC address, and creation date.

ReBAC definition and use cases

Relationship-Based Access Control (ReBAC) is an access control model that grants access based on the relationships between resources. For instance, allowing only the user who created a post to edit it. ReBAC is especially necessary in social network applications like Twitter or Facebook, where users want to limit access to their data to people they choose.

Prefer ABAC and ReBAC over RBAC

ABAC and ReBAC should typically be preferred for application development over RBAC. Their advantages include support for fine-grained complex Boolean logic, robustness in large projects with numerous roles, speed (avoiding role explosion), support for multi-tenancy and cross-organizational requests, and ease of management as systems scale.

ABAC supports fine-grained and complex Boolean logic

In RBAC, access decisions are made on the presence or absence of roles. ABAC greatly expands both the number and type of characteristics that can be considered. A role can certainly be one attribute assigned to a subject, but it need not be considered in isolation. ABAC can incorporate environmental and dynamic attributes such as time of day, type of device used, and geographic location. ABAC can deny access to sensitive resources outside business hours or if a user has not recently completed mandatory training, meeting requirements that RBAC would struggle to fulfill.

RBAC robustness issues with role hierarchies

In large projects or when numerous roles are present, it is easy to miss or improperly perform role checks in RBAC implementations. This is especially true in RBAC implementations where a role hierarchy is not present and multiple role checks must be chained (e.g., `if(user.hasAnyRole("SUPERUSER", "ADMIN", "ACCT_MANAGER"))`), resulting in both too much and too little access.

RBAC role explosion and performance impact

In RBAC, role explosion can occur when a system defines too many roles. If users send their credential and roles through HTTP headers which have size limits, there may not be enough space to include all of the user's roles. A workaround is to only send the user ID and have the application retrieve the user's roles, but this increases the latency of every request.

RBAC poorly suited for multi-tenancy and cross-organizational requests

RBAC is poorly suited for use cases where distinct organizations or customers will need access to the same set of protected resources. Meeting such requirements with RBAC would require highly cumbersome methods such as configuring rule sets for each customer in a multi-tenant environment or requiring pre-provisioning of identities for cross-organizational requests. ABAC allows access control decisions to be executed and administered in the same or separate infrastructures while maintaining appropriate levels of security.

ReBAC supports algebraic operators for policies

Some ReBAC systems support algebraic operators like AND and NOT to express policies such as if this user has relationship X but not relationship Y with the object, then grant access.

CWE-639 Authorization Bypass Through User-Controlled Key

Applications often expose internal object identifiers such as account numbers or Primary Keys in databases as query parameters, path variables, or form fields. When applications fail to properly validate access control on these identifiers, users may be able to view resources associated with other accounts or objects by manipulating the ID. This weakness (CWE-639) can result in authorization bypasses, horizontal privilege escalation, and less commonly, vertical privilege escalation. It represents a form of Insecure Direct Object Reference (IDOR).

Mitigating IDOR: avoid exposing identifiers

Avoid exposing identifiers to the user when possible. For example, it should be possible to retrieve some objects such as account details based solely on the currently authenticated user's identity and attributes (e.g., through information contained in a securely implemented JSON Web Token or server-side session).

Security through obscurity is insufficient for object identifiers

While various techniques can be used to mask or randomize object IDs and make them hard to guess, such an approach is generally not sufficient by itself. The focus should be on controlling access to the underlying objects and identifiers rather than relying on security through obscurity.

Static resources must be protected with access control policies

Ensure that static resources are incorporated into access control policies. The type of protection required for static resources will necessarily be highly contextual. It may be perfectly acceptable for some static resources to be publicly accessible, while others should only be accessible when a highly restrictive set of user and environmental attributes are present. Understanding the type of data exposed in specific resources is critical.

Data classification scheme for static resources

Consider whether a formal Data Classification scheme should be established and incorporated into the application's access control logic for static resources. This ensures appropriate protection levels based on data sensitivity.

Cloud static resource security configuration

Ensure any cloud-based services used to store static resources are secured using the configuration options and tools provided by the vendor. Review the cloud provider's documentation for specific implementation details, such as guidance from AWS, Google Cloud, or Azure.

Protect static resources with same access control logic as other resources

When possible, protect static resources using the same access control logic and mechanisms that are used to secure other application resources and functionality. This ensures consistent and comprehensive protection.

Authorization checks must be server-side

Developers must never rely on client-side access control checks. While such checks may be permissible for improving the user experience, they should never be the decisive factor in granting or denying access to a resource. Client-side logic is often easy to bypass. Access control checks must be performed server-side, at the gateway, or using serverless functions.

OWASP ASVS authorization verification requirements

Authorization checks must be performed in the right location according to OWASP ASVS 4.0.3, V1.4.1 and V4.1.1, which requires server-side, gateway, or serverless function-based implementation.

Handle failed authorization checks safely

Failed access control checks are a normal occurrence in a secured application; consequently, developers must plan for such failures and handle them securely. Improper handling can lead to the application being left in an unpredictable state (CWE-280: Improper Handling of Insufficient Permissions or Privileges).

Exception handling for access control failures

Ensure all exception and failed access control checks are handled no matter how unlikely they seem. This does not mean that an application should always try to correct for a failed check; oftentimes a simple message or HTTP status code is all that is required.

Centralize failed authorization check handling

Centralize the logic for handling failed access control checks. Verify the handling of exception and authorization failures to ensure that such failures do not put the software into an unstable state that could lead to authorization bypass.

Do not expose sensitive information in error messages

Ensure sensitive information such as system logs or debugging output is not exposed in error messages. Misconfigured error messages can increase the attack surface of an application (CWE-209: Generation of Error Message Containing Sensitive Information).

Unit and integration testing for authorization logic

Unit and integration testing are essential for verifying that authorization logic performs as expected. Flaws in access control logic can be subtle, particularly when requirements are complex. Automated unit and integration testing can help reduce the number of security flaws that make it into production. These tests are good at catching low-hanging fruit of security issues but not more sophisticated attack vectors.

Authorization testing concepts to include

Unit and integration testing should incorporate concepts such as: is access being denied by default, does the application terminate safely when an access control check fails even under abnormal conditions, are ABAC policies being properly enforced, and is access control being validated on every request.

Automated testing complement to manual security testing

While simple unit and integration tests can never replace manual testing performed by a skilled hacker, they are an important tool for detecting and correcting security issues quickly and with far less resources than manual testing. Manual penetration testing is recommended per OWASP WSTG 4.5.

Broken Access Control as OWASP Top 10 2021 concern

Broken Access Control was ranked as the most concerning web security vulnerability in OWASP's 2021 Top 10 and asserted to have a High likelihood of exploit by MITRE's CWE program (CWE-285).

Access Control in OWASP Top 10 exploitation statistics

According to Veracode's State of Software Vol. 10, Access Control was among the more common of OWASP's Top 10 risks to be involved in exploits and security incidents despite being among the least prevalent of those examined.

Horizontal privilege escalation as common authorization weakness

Horizontal privilege elevation, which is the ability to access another user's resources, is an especially common weakness that an authenticated user may be able to take advantage of. Both entirely unauthenticated outsiders and authenticated but not necessarily authorized users can exploit authorization weaknesses.

Impact of authorization flaws on resources

Attackers exploiting authorization flaws may be able to read, create, modify, or delete resources that were meant to be protected, thus jeopardizing their confidentiality, integrity, and/or availability. The actual impact of such actions is necessarily linked to the criticality and sensitivity of the compromised resources. Business costs can range from very low to extremely high.

Authorization violations may remain undetected without proper logging

If logging related to access control is not properly set up, authorization violations may go undetected or at least remain unattributable to a particular individual or group. This underscores the importance of appropriate logging and monitoring as detective controls.

Verify tenant membership before granting access

Treat client-supplied tenant identifiers as selectors only. Verify that the authenticated principal is authorized to act in the selected tenant by checking active membership or service authorization, not just verifying the identifier format.

Never trust client-supplied tenant IDs for authorization

Do not treat tenant IDs from client headers or request parameters as authorization proof. They are selectors that require server-side verification against the authenticated principal's membership or permissions.

Propagate server-verified tenant context to downstream components

Bind tenant context to a server-verified identity and propagate it to components that need it for tenant-sensitive decisions or observability. Do not let downstream components replace it with unverified input.

Database isolation strategies: separate databases vs schemas vs row-level

Choose isolation strategy based on security requirements and operational complexity: Separate Databases provide strong isolation when credentials, network access, and backups are isolated but have higher operational cost; Separate Schemas require disciplined grants, role separation, and search_path handling; Shared Tables (Row-Level) require enforceable tenant ownership, policy coverage, constrained request roles, and testing; Hybrid varies by workload.

PostgreSQL FORCE ROW LEVEL SECURITY does not constrain superusers or BYPASSRLS roles

The PostgreSQL FORCE ROW LEVEL SECURITY clause applies row-level security policies to table owners but does not constrain superusers or roles with the BYPASSRLS attribute. These roles always bypass row security. For tenant-scoped request paths, use a least-privileged role that is neither a superuser nor has BYPASSRLS.

Use transaction-local tenant context for PostgreSQL RLS

For shared-table PostgreSQL RLS, use SET LOCAL or set_config(..., true) to make tenant context transaction-local. Session-scoped settings can be inherited by the next request when connection pools reuse database sessions. Re-establish tenant context for every transaction and fail closed if the context is missing or invalid.

PostgreSQL RLS policy example with current_setting

Create RLS policies that reference app-scoped tenant settings: CREATE POLICY tenant_isolation_policy ON orders FOR ALL USING (tenant_id = current_setting('app.current_tenant')::uuid). The omission of missing_ok => true is deliberate fail-closed design—PostgreSQL raises an error if the setting does not exist.

Test database isolation through same role and connection path as application

Test tenant isolation using the same role, connection path, and pooling mode used by the application. A privileged test connection can make a correct policy appear broken, and tests that never exercise the deployed request role can miss bypasses.

Verify RLS coverage by checking pg_class.relrowsecurity and pg_policies

Discover RLS coverage by comparing the expected tenant-scoped table inventory with PostgreSQL's pg_class.relrowsecurity, relforcerowsecurity, and the pg_policies view. Fail when a new table has no classification, RLS is disabled, or the expected policy is absent.

Check deployed request role for superuser and BYPASSRLS attributes

In the deployed environment, fail a configuration test if the request-path role has rolsuper or rolbypassrls set. PostgreSQL exposes these in the pg_roles system view.

Test connection reuse across tenant requests

Run requests for two different tenants over reused database connections and prove the second request cannot observe the first request's tenant context or data. This tests that session-scoped state does not leak between pooled connections.

IDOR prevention: verify tenant ownership for resource access

For each tenant-scoped resource, verify that the authenticated principal can act in the resource's tenant. Include tenant scope in the lookup or authorization policy when ownership is tenant-specific. Treat opaque or random identifiers as defense against enumeration, not as a substitute for authorization.

Use composite keys for tenant-scoped resource lookups

A composite key (tenant_id + resource_id) is one option for enforcing tenant ownership in resource lookups, though not a universal requirement. The key design depends on the application architecture.

Enforce authorization at a boundary traversed by every tenant-owned access path

Enforce authorization at a boundary that every tenant-owned access path must traverse. Add data-layer checks as defense in depth where the architecture supports it.

Validate server-verified tenant context on every tenant-scoped API request

Validate server-verified tenant context on every tenant-scoped API request. Public or global endpoints need no artificial tenant context.

Do not allow ordinary tenant request path to use unscoped queries

Do not allow an ordinary tenant-owned request path to perform an unscoped query. Make any cross-tenant administrative path explicit, separately authorized, and auditable.

Give your agent this brain