{"record":{"id":"06ac96208cf4c638","repo":"OtterMind/Chat2DB","slug":"largecellvalue-tokenforbidden","errorCode":"largeCellValue.tokenForbidden","errorMessage":"largeCellValue.tokenForbidden","messagePattern":"largeCellValue\\.tokenForbidden","errorType":"validation","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbLargeValueTokenServiceImpl.java","lineNumber":154,"sourceCode":"                .primaryKey(primaryKey)\n                .userId(userId)\n                .organizationId(organizationId)\n                .expiresAt(Instant.now().plus(DEFAULT_TTL))\n                .valueType(cell.getValueType())\n                .sqlType(cell.getSqlType())\n                .columnType(cell.getColumnType())\n                .sizeBytes(cell.getSizeBytes())\n                .sizeChars(cell.getSizeChars())\n                .build();\n    }\n\n    private void validateOwner(LargeValueToken token) {\n        Context context = ContextUtils.queryContext();\n        Long organizationId = context == null ? null : context.getOrganizationId();\n        LoginUser loginUser = context == null ? null : context.getLoginUser();\n        Long userId = loginUser == null ? null : loginUser.getId();\n        if (!Objects.equals(token.getUserId(), userId) || !Objects.equals(token.getOrganizationId(), organizationId)) {\n            throw new BusinessException(\"largeCellValue.tokenForbidden\");\n        }\n    }\n\n    private Object getLocatorValue(ResultCell cell) {\n        return cell.getRawValue() == null ? cell.getValue() : cell.getRawValue();\n    }\n}\n","sourceCodeStart":136,"sourceCodeEnd":162,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbLargeValueTokenServiceImpl.java#L136-L162","documentation":"Thrown by DbLargeValueTokenServiceImpl.validateOwner when the token's userId or organizationId does not match the current Context (context.getLoginUser().getId() / context.getOrganizationId()). Tokens are scoped to the user+org that triggered the result render, so a mismatch is treated as unauthorized access. Resolves to 'You do not have permission to access this large value'. This is an authorization boundary.","triggerScenarios":"One user attempting to read a large-cell token issued to another user; an organization mismatch (multi-tenant); a token id leaked/replayed in a different session; context not set so both ids resolve to null but the token was issued under a real user.","commonSituations":"Shared/copy-pasted URLs containing a largeValueId across users; a session that lost its login context (both ids null) trying to read a user-bound token; cross-tenant token reuse.","solutions":["Only request large values for cells rendered in the current user's own session.","Ensure ContextUtils.queryContext() carries a valid LoginUser before calling requireValid.","Do not share largeValueId values between users; they are per-user opaque references."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"Context ctx = ContextUtils.queryContext();\nLoginUser u = ctx == null ? null : ctx.getLoginUser();\nif (u == null || u.getId() == null) {\n    // require login before large-value access\n}","typeGuard":"boolean tokenOwnedByCaller(LargeValueToken t) {\n    Context c = ContextUtils.queryContext();\n    LoginUser u = c == null ? null : c.getLoginUser();\n    Long uid = u == null ? null : u.getId();\n    Long oid = c == null ? null : c.getOrganizationId();\n    return Objects.equals(t.getUserId(), uid) && Objects.equals(t.getOrganizationId(), oid);\n}","tryCatchPattern":null,"preventionTips":["Never share largeValueId across users/sessions.","Ensure an authenticated context is bound before calling requireValid."],"tags":["authz","large-value","token","multi-tenant"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}