5. Authentication, Authorization and Backend SecurityIntroduction and ContextBackend applications protect valuable assets: user identities, personal information, payment records, business rules, intellectual property, and operational systems. Authentication establishes who is making a request; authorization determines what that identity is permitted to do; backend security protects the entire processing path from malicious input, compromised credentials, unsafe integrations, and operational failure. These concerns are closely related but must not be treated as interchangeable. A correctly authenticated user may still be unauthorized to access another customer’s invoice, while a well-designed authorization policy may be undermined by an injection vulnerability. Modern applications expose APIs to browsers, mobile applications, partner systems, internal services, and automated agents. Node.js, Django, and Spring Boot provide useful security mechanisms, but frameworks do not automatically produce a secure system. Security depends on architecture, configuration, coding practices, deployment controls, monitoring, and governance. This chapter therefore treats security as a system property rather than a collection of login screens or libraries. The chapter develops a practical security model covering sessions and cookies, JSON Web Tokens (JWT), OAuth 2.0, OpenID Connect (OIDC), role-based and attribute-based access control, common OWASP API risks, defensive coding, threat modelling, and zero-trust principles. The objective is not merely to name mechanisms, but to select and combine them appropriately. Learning ObjectivesAfter studying this chapter, a learner should be able to: 1. Distinguish authentication, authorization, accounting, confidentiality, integrity, and availability. 2. Select between server-side sessions, cookies, JWT, OAuth 2.0, and OIDC for different architectures. 3. Design RBAC and ABAC policies and enforce object-level authorization. 4. Apply defences against injection, CSRF, CORS misconfiguration, SSRF, insecure deserialization, and API abuse. 5. Protect passwords, secrets, tokens, keys, and sensitive data throughout their lifecycle. 6. Use threat modelling and zero-trust principles to analyse backend designs. 7. Compare security practices in Node.js, Django, and Spring Boot applications. 8. Evaluate security incidents through technical, organizational, ethical, and regulatory perspectives. Identity, Access and Trust BoundariesAuthentication is the process of verifying a claimed identity. Factors may include knowledge, such as a password; possession, such as a hardware token; and inherence, such as a biometric characteristic. Multi-factor authentication combines independent factors. A second password does not normally constitute a second factor because both are knowledge factors. Authorization is the decision to allow or deny an authenticated principal—usually a user, service, or device—from performing an action on a resource. The decision should consider the requested operation, resource ownership, tenant, environment, and relevant business conditions. Accounting, often called auditing, records security-relevant events so that actions can be investigated and responsibilities established. The security objectives of confidentiality, integrity, and availability are commonly called the CIA triad. Confidentiality prevents unauthorized disclosure; integrity prevents unauthorized alteration; availability ensures legitimate access when needed. Authentication and authorization primarily support confidentiality and integrity, but poor availability controls, such as unrestricted expensive queries, can create denial-of-service conditions. A trust boundary is a point at which data or control moves between different levels of trust. Examples include a browser-to-API boundary, an API-to-database boundary, a service-to-service boundary, and an application-to-third-party boundary. Every boundary requires validation, authentication where appropriate, authorization, secure transport, and failure handling. Treating an internal network as automatically trustworthy is a frequent architectural error. Sessions, Cookies and TokensA traditional session architecture stores session state on the server. After successful authentication, the server creates a random, high-entropy session identifier and sends it to the browser in a cookie. Subsequent requests carry the identifier, allowing the server to retrieve the user’s session. The identifier should be meaningless, unpredictable, rotated after login, expired after appropriate inactivity, and invalidated on logout or suspected compromise. Cookies require careful attributes. `Secure` restricts transmission to HTTPS, `HttpOnly` prevents JavaScript from reading the cookie, and `SameSite` limits cross-site transmission. `SameSite=Lax` is often a useful default, while `Strict` provides stronger cross-site protection but may affect usability. `SameSite=None` requires `Secure` and should be used only when cross-site behavior is genuinely required. Cookie scope should be narrow: unnecessary domain and path settings increase exposure. Session authentication is particularly suitable for server-rendered applications and browser clients because credentials remain under server control. It introduces operational concerns, including session storage, replication, invalidation, and load balancing. Distributed systems may use a shared session store such as a database or cache, but that store becomes security-critical. A JWT is a signed token containing claims such as an issuer, subject, audience, expiry time, and permissions. A signature provides integrity and authenticity when the signing key is protected; it does not automatically provide confidentiality. Encrypted JWT forms exist, but sensitive information should not be placed in ordinary readable claims. JWT validation must check the signature, accepted algorithm, issuer, audience, expiry, and relevant claims. Accepting an algorithm merely because it appears in the token is unsafe. JWTs are useful when services need to validate access tokens without a central session lookup, but they create difficult revocation and lifecycle problems. Long-lived tokens remain useful after a user loses access unless there is a revocation strategy. Short-lived access tokens, refresh-token rotation, server-side refresh-token records, key rotation, and breach detection improve the design. A token stored in a browser-accessible location can be stolen by cross-site scripting; a token in an HttpOnly cookie reduces direct script access but reintroduces CSRF considerations. The choice is architectural rather than ideological. Server-side sessions are often simpler for a single web application. Access tokens are appropriate for delegated API access and service boundaries. A system should avoid issuing JWTs simply because a framework makes them convenient. OAuth 2.0 and OpenID ConnectOAuth 2.0 is an authorization framework for delegated access. It allows a resource owner to authorize a client to obtain an access token for a resource server without giving the client the resource owner’s password. OAuth access tokens represent delegated authority; OAuth itself is not an authentication protocol. In the authorization code flow, a client directs the user to an authorization server. After consent and authentication, the authorization server returns a short-lived authorization code to a registered redirect URI. The client exchanges the code for tokens. Proof Key for Code Exchange (PKCE) adds a verifier and challenge, protecting the code exchange against interception and now serving as a strong default for public clients and many web applications. Redirect URIs must be exact and narrowly registered. State values protect request correlation and help prevent login CSRF. An access token should be audience-restricted, minimally scoped, short-lived, and sent over TLS. A refresh token should be protected more strongly than an access token and rotated when used. Client credentials flow is intended for machine-to-machine access, not end-user login. Password-based grant patterns are unsuitable for new systems because they require the client to handle user credentials. OpenID Connect extends OAuth 2.0 with an identity layer. It introduces an ID token, usually a JWT, containing identity claims and authentication context. A relying party must validate the ID token’s issuer, audience, signature, nonce, time claims, and code-flow relationship. It should use the ID token to understand the authentication event, not as a general-purpose API access token. User profile data should also be treated as untrusted input and reconciled according to the application’s account-linking policy. Authorization Models: RBAC and ABACRole-based access control (RBAC) assigns permissions to roles and roles to users. For example, a support agent may view customer tickets, while a billing administrator may issue refunds. RBAC is understandable and manageable when responsibilities are stable. However, large systems often suffer from role explosion: combinations of department, region, customer, and operation produce too many roles. Attribute-based access control (ABAC) evaluates attributes of the subject, resource, action, and environment. A policy might allow a clinician to view a patient record when the clinician is assigned to the patient, the request is made during an authorized operational context, and the purpose is treatment. ABAC expresses fine-grained rules but requires reliable attributes, policy governance, explainability, and careful performance design. Many production systems combine models. RBAC provides broad capabilities, while ownership, tenant, classification, time, device posture, or transaction value are evaluated as attributes. Authorization must be enforced on the server and at the point where the protected resource is accessed. Hiding a button in a user interface is a usability feature, not a security control. A robust authorization decision can be represented as: principal, action, resource, context, and policy. Developers should deny by default, use least privilege, fail closed when policy information is unavailable, and separate policy evaluation from business logic where practical. Object-level authorization is essential: an endpoint such as `/orders/1842` must verify that the current principal may access order 1842, not merely that the principal has a general “customer” role. Threat Modelling as a Design ActivityThreat modelling identifies what must be protected, how it can be attacked, and which controls reduce risk. A useful process begins with an asset inventory and a data-flow diagram showing actors, processes, data stores, and trust boundaries. The team then identifies threats using categories such as spoofing, tampering, repudiation, information disclosure, denial of service, and elevation of privilege. Risks are prioritized by likelihood, impact, exploitability, and affected populations. Threat modelling should produce concrete security requirements: “the API must reject tokens with an incorrect audience,” “users may access invoices only within their tenant,” or “outbound requests may reach only an allow-listed service.” It should be revisited when authentication flows, integrations, data classifications, or deployment environments change. A threat model is valuable only when it changes implementation, testing, monitoring, or operational decisions. Zero-trust architecture applies a related principle: no request is trusted merely because it originates inside a network. Each request is evaluated using identity, device or workload context, resource, action, and policy. Services authenticate one another, access is narrowly scoped, networks are segmented, and activity is continuously logged and assessed. Zero trust does not mean indiscriminate reauthentication; it means explicit, contextual verification rather than implicit network trust. Common Backend and API RisksInjection occurs when untrusted data changes the intended structure of a command or query. SQL injection is prevented primarily through parameterized queries, prepared statements, safe query builders, and least-privileged database accounts. String concatenation is unsafe even when input appears to be numeric. Similar concerns apply to NoSQL, operating-system commands, LDAP, template engines, and expression languages. Validation is useful but is not a replacement for parameterization. Cross-site request forgery (CSRF) exploits a browser’s automatic inclusion of credentials in a request sent from a malicious site. It is principally a concern for cookie-based authentication. Defences include SameSite cookies, anti-CSRF tokens tied to the session, origin or referer checks where appropriate, and avoiding state-changing operations through GET. Bearer tokens held outside automatically attached cookies change the threat model but do not eliminate all browser attacks. Cross-origin resource sharing (CORS) controls whether browser scripts from one origin may read responses from another. It is not an authentication mechanism and does not block non-browser clients. APIs should allow only required origins, methods, and headers, and should not combine credentials with a wildcard origin. Preflight behavior and caching must be tested carefully. Server-side request forgery (SSRF) occurs when an attacker influences a server to make a request to an unintended destination, such as cloud metadata services or internal administration interfaces. Defences include strict destination allow-lists, URL parsing, blocking private and link-local address ranges, controlling redirects, validating DNS resolution, restricting protocols, and applying network egress controls. Checking a hostname only once may be insufficient because DNS can change between validation and connection. Insecure deserialization arises when untrusted serialized data causes unsafe object creation, code execution, or authorization bypass. Prefer simple, explicitly defined data formats and schemas. Do not deserialize arbitrary language-native objects from untrusted sources. Signatures can establish integrity but do not make dangerous object graphs safe by themselves. Broken authentication includes weak password storage, credential stuffing, session fixation, token leakage, poor reset flows, and missing MFA for high-risk operations. Passwords should be hashed with adaptive, memory-hard algorithms such as Argon2id, with unique salts and appropriate work factors. Plaintext or reversible encryption is inappropriate for password storage. Reset tokens should be random, short-lived, single-use, and not disclosed through response differences. Sensitive data exposure can result from verbose errors, logs, backups, URLs, browser storage, or unencrypted transport. TLS should protect data in transit; encryption at rest and application-level encryption may be needed for high-value fields. Key management, rotation, access separation, and recovery procedures matter as much as the cipher. Cryptographic design should use reviewed libraries and authenticated encryption rather than custom algorithms. API risks also include unrestricted resource consumption, mass assignment, excessive data exposure, security misconfiguration, improper inventory management, and failure to authorize function or object access. Request size limits, pagination caps, timeouts, quotas, schema validation, explicit output DTOs, version inventories, and centralized authorization reduce these risks. Rate limiting is both a security and availability control. Limits may apply per account, IP, token, tenant, endpoint, or device signal. Login endpoints need particularly careful controls because overly aggressive IP limits can enable denial of service, while only per-account limits can be bypassed through account rotation. Responses should avoid revealing whether an account exists. Distributed rate limiting requires a shared, consistent store or an appropriate gateway design. Secure Implementation in Node.js, Django and Spring BootIn Node.js, applications should use maintained middleware for security headers, strict request schemas, centralized error handling, and parameterized database access. Asynchronous errors must be handled consistently, and secrets must not be embedded in source code or committed to repositories. Dependency lockfiles, audit processes, and runtime permission restrictions help reduce supply-chain and execution risk. Django supplies secure password hashing, CSRF middleware, session management, ORM parameterization, and security-oriented settings. Production deployments should configure secure cookies, HTTPS redirects, trusted hosts, allowed origins, clickjacking protection, and appropriate security headers. Django’s ORM reduces common SQL injection risks, but raw queries, unsafe template output, file uploads, and authorization logic still require explicit review. Spring Security provides filter-chain authentication, authorization rules, CSRF protection, OAuth2 client and resource-server support, and method-level security. Applications should avoid broad permit rules, distinguish authentication from authority mapping, validate JWT issuer and audience, and use secure password encoders. Actuator endpoints, management ports, serialization features, and error responses require production hardening. Across all frameworks, security logic should be centralized enough to be consistent but close enough to the resource to understand business ownership. Automated tests should include unauthorized access, cross-tenant access, expired tokens, malformed claims, CSRF attempts, injection payloads, and rate-limit behavior. Secrets, Dependencies and Operational SecuritySecrets include database passwords, signing keys, private certificates, API keys, and refresh tokens. They should be supplied through a managed secret store or protected deployment mechanism, not source code, container images, tickets, or ordinary logs. Access should be limited by workload identity, audited, and rotated. Rotation design must account for key overlap, token validation during transition, emergency revocation, and recovery from a compromised secret. Dependency security is a lifecycle activity. Teams should maintain an inventory or software bill of materials, pin or constrain versions, review transitive dependencies, monitor vulnerability advisories, and test updates. A vulnerability scanner is not a substitute for prioritization: exploitability, exposure, compensating controls, and business impact matter. Build pipelines should protect package registries, signing credentials, and artifact promotion. Security monitoring should record authentication failures, privilege changes, token anomalies, administrative actions, policy denials, and unusual outbound requests. Logs must support investigation without exposing passwords, access tokens, or unnecessary personal data. Time synchronization, retention rules, access controls, and tamper resistance are important for reliable auditing. Illustrative Case Study: Multi-Tenant Clinical Scheduling APIBackgroundA fictional healthcare software provider operates a Django-based web portal and a Node.js API used by clinics. A Spring Boot integration service exchanges appointment information with laboratories. The platform serves multiple clinics, each represented as a tenant. Situation and ProblemThe initial system used a shared JWT containing a clinic identifier and a broad `staff` role. An API endpoint accepted a patient-record identifier and returned data if the token was valid. A security review found that a staff member could alter the identifier and retrieve another clinic’s record. The review also identified permissive CORS, long-lived refresh tokens, raw SQL in a reporting feature, and outbound requests to URLs supplied by clinic administrators. AnalysisAuthentication was functioning, but authorization was not object- or tenant-aware. The JWT’s clinic claim was treated as sufficient without checking the record’s actual tenant. The reporting feature created an injection risk. Permissive CORS increased browser exposure, while refresh-token persistence made theft difficult to detect. The outbound integration created an SSRF risk. The threat model therefore identified confidentiality, integrity, and availability concerns at several trust boundaries. Approach and SolutionThe team retained OIDC for workforce login and used authorization-code flow with PKCE. Access tokens became short-lived and audience-restricted. Refresh tokens were rotated and stored as hashed records with device and session metadata. The API introduced a policy decision requiring principal, action, record, tenant, and purpose. Database queries always included tenant constraints, and service accounts received only the scopes required for their integration. The reporting feature was rewritten using parameterized queries and allow-listed sort fields. CORS was restricted to registered clinic origins, credentials were enabled only where required, and state-changing browser requests used CSRF protections. Outbound laboratory URLs were replaced by registered integration identifiers; the server resolved only allow-listed destinations, blocked private address ranges, restricted redirects, and applied timeouts. Rate limits were applied per tenant and operation, with stricter controls for authentication and report generation. Security events were logged without tokens or clinical data. Automated tests attempted cross-tenant access, malformed tokens, injection, SSRF, and replay of refresh tokens. A formal incident procedure defined revocation, notification, investigation, and recovery responsibilities. OutcomeThe revised design reduced reliance on claims as authorization decisions, made tenant boundaries explicit, limited token lifetime, and removed several dangerous input-to-command paths. It did not claim that risk was eliminated; instead, the organization gained layered prevention, detection, and response controls. Learning PointsThe case demonstrates that valid authentication does not imply valid resource access. Claims should inform policy rather than replace resource checks. Integrations are trust boundaries, and security controls must cover data, identity, network destinations, dependencies, and operations together. Challenges, Ethics and GovernanceSecurity controls often create tensions with usability, performance, accessibility, privacy, and operational cost. MFA recovery must not become an account-takeover channel. Rate limits must consider shared networks and users with assistive technologies. Logging must support accountability without creating a second database of sensitive personal information. Organizations should apply data minimization, purpose limitation, retention controls, and access governance to authentication and audit data. Security testing must be authorized and carefully scoped. Vulnerability disclosure should provide a responsible channel for researchers, and incidents should be assessed for legal, contractual, and regulatory notification duties. Developers and managers share responsibility: security cannot be delegated entirely to a framework or a security team. Emerging Directions and Best PracticesPasskeys based on public-key credentials are increasingly important because they reduce phishing and password-reuse risk. Workload identity, short-lived service credentials, policy-as-code, software supply-chain attestations, and continuous authorization are extending security beyond perimeter controls. Automated code analysis and AI-assisted security review can identify patterns, but generated code and automated findings require human verification. AI systems themselves introduce risks involving prompt injection, sensitive-data disclosure, tool authorization, and uncontrolled outbound actions. A mature backend security programme should adopt the following habits: - Model assets, trust boundaries, threats, and abuse cases before implementation.
- Prefer established protocols and maintained libraries over custom cryptography or authentication schemes.
- Use short-lived credentials, least privilege, explicit audiences, secure defaults, and deny-by-default authorization.
- Validate input by schema and context, parameterize commands, and encode output appropriately.
- Enforce object and tenant authorization on the server for every sensitive operation.
- Protect cookies, tokens, secrets, keys, logs, dependencies, and administrative interfaces throughout their lifecycle.
- Test negative cases, monitor meaningful events, rehearse response, and review controls when architecture changes.
Chapter SummaryAuthentication verifies identity, whereas authorization evaluates permitted actions on particular resources. Sessions, cookies, JWT, OAuth 2.0, and OIDC solve different problems and must be selected according to client, trust, revocation, and delegation requirements. RBAC is manageable for stable responsibilities; ABAC supports contextual and fine-grained decisions, and hybrid models are common. Secure backend design requires threat modelling, explicit trust boundaries, zero-trust assumptions, parameterized queries, safe deserialization, CSRF and CORS controls, SSRF defences, rate limiting, secure password hashing, protected secrets, encryption, dependency governance, and useful monitoring. Frameworks such as Node.js, Django, and Spring Boot provide important capabilities but cannot replace architectural reasoning. The strongest designs combine prevention, detection, response, and accountable governance. Key TermsAuthentication: Verification of a claimed identity. Authorization: A decision about whether a principal may perform an action on a resource. Accounting: Recording security-relevant activity for audit and investigation. Session: Server-managed state associated with a client through an identifier. Cookie: A browser-managed value sent according to scope and security attributes. JWT: A signed, structured token carrying claims. OAuth 2.0: A framework for delegated authorization and access-token issuance. OpenID Connect: An identity layer built on OAuth 2.0. PKCE: A proof mechanism that protects authorization-code exchanges. RBAC: Access control based on roles assigned to principals. ABAC: Access control based on subject, resource, action, and environmental attributes. CSRF: Abuse of automatically submitted browser credentials through a cross-site request. CORS: Browser policy mechanism controlling permitted cross-origin reads. SSRF: Inducing a server to make an unintended outbound request. Injection: Manipulation of an interpreter’s command or query structure through untrusted input. Zero trust: Security architecture that does not grant implicit trust based on network location. Least privilege: Granting only the access required for an approved purpose. Threat modelling: Systematic identification and prioritization of security threats and controls. Refresh token: A credential used to obtain a new access token. Rate limiting: Restricting request frequency or resource consumption according to a defined policy. Review QuestionsShort Answer Questions1. Distinguish authentication from authorization using an API example. 2. Explain the security purpose of the Secure and HttpOnly cookie attributes. 3. Why is OAuth 2.0 not, by itself, an authentication protocol? 4. What problem does PKCE address? 5. Define SSRF and state one effective defence. Long Answer Questions1. Compare server-side sessions and JWT-based authentication, including revocation, storage, scalability, and browser security considerations. 2. Explain how RBAC and ABAC differ and describe a hybrid policy for a multi-tenant application. 3. Describe a secure OAuth 2.0 and OIDC authorization-code implementation. 4. Discuss how injection, CSRF, CORS, SSRF, and insecure deserialization arise and how they should be mitigated. 5. Explain how threat modelling and zero-trust principles influence backend architecture and operations. Analytical / Application Questions1. An API accepts a valid JWT containing `role=customer` and returns any invoice whose identifier appears in the URL. Identify the authorization weakness and propose a corrected decision process. 2. A server fetches a URL supplied by an administrator to retrieve an image. Analyse the SSRF risks and design layered controls. 3. A company wants to store long-lived JWTs in browser local storage for convenience. Evaluate the design and recommend a safer credential and refresh strategy. 22. Multiple Choice Questions with AnswersQuestion 1Which statement best distinguishes authentication from authorization? A. Authentication assigns roles, while authorization encrypts passwords. B. Authentication verifies identity, while authorization decides permitted actions on resources. C. Authentication records events, while authorization provides network availability. D. Authentication prevents injection, while authorization prevents all malware. Correct Answer: B. Authentication verifies identity, while authorization decides permitted actions on resources. Question 2A JWT signature primarily provides which property? A. Confidentiality of every claim B. Guaranteed revocation after logout C. Integrity and authenticity when the key is trusted and validation is correct D. Protection against all cross-site scripting Correct Answer: C. Integrity and authenticity when the key is trusted and validation is correct Question 3Why is PKCE used in the OAuth 2.0 authorization-code flow? A. To encrypt database passwords B. To protect the authorization code from interception during exchange C. To replace the need for redirect URI validation D. To convert OAuth into a session protocol Correct Answer: B. To protect the authorization code from interception during exchange Question 4An API checks that a user has the role customer but does not check whether invoice 1842 belongs to that user’s tenant. Which risk is most directly present? A. Broken object-level authorization B. Insecure deserialization C. DNS cache poisoning only D. Weak password hashing Correct Answer: A. Broken object-level authorization Question 5Which combination is most appropriate for storing passwords? A. Plaintext with database access restrictions B. Reversible encryption with a shared application key C. A fast unsalted hash calculated once D. An adaptive password-hashing algorithm with unique salts Correct Answer: D. An adaptive password-hashing algorithm with unique salts Question 6Which statement about CORS is correct? A. CORS authenticates every API client. B. CORS prevents non-browser clients from sending requests. C. CORS controls browser-origin access to responses and should use narrowly permitted origins. D. CORS makes CSRF impossible in every cookie-based application. Correct Answer: C. CORS controls browser-origin access to responses and should use narrowly permitted origins. Question 7A backend downloads a user-supplied URL and can reach cloud metadata addresses. Which defence is most appropriate? A. Allow every HTTP redirect after checking only the initial hostname. B. Use destination allow-lists, block private and link-local ranges, and restrict egress. C. Require the user to enter the URL twice. D. Put the URL in a JWT claim. Correct Answer: B. Use destination allow-lists, block private and link-local ranges, and restrict egress. Question 8What is a principal advantage of server-side sessions over long-lived JWTs? A. They cannot be stolen. B. They provide simpler centralized invalidation and server-controlled state. C. They never require secure cookies. D. They automatically authorize every resource correctly. Correct Answer: B. They provide simpler centralized invalidation and server-controlled state. Question 9Which practice best reflects zero-trust architecture? A. Trust all requests from the internal network. B. Authenticate only users, never services. C. Evaluate identity, resource, action, and context rather than relying on network location. D. Remove authorization after a user passes MFA once. Correct Answer: C. Evaluate identity, resource, action, and context rather than relying on network location. Question 10A reporting endpoint builds SQL by concatenating a client-provided sort expression. What is the strongest immediate design? A. Use parameterized values and allow-list permitted sort fields. B. Increase the JWT lifetime. C. Permit only requests from browsers. D. Encode the SQL string with Base64. Correct Answer: A. Use parameterized values and allow-list permitted sort fields.
|