I am trying to create an authorization request with front-end encrypted data.
My First encrypted data is :
eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiMSIsImNvbS53b3JsZHBheS5hcGlWZXJzaW9uIjoiMS4wIiwiY29tLndvcmxkcGF5LmxpYlZlcnNpb24iOiIxLjAuMSIsImNvbS53b3JsZHBheS5jaGFubmVsIjoiamF2YXNjcmlwdCJ9.NdjUwAHMuc3f_YIfti3VHcDLUbvUD58z76WVmS3_PqjktboxS12lwocooA5Py30aADsf4f3slAsxvVBMM_GC7uAv55-6o87RMkoVZWfhmibMoQfkmgijUfQ9R4nVi5kBXWzzFurQDi9dqLb-dRrSQBQb7IkAboA_UXf5X3bcr71yULudDULHOS_0cBSu9Csw2m1dZEtu6X_Ofayvw9ujTX7DHgNcAIdQoVQlYkWUKEv45pfeLvsv_yL4jV4TMlBOGLt-Hw0VXUSIrMCQ_239qAHIUsPU5mWoXmBbGtOWXZz7H-3RHg8xoU0DqPqwTELtQSEV_Zv-I0uQOx3T17cK5Q.8oKxgccRVID8cabx.mPQtAneIy6Y9fqYtMXHqQ0KZCXJMPV9D0aoijB7YO-nxjroUzW1xzfQT8t1BiGiSk949BbTOyPY47yC4lfkWmMmjvL19cKp6Liet1S_GIaV7zvPO7NHK1sk3EtBqXm0SO4pOg2oYFR9gOsmfWOC2_P0.Kdx3duCGTqiyRsC5hSkgaQ
it is a test card's encrypted data (5454545454545454 - 10 - 2019 - 123)
Then this request returns me same credit card and authorization. And I am saving this information.
Then I am trying to new authorization request with same card but different expiry dates (like: 5454545454545454 - 07 - 2022 - 123)
and it's encrypted data is different:
eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiMSIsImNvbS53b3JsZHBheS5hcGlWZXJzaW9uIjoiMS4wIiwiY29tLndvcmxkcGF5LmxpYlZlcnNpb24iOiIxLjAuMSIsImNvbS53b3JsZHBheS5jaGFubmVsIjoiamF2YXNjcmlwdCJ9.gayFeZkSPGh9zYTEHj6qK9ikWNKDQ6kJApdEKlvfQqhsoK66PCwuFrIW50wbzBUQA_VGVSBFiOHF-iyHGVg1G7OQt3CIW0-bpvHN6dsVNzVKL5SXkL15oN8LpiH6W57Zk0IyWmhukMrsdeg_fqyHUW5AmkZ7sGMw7_FWMkyZsA07nFn90YvpXnS-ZIifr-cK3Kl4uoaitB6_mLKxh5l6ZlHa6eychbcjV-BHW8Hx0o9WHyl-MHrgZD2h8H9ulbWSkyQOMniV_--r-_ewN0znZaHdyv0BzzUoVHX4GliNmJpJ3iolkFeLl07H_i4rqdAOhBJprCm9eY3j8qgqOJNr4w.bh4c8SwzG8Lg2HTA.Gt0DCdG__Nc_eB8xAa8ziD7YNg5V8dOTcfOZUY4VG0Ta5hY7ekO57pDWcmmKD2BpEiZY34098zO8xC0PoR0gHb5k9G9dgkrLgFeC9ORfe7zZa_2tVe6vfJysZ7POkYqp8W2KMGaJEtZlGKDrLgPs26o.mcXSrq0ab-yOruwJNlpobQ
But Worldpay gives me same response.. (same masked credit card number and same dates with previous request.)
Are there any idea?
I learnt this issue come from Worldpay configuration for the development environment. So, don't spent time on this issue.
Related
I am trying to implement expiring to the activation link I send to the user's email when they register a new account.
The link should expire after 24 hours if the user doesn't click on it.
Up until this point I am able to send the link to the user's email upon registration, the link looks like this 'http://localhost:3000/auth/activate/${verificationKey}', everything works smoothly.
But like I said, I want the link to expires after 24 hours and I just don't have any idea of how to do it.
From what I've gathered so far I think one way to do this would be to delete the verificationKey value from my User entity/model after 24 hours, then if the verificationKey value is falsy I need to send another link to the user.
Now my question is, how do I check if a value (in this case user.verification_key) has been generated for over 24 hours?
This is the relevant code to register a new user:
const user = new User();
user.username = username;
user.password = await bcrypt.hash(password, salt);
user.is_verified = false;
user.verification_key = cryptoRandomString({
length: 10,
type: 'url-safe',
});
Some people have suggested to use Redis for this, which I don't know anything about other than it's a in-memory store, and while I'm ok reading more about this tool, I would like to know if there are other ways to do this. I don't know if by installing Redis I would need extra configuration for the server when I host my app, I'd like to avoid that.
Since you already have some database set up, it makes sense to store some verification key and an expiration time for it. You don't need to actually delete that verification key... just need to store when it expires.
Perhaps you have a separate model for RegVerificationKey, with fields key (randomly generated string), expiration (set to a date/time 24 hours after you create it), and userId (the ID of the user this is associated with). Create this key. When you go to activate, just check to see if there is a key associated with the requested user that hasn't expired yet.
Some people have suggested to use Redis for this
No need here, you already have a database you can put data in.
I would like to know if there are other ways to do this
There's an alternative, where you cryptographically sign your URL. Basically, you would store the key and its expiration data in the URL itself, and include some calculated proof that you (the person with the private key) created this URL. When your system receives this URL, it can verify the URL was signed correctly without even having to consult a database. This method can be complicated and probably isn't useful in your case. I'm just mentioning it here as an alternative. Check out JWT for one possible implementation: https://jwt.io/
Recently I was needed to implement this kind of implementation in my web application. So I just followed the below points to achieve it.
1- Create the URL (web link) and append the current date and time along with an encrypted key which you would store in the database as mentioned below.
2- Create a column in the database table (the table where you store any user specific details) to store a randomly generated key which you have encrypted and appended in the URL.
3- When you would receive this URL on server you would check the encrypted date and time in the URL and would decide whether it is still valid depends on your criteria of retaining a link (e.g. 24 hours)
4- Next you would decrypt that key in the URL that you have appended in it at the time of creating it and would match it with what you have stored in the table.
So by implementing above logic you could achieve the desired functionality.
Hope its useful for any one who wants similar type of implementation
I understood that you already found a solution, by storing two fields in the database: one for the key and another one for he expiration timestamp. Everything depends on the use cases and it is definately one way to do it. However I will explain Redis and JWT as a solution in comparison to yours.
Redis is an in-memory datastore (that also allows persistence to disk) as you pointed out and I think the reason why people suggested it is, that you can define an expiration time for a record. Redis will remove that record automatically for you then. Reference: https://redis.io/commands/expire
Redis would take the work off of your shoulders to check if the 24hrs already passed. If you can’t fetch the key anymore, the key probably expired. Another benefit of Redis is, that is super quick compared to your normal database query. But if you only need it for the activation link, which is a one-time-action for the user, the time benefit is negligible. Also you would introduce a new technology just for that use case.
#Brad already suggested using JWT (Json Web Token) instead of implementing your own token solution and I would also suggest that for the following reasons.
A JWT is a self-contained token consisting of three parts: Header, Payload, Signature. The header contains the name of the algorithm that was used to create the token. The paylod contains some standardized fields (e.g. creation date, expiration date, subject the token was issued for like username) and you can also add custom fields. The third part is a signature that ensures that no one changed the payload after it was issued by your token service.
Self-contained means that the token contains everything to validate it, including the expiration timestamp. In your case the expiration time is not part of your token but stored in the database. If you create another microservice that needs to verify your token, that service needs to contact your main service which contains the logic to check the expiration database field.
With JWT the Microservice would only need to know the secret key that was used to sign the token and then you can just import some standard JWT library to verify the token. These libraries validate the signature as well as the expiration timestamp which is an optional field in the payload of the token.
By the way, the payload can be read without knowing the secret key from the signature. So it is even possible to read the payload for example on client side to check the expiration time.
With your solution you have additional database calls, which are potentially slow. For an activation link that is acceptable, but for tokens with recurring use within a short timespan (i.e. API requests that require authentication) additional database calls should be avoided. Also you need to implement token generation and verification yourself, whereas JWT provides standard libraries. This is a benefit when you want to have another Microservice in Java instead of NestJS for example. You can quickly knit them together by using standard libs instead of porting your implemtation or being forced to decide for a centralized token verification service.
One limitation of JWT you have to workaround yourself, is the use case where you want to have a „one time token“. You can only define an expiration date but you can not say that a token can only be used x times. Here you need a centralized service again, which keeps track of how often a token was used (by making use of some datastore) and all other services around need to contact that service.
A good starting point for JWT with NestJS is the official NestJS documentation.
I am sending a transaction ID as a link via email, using this link anyone can search for the details of transaction happened in my system. I would like to enforce expiry time for the link, say for 1 month link should work and post 1 month, link should expire.
I am using nodejs for implementing my software. I would like to send only transaction ID as the parameter for creating the link.
I planned to combine Transaction ID and expiry_timestamp and encode/encrypt and send the encoded/encrypted data as the parameter in the URL. Later when link is clicked and request is received to server, I should be able to retrieve the expiry_timestamp and compare it with current data and decide to proceed or no. Here if Iam sending timestamp in plaintext, user may change the timestamp and request, so I am planning to encode or encrypt it.
Please suggest some cryptographic techniques for implementing this.
Thanks in advance.
You can do this by following way.
Create another column name something like token
Store expiry date and time on another column as you are already doing this.
Pass token as a query string that has been stored in DB rather than the timestamp.
when user click on the link you can check either validate or not using token (query string)
You can use this( https://www.npmjs.com/package/rand-token) package to generate tokens.
Before you ask for some code, understand that this question is about the implementation technique than code mongering.
OK, so in order to save a customer in stripe connect to charge them later or monthly, here is the prescribed process:
step 1. Use Stripe.js to get card details of the user such as card numbr, exp date, cvv etc. which will be sent to stripe.
step 2. Stripe returns a token corresponding to the card like: tok_xyz, now this token can be used to generate a customer in Stripe and you will get customer id.
step 3. Once you have customer id, you can charge them anytime.
Now I have two questions:
If I provide same card details in the step 1 above, will strip return same token everytime? I am asking it so that I may know how to handle the condition when a user enters same card details twice and I don't accidentally create multiple entries in the database for same card again and again.
It's documented in Stripe that after they issue card token (step 1 above) the CVV remains valid only for few minutes and if you don't make a charge in that time, later on the card will become invalid so do I need to charge the customer right away with a small amount like 0.01$ or something? or when I create customer (step 2 above), stripe takes care of that?
Thank you for any help in advance.
No, you will get a different token and tok_xxx ID value every time. However, there is a fingerprint property you can read from the token and compare to cards saved to the customer, to check for duplicates. There are some good answers on StackOverflow showing examples of that.
True, the CVC value is only held for a short amount of time. If you make a charge during that time, it can be checked by the bank. Creating a charge outside that time doesn't make the card invalid, but it will likely lead to more chance of a decline. Luckily this isn't an issue — when you create a customer object Stripe performs a $0 authorisation charge(as described in the blue box here). So as long as you either charge the token directly, or use it to create a customer object, as soon as you get it, you don't need to think about this.
I've been playing with stripe recently and while i fully understand that the token hides the clients credit card details from the server. This tutorial suggests that the server should not rely on the data-amount since it can be changed by the client
Don’t Rely on the Form’s Price
A frequent mistake stems from using form data to contain the price of
the product being purchased, possibly via a hidden input. Because a
user can easily edit this input’s value, it’s unwise to depend on it.
Always fetch the price of the product from the server-side. Never rely
on the form to tell you. A simple database query is the preferred option.
Can someone explain to be why stripe does not include the data-amount value as a parameter in the token generation? Is there not a potential for a server side code to change the agreed price and overcharge the client.
The token is a placeholder of a pending charge, it does not know how much you are going to charge yet. Once you are ready to charge the card an api request will be sent to Stripe along with the token. The concern about the amount deals with relying on POST data from a form that can be manipulated by the customer.
Its up to you to set the charge amount. For example a hotel could authorize $100 to spend the night but then at check out discover that you used the minibar and then charge $150. Or the auto calculated shipping is off so when you actually purchase the shipping its $5 less and you decide to charge $5 less than your auth.
What you should be doing is calculating the amount to charge the customer, save it via a shopping cart like function in your DB (or serverside somehow) sending the checkout form to the customer then using the previously calculated amount run the auth then the charge.
Form data can easily be changed by the end user. Just open the page and right click (in chrome) and click inspect element. You can then arbitrarily change form data. So if you were using that, the user could set the price to $.01 for your $1,000.00 product.
The propose of tokenization in the PCI world is to keep sensitive data off your servers. Otherwise you would collect the PCI data yourself then send the amount off to the processor along with the PCI data. By not ever having the sensitive data touch your systems you save a ton of money and headache in PCI compliance. See this 115 page document: https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-1.pdf
Hope that helps, Please comment and I'll try to help further if it doesn't.
I have an application that runs on for example Google TV or Apple TV, which sends HTTP requests to a service of mine.
Now if someone listens in on this request, they can replay it and in that way execute a Denial of Service (DOS) attack our service.
Is there any way to make each request unique, so it cannot be replayed?
I thought of sending the time encrypted in the request and check the difference between the server time and the time the request was sent, but I'm getting too big time differences to compare.
Does anyone have a better idea?
You are in a good situation as you have control both on the server side and the client side (your application is talking). Include into your message
The current time in milliseconds plus + random number
The combined hash produced by these values plus (as a the third input) some key only your application knows. Use some good one way hashing algorithm.
Only the code who knows the mentioned key will be able to compute a correct hash. The used request records (hash and time stamp) can be stored for some expiration time that can be long. Very old request records can be easily expired as they contain the time stamp.
The positive feature of the proposed approach is it does not require to connect in advance in order to receive a token, needs no authentication, needs no registration and can use the open protocol. Using token just by itself does not help much against DoS as an attacker quickly writes a script to connect and obtain the token in advance as well.