State parameter

It’s your responsibility to protect the security of your app’s users. Because of this, we strongly recommend using a state parameter provided by OAuth 2.0 to increase the security when users install the app from the Pipedrive Marketplace.



CSFR attacks


Your app can use a state parameter for making sure the response belongs to a request initiated by the same user, therefore preventing cross-site request forgery (CSFR) attacks. A CSFR attack occurs when a malicious attacker tricks the user into performing unwanted actions that only the user is authorized to perform on a trusted web application, and all will be done without involving or alerting the user.

📘

"A CSRF attack against the client's redirection URI allows an attacker to inject its own authorization code or access token, which can result in the client using an access token associated with the attacker's protected resources rather than the victim's (e.g., save the victim's bank account information to a protected resource controlled by the attacker)." Continue reading from the source RFC-6749.



State parameter value


Have your app generate a random string and use it as a state value, unguessable by attackers. It can be a session ID, hashed user ID, or any other value you would like to use. Make sure to store this value so you can validate the incoming state against it later.



How to implement the state parameter


Here’s the simplest example of how providing the state can make your app more secure. in this example, we use the session ID as the state parameter, but you can use whatever logic you want to create value for the state.

Step 1: Your app needs to generate the state parameter value and append it to the OAuth authorization URL (make sure the state is different for different users/requests):

<?php
session_start();
 
// Assign to state the hashing of the session ID
$state = hash('sha256', session_id());
 
// Prepare parameters
$data = [
    'client_id' => 'b4d083d9216986345b32', // The client_id of your App
    'redirect_uri' => 'https://awesomeapp.com/oauth/callback', // The redirect_uri of your App
    'state' => $state
];
 
// Build the final url
$url = 'https://oauth.pipedrive.com/oauth/authorize?' . http_build_query($data);
 
echo $url;

Step 2:  Your app must redirect the user to the OAuth authorization URL with the state parameter you created.

Step 3: Once the user has authorized your app, the user will be redirected back to your app’s redirect_uri. The OAuth server will return the state parameter unchanged.

Step 4: Check if the state provided in the redirect_uri matches the state generated by your app:

<?php
session_start();
 
$state = !empty($_GET["state"]) ? $_GET["state"] : null;
$code = !empty($_GET["code"]) ? $_GET["code"] : null;
 
// Check the state received with current session id
if ($state != hash('sha256', session_id())) {
    exit('State does not match!');
}
 
echo $code;

By doing so, you have made sure that the state passed to the OAuth server matches the state in the redirect_uri to where the user was redirected, thus ensuring the validity of the redirect.

In the case of the state not matching, you could assume a possible redirect by a malicious attacker.