I've discovered a bug in how Zoho's API Console handles the OAuth 2.0 authorization flow when the state parameter contains pipe characters (|), and I'm hoping the Zoho team can address this in a future update.
The Issue
Zoho's OAuth 2.0 implementation for server-based client applications uses the standard authorization endpoint:
https://accounts.zoho.com/oauth/v2/auth?response_type=code
&client_id=<client_id>
&scope=<scope>
&redirect_uri=<redirect_uri>
&access_type=offline
&state=<state_value>
While Zoho's
documentation does not explicitly list the
state parameter, it is a standard part of the OAuth 2.0 specification (
RFC 6749 Section 4.1.1) and is widely used for CSRF protection and maintaining application state through the authorization flow.
However, when the state parameter contains pipe characters (|), Zoho's authorization server fails to process the request correctly, preventing users from authorizing the connection. This occurs whether the pipe characters are URL-encoded (%7C) or left unencoded.
The Problem
The pipe character is a standard delimiter in multi-part state values, particularly when passing a combination of a CSRF token and a return URL. This behavior—failing on both encoded and unencoded pipe characters—is often indicative of overly restrictive input validation or a "leaky" WAF/Proxy layer that decodes parameters before the application logic can handle them.
| State Value |
As Sent in URL |
Result |
abc123xyz |
state=abc123xyz |
✓ Works correctly |
session_12345 |
state=session_12345 |
✓ Works correctly |
user|action|timestamp |
state=user|action|timestamp (unencoded pipes) |
✗ Authorization fails |
user|action|timestamp |
state=user%7Caction%7Ctimestamp (URL-encoded pipes) |
✗ Authorization fails |
user:action:timestamp |
state=user%3Aaction%3Atimestamp |
? Not tested |
Note: Pipe characters cause failures whether URL-encoded or not. Other special characters/delimiters have not been tested and may or may not exhibit similar issues.
RFC 6749 Compliance Issue
Section 4.1.1 - Authorization Request:
"state: RECOMMENDED. An opaque value used by the client to maintain state between the request and callback."
Section 4.1.2 - Authorization Response:
"state: REQUIRED if the 'state' parameter was present in the client authorization request. The exact value received from the client."
The RFC explicitly defines the state parameter as an opaque value. This means:
- The Authorization Server should not be looking "inside" or parsing the string at all
- The state value must pass through the authorization process unchanged
- Any URL-encoded characters should be handled transparently
- The exact value received must be returned to the client in the redirect
Key Point: By definition, an "opaque" parameter means the authorization server must treat it as a data blob—accepting it, storing it, and returning it without any interpretation or transformation.
Current Behavior vs Expected Behavior
| Current Behavior |
Expected Behavior (Per RFC 6749) |
1. Client sends: state=user|action|123
(or state=user%7Caction%7C123)
2. Zoho fails to parse the state parameter
3. Authorization server returns HTTP 400 Bad Request
4. User cannot authorize the connection
|
1. Client sends: state=user|action|123
2. Zoho treats state as opaque data blob
3. User authorizes the connection
4. Redirect includes the exact value received:
state=user|action|123
(or consistently encoded as sent)
|
The Current Workaround (Suboptimal)
Important: The workarounds below only apply if you have control over the client application generating the OAuth request. If you're integrating with a third-party application that sets the state parameter (e.g., integration platforms, SaaS tools, enterprise software), you have no ability to modify the state value and therefore no workaround is available. You are completely blocked from completing the OAuth flow.
For developers who do control the client application, you must avoid pipe characters entirely:
// Instead of using pipes as delimiters:
state = csrf_token + "|" + user_id + "|" + redirect_path;
// ❌ This breaks Zoho's authorization flow
// Developers must use alternative approaches:
state = csrf_token + "_SEP_" + user_id + "_SEP_" + redirect_path;
// or
state = base64_encode(json_encode({"csrf": token, "user": id, "path": path}));
// or
state = csrf_token; // Store other data server-side keyed by CSRF token
Problems with these workarounds:
- Requires refactoring existing codebases that use pipe delimiters
- Base64 encoding increases state parameter length significantly, risking URL length limits (particularly in older browsers and some enterprise proxies which enforce ~2000 character limits)
- Server-side storage approach adds complexity, database overhead, and potential race conditions
- Inconsistent with how the same code works with other OAuth providers (Google, Microsoft, etc.)
- Developers may not discover this issue until production deployment
- Custom delimiters (like
_SEP_) are non-standard and may conflict with actual data values
What Should Happen Instead
Proposed Solution:
Zoho's authorization server should properly handle URL-encoded pipe characters (%7C) in the state parameter, as required by RFC 6749. The state value must be treated as an opaque data blob.
Technical Requirement: Treat state as a Data Blob
| 1. Input |
Accept %7C (and other encoded characters) as valid parts of the query string without triggering validation errors or WAF rules |
| 2. Persistence |
Store the string exactly as received during the user's login/consent session—do not decode, parse, or transform |
| 3. Output |
Append the exact string back to the redirect_uri without additional transformations that might strip or corrupt the delimiters |
This approach:
- Complies with RFC 6749's requirement to return "the exact value received"
- Follows the same behavior as other major OAuth providers
- Requires no changes from client applications
- Unblocks third-party integrations that cannot modify their state format
Real-World Impact
This limitation affects any integration where:
- Third-party applications set the state parameter and cannot be modified (integration platforms, SaaS connectors, enterprise software)
- Multi-tenant applications need to encode tenant ID and return URL in state
- CSRF protection implementations combine security tokens with application state
- Single Sign-On flows need to preserve original request context
- Migration projects from other OAuth providers that used pipe delimiters
Critical Blocker: When the state parameter originates from a third-party system outside your control, there is no workaround available. The integration is completely impossible until this is fixed.
Security Note: The state parameter is critical for CSRF protection in OAuth flows. Forcing developers to change their state encoding approach may inadvertently introduce security vulnerabilities if not handled carefully.
Request to Zoho Team
Can this be addressed in a future update?
This is a standards compliance issue that impacts developers integrating with Zoho's API. For those who control their client application, the current implementation forces unnecessary workarounds. For those integrating third-party applications, the situation is worse:
1. Custom development
Refactor code to avoid pipe characters, creating Zoho-specific OAuth handling
|
2. Third-party integrations
No workaround possible - integration is completely blocked
|
Users should not be blocked from integrating with Zoho due to non-standard OAuth implementation.
Community Input Requested: Has anyone else encountered this issue? Are there other special characters that cause similar problems with Zoho's OAuth implementation?
📚 Documentation References:
Recent Topics
Zoho Mail Android app update: Calendar enhancements
Hello everyone! In the most recent version of the Zoho Mail Android app update, we have introduced various new enhancements for the calendar module. Let's explore what's new. Drag and drop events to update the date and time We have enhanced the calendar
Enhance Delay Configuration in Zoho Flow
Dear Zoho Flow Support Team, We are writing to request an improvement to the delay configuration process within Zoho Flow. Currently, users are required to manually enter the exact delay duration (e.g., "2 days") in the delay block. This can be time-consuming
Contratação ProdutivosX
Bem-vindo(a) ao processo de contratação da ProdutivosX. Este formulário tem como objetivo coletar informações essenciais para análise de perfil profissional, alinhamento de competências e possível integração ao equipamento ProdutivosX. A ProdutivosX é
Enhance Sign CRM integration
Hello all, I'm working on a custom Deluge script to enhance the integration between Zoho CRM and Sign by using a writer merge template for additional flexibility. I want to replicate the post-sign document integration that exists between CRM and Sign
Unified WhatsApp Number Management in Zoho Desk and SalesIQ
Dear Zoho Desk Support Team, We are currently utilizing both Zoho Desk and Zoho SalesIQ for our customer support operations. While both platforms offer WhatsApp integration, we are facing challenges due to the requirement of separate WhatsApp numbers
Email Field Validation Incorrectly Rejects RFC-Compliant Addresses (Forward Slashes)
I've encountered a validation issue with Zoho Creator's Email field that rejects RFC-compliant email addresses containing forward slashes, and I'm hoping the Zoho team can address this in a future update. The Issue When entering an email address containing
Plug Sample #15 - Enable Human-Like, Contextual Interactions in SalesIQ with Zia Agents
Zia Agents are conversational AI assistants designed to understand user intent and respond intelligently, helping businesses automate conversations and offer personalized support at scale. While Zia Agents are yet to be publicly released, access is currently
Best way to schedule bill payments to vendors
I've integrated Forte so that I can convert POs to bills and make payments to my vendors all through Books. Is there a way to schedule the bill payments as some of my vendors are net 30, net 60 and even net 90 days. If I can't get this to work, I'll have
Seamless Round-Trip Navigation for Related Blocks (Detail View)
As highlighted previously in this post (and here, here, here, and here), we still lack a fundamental capability for seamless navigation in Related Blocks. The popup that appears when adding a related record doesn't exist for viewing/editing existing records,
Social Profile Logo Format
Hello, I'm using Zoho Sites and am attempting to add a couple of social media accounts to my profile that aren't included in the default platforms that are available. What format is the logo required to be in? I have tried .png and .jpg with no success.
How to create Sepa Direct Debit XML file: solution and code
Even though Books provides a payment integration for Stripe and Gocardless (in Europe) there are customers that want to use the Sepa services of their own bank. Mainly because Stripe and Gocardless are quite expensive. In that case they would need a Sepa
Traditional Spreadsheet vs Zoho Tables
Hello everyone, This article explains the differences between Spreadsheet applications and no-code databases, such as Zoho Tables. While both tools belong to the "grid" family, the core difference lies in their purpose. A spreadsheet (such as Zoho Sheet,
RFQ MODEL
A Request for quotation model is used for Purchase Inquiries to multiple vendors. The Item is Created and then selected to send it to various vendors , once the Prices are received , a comparative chart is made for the user. this will help Zoho books
Delegate Access - Mobile iOS/iPad
We’re over the moon that delegate access is now available in Zoho Mail as we were nearly ready to switch platforms because of it! Is there a timeline on when delegate mailboxes will be accessible from the iOS and iPad OS applications? Thanks, Jake
Request For Quotation (RFQ) module
Hello, Do you have any plans to implement a RFQ module in to ZOHO Inventory? I would like to chose items that I require a price for, select a number of different suppliers to e-mail and have them submit there pricing online. I would then like to see a
Support for Developing Zoho Recruit Extensions via Zoho Sigma
Hi, I’m interested in building an extension for Zoho Recruit using Zoho Sigma. However, when I navigate to Sigma and attempt to create a new extension (via the "New Extension" option), Zoho Recruit does not appear as a listed service—only options like
FOLDER DISAPPEARED
Hello Zoho Community. I recently found a problem with no explanation: a folder in Zoho Analytics just disappeared, but the tables and SQL sentences still existed, the folder was not deleted. The solution for me in this case was to create a new folder,
How to create estimates/Invoices with sub-totals
Every other accounting package can create estimates and invoices with Sub-totals. How can I do that in ZohoBooks?
Deluge scripts
Why is there not a search function to make it easier to find the script of interest when modifications are required.
Social media simplified with Zoho Social: Why should brands have a Threads profile?
Just over a year ago, Instagram launched Threads, the all new social media app primarily focusing on sharing text online. It was welcomed by people worldwide with more than 10 million users in just seven hours, and it currently has over 175 million active
Auto tracking URL generation based on Carrier
Hi, While creating a shipment order for a package in Zoho Books, I have a requirement that for example, if the carrier is Delhivery and tracking number is 1234, then can automatically the tracking link/URL be generated as www.delhivery.com/1234. Similary,
New Beginnings with Zoho Desk mobile app best practices: Part 3
In focus: Scaling consistency, intelligence, and customization In our third installment, we'd like to share tips to help you elevate your customer experience as you handle support operations seamlessly on mobile. Let's reconnect with Omniserve, the field
Highlights of 2025: Milestones and moments
Hey everyone! As we step into 2026, it’s a great time to look back at everything 2025 brought to Zoho Social. This year was big, packed with powerful new features, smart enhancements, exciting events, and a major milestone: a whole decade of Zoho Social.
Introducing the sandbox environment in Zoho Sign
Hey there! Customer and partners across the globe have been requesting a testing environment—also called a sandbox—for quite some time. Sandboxes help you try out document workflows before using them in your production setup. This new year, we are excited
Can I share the drive with another Windows user?
We use the WorkDrive Sync application on a server with several remote desktop users. Our question is: Can the drive created by WorkDrive Sync be shared from one of these remote users with the other users so they can access the files, or do we need to
Syncing Bills in Zoho Books to Zoho CRM
Is there any way to sync the Bills in Zoho Books in Zoho CRM
Auto CheckOut Based On Shift.
This Deluge script runs on a scheduled basis to automatically set the 'Actual_Check_Out' time for employees who haven't manually checked out. If the current time is past their scheduled 'Shift_End_Time', the script updates the check-out time to match
ERROR: Product type cannot be changed for Items having transactions.
I have mistakenly added a product type as goods for an item that was a digital service. Now when HSN/SAC became mandatory, this brought my attention to this error I did. So I tried changing the product type but it displayed this error message Product
Boost your CRM accuracy with smart Data Enrichment
Hello all! In this post let's look at data enrichment from a holistic perspective to gain more clarity on how you can use it. So, here's a quick recap of what data enrichment is and how you set it up it to enhance your existing module data! What is data
Is it possible to set a region lookup table so that my deal country can lookup this lookup table
Hi there, I would like to be able to add a data lookup table with the following fields: Country, Region. And then in my deal report, i can then lookup this table to fish out the region in my report. This will be important for my sales process to categorise
Test Emails Show Sent "via zcsend.net" in My Gmail Account
I noticed the following info... However, a few email service providers such as Outlook and Gmail will display that the email was sent by zcsend.net (Zoho campaigns’ server) on your behalf instead of just your from email address. In order to prevent this, you can go for either of these options: Do not select the check box meant for DomainKey Signature which is listed under Unverified sender domains. Include our mail servers by advanced authentication method such as SPF/ Sender ID and DomainKey/ DKIM.
'UnAuthenticated Connection: zbooks_connection'
I have a zoho connection in Zoho Books, the link name es zbooks_connection, but I like to validate if exist, by example if I use this line in my code: response=zoho.books.getTemplates("", "","zbooks_connection"); But I don't have the connection I like
Calling the new 'Custom API' feature from within a Custom Widget
From what I've learned it is not possible to call an endpoint from the new "Custom API" feature within a Creator Widget. The SDK's doesn't support it yet, when calling it natively you end up with CORS issues or at least I couldn't get it working even
Cannot post to Instagram. I get the error: Insufficient permission to publish on this page. Check with your page Admin to update permissions.
We had another admin that left the company. Since he left, we get this error when posting to Instagram.
Zoho desk desktop application
does zoho desk has a destop applicaion?
Ability to re-order Workflow Rules
We really need the ability to re-order workflow rules within departments. Either the ability to drag/drop them into a different order or something.
Create an article template
I have a question concern the Knolwedge Database from Zoho Desk. There is any possibility to create an article template ? Exemple of what I research : TODAY : I want to create a lot af articles with the same baseline > I create one article > I copy/paste
Change of Blog Author
Hi, I am creating the blog post on behalf of my colleague. When I publish the post, it is showing my name as author of the post which is not intended and needs to be changed to my colleague's name. How can I change the name of the author in the blogs?? Thanks, Ramanan
Zoho FSM API Delete Record
Hi FSM Team, It would be great if you could delete a record via API. Thank you,
Instant Messaging Update | Now migrate your WhatsApp Business phonenumber from another BSP to Zoho Desk | Dec'23
Hi All, Everything seems to move at lightning speed these days, and time is certainly flying by for the IM team. But we are delighted at how much ground we covered this year. 🚀 For one, we enabled WhatsApp business phone number migration so that you
Next Page