App component approval checklist

A list of criteria your app component app must meet to pass our review process

Security

1: Ensure that the stateparameter is being respected

The state variable in OAuth is used to prevent Cross-Site Request Forgery (CSRF) attacks. By validating the state query parameter, you enhance the security and reliability of your OAuth implementation, protecting both your application and its users from various types of attacks and vulnerabilities.

During the OAuth process, your app server should send a randomized state value to Asana when it calls GET https://app.asana.com/-/oauth_authorize. This will take the user to the "Grant Permission" page. When the user clicks on "Allow" Asana will make an API call back to your app server's redirect URL with the sate parameter you provided earlier (e.g., GET https://example.com/oauth/callback?...&state=02208f10-f2d3-420f). When this happens, your app should verify that the state that the request is coming from matches the state that you sent earlier. If the state does not match, your app should return a 422error.

2: state query param is unguessable

Make sure the state that you are sending to Asana's https://app.asana.com/-/oauth_authorizeendpoint is randomized and not easily guessable. By making the state variable unguessable, you add an extra layer of security to your OAuth implementation, protecting against various attack vectors and ensuring a more secure authentication process.

EX: Good statevalue

c527dd5e-4fa5-4626-a064-f81218d8c856

EX: Bad statevalue

hello-world

3: Handle the "Deny" use case

When the user clicks on the "Deny" button on the grant permission page, your app should return the following:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>You have successfully connected Asana to the app</title>
    </head>
    <body>
        Success!
        <script>
            window.opener.postMessage("error", "https://app.asana.com");
            window.close();
        </script>
    </body>
</html>

Doing so will redirect the user to the OAuth page, where it will show the message: "You denied authorization of the app."

4: Ensure that the x-asana-request-signature header is being respected

Each time Asana makes a request to your app server's app component endpoints (e.g., Get form metadata, On submit callback, etc.), we send an x-asana-request-signature value in the request header. Your app server should generate a computed signature based on the request and compare it to the x-asana-request-signature from the request header. If the computed signature and x-asana-request-signature do not match, your app server should return a 400 error.

For details on how to generate the computed signature see: More details on validating request signatures

GET Requests

POST Requests

5: Ensure that the expires_at query param is being respected

Each time Asana sends a request to your app server's app component endpoints, we include an expires_at query parameter. Your app server should check this value and only return a 200 response if the current date and time is before the expires_at time.