Bug: OAuth 2.0 State Parameter fails with Pipe Delimiters (RFC 6749 Non-Compliance)

Bug: OAuth 2.0 State Parameter fails with Pipe Delimiters (RFC 6749 Non-Compliance)

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?

    • Sticky Posts

    • Deprecation of SMS-based multi-factor authentication (MFA) mode

      Overview of SMS-based OTP MFA mode The SMS-based OTP MFA method involves the delivery of a one-time password to a user's mobile phone via SMS. The user receives the OTP on their mobile phone and enters it to sign into their account. SMS-based OTPs offer
    • Recent Topics

    • How to post more than 4 Images on Instagram?

      Hi I read several articles to the topic od how to post more than 4 images on instagram, but i can't figure out how it works. I can't find the content editor and i installesd the z share extension for google chrome. Could someone please help me? Than
    • Clone Recurring Expenses

      Our bookkeeping practices make extensive use of the "clone" feature for bills, expenses, invoices, etc. This cuts down significantly on both the amount of typing that needs to be done manually and, more importantly, the mental overhead of choosing the
    • Zoho Books - How to Invoke a Custom Function in Schedulers

      We have multiple schedulers that send emails to customers in batches. Currently, we are maintaining the same code across several schedulers. Is it possible to use a custom function inside a scheduler script? If yes, how can we invoke the custom function
    • Special characters (like â, â, æ) breaking when input in a field (encoding issue)

      Hey everyone, We are currently dealing with a probably encoding issue when we populate a field (mostly but not exclusively, 'Last Name' for Leads and Contracts). If the user manually inputs special characters (like ä, â, á etc.) from Scandinavian languages,
    • Set Custom Icon for Custom Modules in new Zoho CRM UI

    • Notes badge as a quick action in the list view

      Hello all, We are introducing the Notes badge in the list view of all modules as a quick action you can perform for each record, in addition to the existing Activity badge. With this enhancement, users will have quick visibility into the notes associated
    • Is Zoho Live Chat compatible with WordPress CMS?

      Hello, I have a website called www.jjrlab.com and I'm interested in using Zoho Chat on it. Does it support WordPress CMS? Thanks.
    • Introducing spam detection for webforms: An additional layer of protection to keep your Zoho CRM clean and secure

      Greetings all, One of the most highly anticipated feature launches—Spam Detection in webforms—has finally arrived! Webforms are a vital tool for record generation, but they're also vulnerable to submissions from unauthenticated or malicious sources, which
    • Bring your CRM and Desk app inside SalesIQ with widgets

      Have you ever been confused and frustrated with multiple open tabs and switching back and forth from SalesIQ to other apps to perform your business-specific operations? How effective would it be to have all the required tools and data of the apps you
    • Speak Your Customers' Language: SalesIQ's chatbots now support 30 languages 🤖

      We're unveiling some major upgrades to our chatbot that are set to revolutionize your experience! Now SalesIQ support 30 languages for both Zobot and Answer bot. By speaking your customers' language, you can enhance engagement, improve customer satisfaction,
    • Repeat Column merge in ZOHO writer columns doesn't allow to set max columns per row

      I'm using ZOHO writer to merge data from a ZOHO CRM subform and I want it to make a table. We're using Insert Table for Column Repeat, because this is what we need. (Name of column (Teamname) and underneath that a list of names of teammembers). It works
    • Persisting email signals to contact timeline?

      Hello there. Regarding the email signals that are logged when a contact opens an email, am I correct that these signals are not logged to a contact's timeline? Ideally, I would like to have this context available for future follow-ups, if the contact
    • Trouble with using Apostrophe in Name of Customers and Vendors

      We have had an ongoing issue with how the system recognizes an apostrophe in the name of customers and vendors. The search will not return any results for a name that includes the mark; ie one of our vendors names is "L'Heritage" and when entering the
    • Really want the field "Company" in the activities module!

      Hi team! Something we are really missing is able to see the field Company when working in the activities module. We have a lot of tasks and need to see what company it's related to. It's really annoying to not be able to see it.🙈 Thx!
    • Upcoming update to Google Drive integration in Zoho Creator

      Hello everyone, We're writing to inform you about an upcoming update to how Zoho Creator integrates with Google Drive. In Zoho Creator, during actions like importing files to create an app or attaching files to fields, you can choose files directly from
    • Changing Account Type in Chart of Accounts

      Does anyone know how to change/edit the account type for an Account name in Chart of Accounts. Zoho will not let me do this for some reason
    • Managing Scheduled Replies

      Communication is most effective when the intended message reaches the right person at the right time. However, this can be challenging when communication occurs across different time zones. By scheduling replies, businesses can ensure that responses reach
    • Show price book list price

      When using price books, once you add products to the price book in the Products related list you can display the Unit price which is the default list price; however, there is no option to show the price book list price. To see the price book list price
    • Allow Attaching Quartz Recordings to Existing Zoho Support Tickets

      Hi Zoho Team, We would like to request an enhancement to how Zoho Quartz recordings integrate with Zoho Support tickets. Current Behavior: At the moment, each Quartz recording automatically creates a new support ticket. However, in many real-world scenarios:
    • Can I hide empty Contact fields from view?

      Some contacts have a lot of empty fields, others are mostly filled. Is there a way I can hide/show empty fields without changing the actual Layout? I would like to de-clutter my view, and also be able to add information later as I am able. I would be
    • Manage user roles and profiles from the Bigin app (iOS and macOS)

      Hello everyone! We're happy to announce that you can manage user roles and profiles from the Bigin mobile app. The Users & Controls section has three subsections: Users, Profiles, and Roles. Users Employees who belong to your Bigin organization are called
    • Support Bots and Automations in External Channels

      Hello Zoho Cliq Team, How are you? We actively use Zoho Cliq for collaboration, including with our external developers. For this purpose, external channels are a key tool since they work seamlessly within the same interface as all of our other channels
    • Form to PDF template

      I am looking to create a Form and when information is inputted, it will merge it into a PDF template we already have. There could be multiple lines in the form and each line inputs information into a new page of a PDF template.
    • Please verify my account

      Hi, We have just launched our website and received media coverage in our country. Hundreds of users are signing up for our platform every day. We would like to send them a welcome email, but we are unable to do so because our ZeptoMail account has not
    • Subject character limit increase

      We have an occasional user case where subject lines exceed 500 characters which is the ZeptoMail imposed limit. While I understand long subject lines are not "best practice", these are particular notification emails with specific information for client
    • Account blocked

      Yesterday I got my Zeptomail account blocked due to too many hard bounces. My account is used exclusively for sending transactional emails (eg. your order has been shipped, a form has been filled, etc) and the sudden blocking impacted hundreds of websites
    • Nested notebooks

      Dear Sir/Madam, I would like to know if it is possible to nest notebooks. It would be very helpful when there are too many, as it would improve organization. Thank you for your response. Best regards.
    • Cannot see correct DNS config for mail after moving domain to another provider

      I have moved my domain from one provider to another and after that zoho mail stopped working (expected). Problem is, zoho mail admin panel still shows (10 hours after move) that all records are correct while I haven't changed anything in my domain DNS
    • Proactive Alert for Existing Open Tickets per Contact / Account

      Hello Zoho Desk Team, Greetings, and hope you’re doing well. We would like to submit a feature request aimed at improving agent awareness and efficiency when handling tickets in Zoho Desk. Use case When an agent opens a ticket (new or existing), it is
    • Ticket resolution field - can you add links, video, and images?

      Seems like the ticket resolution fields is just a text field. Any plans to add the ability to add links, images...the same functionality in the problem description box? I would like to send the customer a link to a KB article, a link to our Wiki, embed
    • Ticket Resolution - Add rich formatting, screenshots and attachments

      The resolution field only allows plain text at the moment. Many of our resolutions involve posting screenshots as evidence, it would be great for us to be able to have rich text formatting, be able to paste screenshots and add attachments in the solution
    • CRUD actions for Resources via API

      Hello, is it possible to perform CRUD actions through the API for Resources? We want to create a sync from Zoho CRM Car record to Bookings resources to create availabilities for Car bookings. For Test drives, not only the sales person needs to be available,
    • Kaizen #140 - Integrating Blog feed scraping service into Zoho CRM Dashboard

      Howdy Tech Wizards! Welcome to a fresh week of kaizen. This week, we will look at how to create a dashboard widget that displays the most recent blog post of your preferred products/services, updated daily at a specific time. We will leverage the potential
    • Convert Lead Automation Trigger

      Currently, there is only a convert lead action available in workflow rules and blueprints. Also, there is a Convert Lead button available but it doesn't trigger any automations. Once the lead is converted to a Contact/Account the dataset that can be fetched
    • I'm getting this error when I try to link an email to a deal inside the Zohomail Zoho CRM extension.

      When I click "Yes, associate," the system displays an "Oops!! Something went wrong" error message. I have attached a screenshot of the issue for reference.
    • Zoho Sheet - Desktop App or Offline

      Since Zoho Docs is now available as a desktop app and offline, when is a realistic ETA for Sheet to have the same functionality?I am surprised this was not laucned at the same time as Docs.
    • ZOHO add-in issue

      I cannot connect ZOHO from my Outlook. I am getting this error.
    • Marketing Automation

      L.S. Marketing Automation is and has always been part of the Zoho One bundle - according to the information provided on the Zoho Website. Why when I open Marketing Automation do I get the following message?: "Your trial has expired. We hope you enjoyed
    • What's New in Zoho Analytics - January 2026

      Hello Users! We are starting the year with a strong lineup of updates, marking the beginning of many improvements planned to enhance your analytics experience. Explore the latest improvements built to boost performance, simplify analysis, and help you
    • Translation from Chinese (Simplified) to Chinese (Traditional) is not working. It randomly translated. Google Translate accurately but zoho translate is not working at all

      Hi friends, The newly added language for translation. https://www.zoho.com/deluge/help/ai-tasks/translate.html "zh" - Chinese "zh-CN" - Chinese (Simplified) "zh-TW" - Chinese (Traditional) my original text: 郑这钻 (and it is zh-CN) translated traditional
    • Next Page