When Canva sends an HTTP request to an app, it includes a UNIX timestamp (in seconds) of when the request was sent. To protect itself against replay attacks, an app must:
- Compare the timestamp of when the request was sent with when it was received.
- Verify that the timestamps are within 5 minutes (300 seconds) of one another.
When the timestamps are not within 5 minutes of one another, the app must reject the request by returning a 401
status code.
This page provides functions in a variety of programming languages to verify timestamps.
For step-by-step tutorials, refer to:
Examples
This section provides examples in the following languages:
Go
package mainimport ("fmt""math")func IsValidTimestamp(sentAtSeconds int, receivedAtSeconds int, leniencyInSeconds int) bool {return int(math.Abs(float64(sentAtSeconds - receivedAtSeconds))) < leniencyInSeconds}func main() {// Valid timestampsfmt.Println(IsValidTimestamp(1590980773, 1590980773, 300)) // => truefmt.Println(IsValidTimestamp(1590980773, 1590980523, 300)) // => truefmt.Println(IsValidTimestamp(1590980773, 1590981023, 300)) // => true// Invalid timestampsfmt.Println(IsValidTimestamp(1590980773, 1590980273, 300)) // => falsefmt.Println(IsValidTimestamp(1590980773, 1590981273, 300)) // => false}
go
Java
public class Example {public static void main(String[] args) {// Valid timestampsSystem.out.println(isValidTimestamp(1590980773, 1590980773, 300)); // => trueSystem.out.println(isValidTimestamp(1590980773, 1590980523, 300)); // => trueSystem.out.println(isValidTimestamp(1590980773, 1590981023, 300)); // => true// Invalid timestampsSystem.out.println(isValidTimestamp(1590980773, 1590980273, 300)); // => falseSystem.out.println(isValidTimestamp(1590980773, 1590981273, 300)); // => false}static Boolean isValidTimestamp(Integer sentAtSeconds, Integer receivedAtSeconds, Integer leniencyInSeconds) {return Math.abs(sentAtSeconds - receivedAtSeconds) < leniencyInSeconds;}}
java
JavaScript
function isValidTimestamp(sentAtSeconds,receivedAtSeconds,leniencyInSeconds = 300) {return Math.abs(sentAtSeconds - receivedAtSeconds) < leniencyInSeconds;}// Valid timestampsconsole.log(isValidTimestamp(1590980773, 1590980773)); // => trueconsole.log(isValidTimestamp(1590980773, 1590981023)); // => trueconsole.log(isValidTimestamp(1590980773, 1590980523)); // => true// Invalid timestampsconsole.log(isValidTimestamp(1590980773, 1590980273)); // => falseconsole.log(isValidTimestamp(1590980773, 1590981273)); // => false
javascript
PHP
<?phpfunction isValidTimestamp(int $sentAtSeconds, int $receivedAtSeconds, int $leniencyInSeconds = 300) {return abs($sentAtSeconds - $receivedAtSeconds) < $leniencyInSeconds;}// Valid timestampsvar_dump(isValidTimestamp(1590980773, 1590980773)); // => bool(true)var_dump(isValidTimestamp(1590980773, 1590980523)); // => bool(true)var_dump(isValidTimestamp(1590980773, 1590981023)); // => bool(true)// Invalid timestampsvar_dump(isValidTimestamp(1590980773, 1590980273)); // => bool(false)var_dump(isValidTimestamp(1590980773, 1590981273)); // => bool(false)?>
php
Python
def is_valid_timestamp(sent_at_seconds, received_at_seconds, leniency_in_seconds = 300):return abs(sent_at_seconds - received_at_seconds) < leniency_in_seconds# Valid timestampsprint(is_valid_timestamp(1590980773, 1590980773)) # => Trueprint(is_valid_timestamp(1590980773, 1590980523)) # => Trueprint(is_valid_timestamp(1590980773, 1590981023)) # => True# Invalid timestampsprint(is_valid_timestamp(1590980773, 1590980273)) # => Falseprint(is_valid_timestamp(1590980773, 1590981273)) # => False
python
Ruby
def is_valid_timestamp(sent_at_seconds, received_at_seconds, leniency_in_seconds = 300)(sent_at_seconds - received_at_seconds).abs < leniency_in_secondsend# Valid timestampsputs is_valid_timestamp(1590980773, 1590980773) # => trueputs is_valid_timestamp(1590980773, 1590980523) # => trueputs is_valid_timestamp(1590980773, 1590981023) # => true# Invalid timestampsputs is_valid_timestamp(1590980773, 1590980273) # => falseputs is_valid_timestamp(1590980773, 1590981273) # => false
ruby
TypeScript
function isValidTimestamp(sentAtSeconds: number,receivedAtSeconds: number,leniencyInSeconds: number = 300): boolean {return Math.abs(sentAtSeconds - receivedAtSeconds) < leniencyInSeconds;}// Valid timestampsconsole.log(isValidTimestamp(1590980773, 1590980773)); // => trueconsole.log(isValidTimestamp(1590980773, 1590981023)); // => trueconsole.log(isValidTimestamp(1590980773, 1590980523)); // => true// Invalid timestampsconsole.log(isValidTimestamp(1590980773, 1590980273)); // => falseconsole.log(isValidTimestamp(1590980773, 1590981273)); // => false
javascript