Ensure attempt to complete a verification method is allowed
What does this MR do and why?
In preparation for https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/issues/542+, this ensures attempt to complete a verification method is allowed.
Context: users are required to complete verification methods in order depending on their risk score:
Risk score | Required verification methods (in order) |
---|---|
Low | 1. email |
Medium | 1. email 2. phone |
High | 1. email 2. phone 3. credit card |
Previously, phone number verification endpoints were secured (using a before action hook) by ensuring that a user is required to complete phone number verification and has already completed email verification.
In this MR, the before action hook is made generic so it can ensure that a verification method is required and all its prerequisite verification methods are completed before the corresponding action is executed.
For example, if a user is required to complete the following:
Note: that the order of credit card and phone are swapped. This should not matter.
- credit card
- phone
Hitting the credit card verification endpoints will require email method is completed and that credit card verification is actually required for the user. The same happens for phone number verification endpoints except for a slight difference: instead of just email method, completion of both email and credit card methods are checked.
How to set up and validate locally
Click to expand
-
Enable the relevant feature flags
> Feature.enable(:arkose_labs_signup_challenge) > Feature.enable(:identity_verification_phone_number) > Feature.enable(:identity_verification_credit_card) > Feature.enable(:identity_verification)
-
Configure application settings for Identity Verification
> ApplicationSetting.first.update(email_confirmation_setting: 'hard') > ApplicationSetting.first.update(arkose_labs_public_api_key: "XXX", arkose_labs_private_api_key: "YYY", require_admin_approval_after_user_signup: false) > ApplicationSetting.first.update(telesign_customer_xid: 'XXX', telesign_api_key: 'YYY')
Note: credentials are in 1Password under
Telesign API keys
(development) andArkoseLabs API keys
(development) -
Register a new user
-
Force user to have high risk
> User.last.custom_attributes.by_key('arkose_risk_band').first.update!(value: 'High')
-
Login with the new user
-
Inspect the page and copy the CSRF token value as well as the session token key and values
-
Tail the logs
tail -f log/application_json.log
-
cURL the credit card verification endpoint with the CSRF token and session cookie key and values
# example: curl 'http://localhost:3000/users/identity_verification/verify_credit_card' -H 'X-CSRF-Token: AcASKvAh5fs1iN3Gdm4mUyN6bd0JZ_cHP9wDZinLNQVcAPq_l-xYu3PvuZ5-gCfab1Zq6VlqUBWmyvvq890hZg' -H 'Content-Type: application/json' -H 'Cookie: _gitlab_session_0d0184310be27aaaec4eedf3c05ef650b389e2b1f09bc0cf7ce1d212eae05729=883b39b4a674e7cae77398deb0b4381d' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' curl 'http://localhost:3000/users/identity_verification/verify_credit_card' -H 'X-CSRF-Token: <CSRF_TOKEN>' -H 'Content-Type: application/json' -H 'Cookie: <SESSION_COOKIE_KEY>=<SESSION_COOKIE_VALUE>' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin'
-
Verify that you get
{}%
response and the following entry is logged{"severity":"INFO",..."meta.caller_id":"Users::IdentityVerificationController#verify_credit_card",..."message":"IdentityVerification::CreditCard","event":"Failed Attempt","action":"verify_credit_card"..."reason":"unauthorized"...}
-
cURL the phone number send code endpoint with the CSRF token and session cookie key and values
curl 'http://localhost:3000/users/identity_verification/send_phone_verification_code' -X POST -H 'X-CSRF-Token: <CSRF_TOKEN>' -H 'Content-Type: application/json' -H 'Cookie: <SESSION_COOKIE_KEY>=<SESSION_COOKIE_VALUE>' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' --data-raw '{}'
-
Verify that you get
{}%
response and the following entry is logged{"severity":"INFO",..."meta.caller_id":"Users::IdentityVerificationController#send_phone_verification_code",..."message":"IdentityVerification::Phone","event":"Failed Attempt","action":"send_phone_verification_code"..."reason":"unauthorized"...}
-
cURL the phone number verify code endpoint with the CSRF token and session cookie key and values
curl 'http://localhost:3000/users/identity_verification/verify_phone_verification_code' -X POST -H 'X-CSRF-Token: <CSRF_TOKEN>' -H 'Content-Type: application/json' -H 'Cookie: <SESSION_COOKIE_KEY>=<SESSION_COOKIE_VALUE>' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' --data-raw '{}'
-
Verify that you get
{}%
response and the following entry is logged{"severity":"INFO",..."meta.caller_id":"Users::IdentityVerificationController#verify_phone_verification_code",..."message":"IdentityVerification::Phone","event":"Failed Attempt","action":"verify_phone_verification_code"..."reason":"unauthorized"...}
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.